GNOME Bugzilla – Bug 121239
Window List Applet still violates Fitt's Law
Last modified: 2004-12-22 21:47:04 UTC
When creating a new Window List applet, it works exactly as it should. However, after logging out then back in again, the applet now has an extra pixel of insensitive space along the panel's screen edge. I can reproduce it 100% of the time by doing the following: 1. Add a Window List applet to the panel at the bottom of the screen. It seems to obey Fitt's law (that is, it's clickable area extends all the way to the screen edge). 2. Log out, then back in. 3. Open any window and observe the Window List. Or better yet, slide the mouse all the way to the bottom of the applet and try to select the window. This bug seems to crop up again and again in many versions of gnome, but I was pretty sure it had finally been fixed. At least previous bugs on this issue seem to have been closed. All the other panel applets I have tested seem to work correctly now, though.
I assume this is a pretty recent 2.3.x version, right ? I have to say, I've never seen this problem myself with 2.3.x. It seems to work correctly here. For that reason, I suspect it might be a race condition in the setting of the expand_minor flag by the applet. Just a guess though.
Created attachment 19680 [details] a cropped screenshot showing the bug
I see this bug in gnome-panel-2.3.7 and the newly released 2.3.90. Upon closer examination, I've noticed that the applet as a whole *does* extend all the way to the screen edge, but the individual window items in the list have a 1-pixel border around every side. I've attached a screenshot showing a buggy window list (on the left) next to a newly created applet that doesn't yet show the bug (right).
I'm now trying this with Redhat's rawhide binaries of the 2.4.0 release, and having the same result. Some more testing has revealed that forcing a panel restart (i.e. 'killall gnome-panel') corrects the problem, until I log out then back in again. This does seem to be consistent with the race condition theory mentioned above. The applet apparently can't get the panel size accurately while the session is starting up. On a side note: After looking carefully at some of the screenshots that have been posted in the mailing lists, I've noticed that I'm not the only one with this problem. It just seems to bug me more than others :^)
*** Bug 123340 has been marked as a duplicate of this bug. ***
I also see this problem, where the applet will conform to Fitts' law after a killall gnome-panel, but not on login.
I've done some further testing, and this bug behaves a little differently than I previously thought. It has nothing to do with gnome-session startup. The problem is actually caused as follows: When the window list is initialized, if there are currently no windows open that belong in the list, it will set the list item size incorrectly. This means that, if you have no windows open when the session starts, the window list size will be incorrect. However, if you leave some windows open in your session and they get opened at startup before the window list applet finishes initializing, this bug will not get triggered. Likewise, if you restart the panel with some windows already open, the window list will size correctly, but if you restart with no windows open (by using a launcher that runs 'pkill gnome-panel', not in a terminal), then the bug will be triggered. Also, Remember that the problem is not the whole applet itself, just the individual window items that are in the list having a border around them.
Created attachment 25703 [details] [review] panel-applet.c ignore focus_width
So here's a potential fix for this. The problem was in panel_applet_size_allocate in gnome-panel/libpanel-applet/panel-applet.c The function has two different execution paths depending on whether the widget has any child widgets (i.e. whether the tasklist has any tasks in it). When there are tasks, it calls the tasklist's size_allocate function, which works fine (no border around task buttons). When there are no tasks, it executes it's own code which gets the "focus-line-width" property of the widget and reduces the height of the widget by twice that number (i.e. 2), resulting in a 1 pixel non-clickable area above and below the task button. There was a comment in the code saying it ignores "focus-line-width", which it wasn't, so that's what I did. This patch removes the "focus-line-width" fetch, defaulting it to 0. This fixes the problem and I haven't noticed any knew one. Someone who knows the code will obviously have to approve it.
*** Bug 128206 has been marked as a duplicate of this bug. ***
Hmm, the real fix is to make panel_applet_can_focus() work for an empty task list. cc-ing Padraig.
Mark, What do you mean by making panel_applet_can_focus() work for an empty list?
apparently when the window list is empty, panel_applet_can_focus() returns FALSE and we reserve focus-line-width around the applet to draw the focus. However, I know the window list does actually draw its own focus when its empty.
Is your comment correct? If panel_applet_can_focus() returns FALSE we do not reserve any space around the applet in panel_applet_size_request and panel_applet_size_allocate. It looks to me that the space is reserved if panel_applet_can_focus() returns TRUE. If the PanelApplet has focus, where is the focus indication to be drawn if we do not reserve space for it?
Padraig: the details are in the previous comments, my comment was only an attempt to summarise the previous ones. Ben is saying that when there are no tasks in the tasklist we reduce the size allocated to the applet by the focus-line-width. The panel_applet_can_focus() heuristic looks like it might be the cause. Without looking at it closely, I'm pretty sure that when the window list is empty it *still* draws focus internally which means PanelApplet should not need to reserve focus-line-width. But according to Ben, it does.
I think the problem here is that the window list is a special case, it *never* needs the extra focus-line-width allocated around it whether it is empty or not, yet panel_applet_can_focus() returns TRUE when it is empty and FALSE when it is not. BTW, I don't know that the window list draws its own focus when it is empty, I only know that if you allocate that space around it you end up with an unclickable border. Maybe there needs to be code in panel_applet_can_focus() to check if the widget is a window list and, if so, return FALSE?
The reason for leaving the space is to have somewhere to drwaw the focus indication when the PanelApplet has focus. The Panel Applet can have focus if it has a tooltip or contains no focusable children. When the Window List is empty, is it focusable? If it were and was responsible for drawing its focus indication then it seems to me that it would work without any change to PanelApplet code.
When the window list is empty, it is focusable. At least, I can tab around and get a focus indication next to the window list handle, I don't know if window list or PanelApplet is drawing that. Padraig, are you saying that you think the problem is that the window list has no focusable children when it's empty and that the fix is to add one (for purpose of drawing focus indication)? That sounds reasonable to me, but I don't know the window list code well enough to know if it's drawing its own focus indication (I'm a GNOME newbie).
I ought to be able to figure out what is happening but I am distracted by other problems at the moment. I will try to look at this tomorrow.
When the window list is empty and one tabs to the window list the focus is grabbed by the PanelApplet, see panel_applet_focus() in panel-applet.c. The focus indication is drawn in panel_applet_expose(). I am not sure what the correct solution is. The reason that a PanelApplet with an empty WindowList grabs focus when tabbing through it is to allow one to pop up its context menu. If the PanelApplet is going to have focus we need somewhere to draw its focus indication. If an empty WindowList does not want the PanelApplet to have focus it needs to be focusable or have a focusable child and take responsibility for drawing the focus indication.
Does the window list need a focus indication? You can pop up the context menu by right-clicking on the handle. Or do you need the indication so you can get the context menu with the keyboard? Is there a keyboard shortcut to get the context menu? I couldn't find one. If window list does need a focus indication when it's empty, it sounds like the correct solution is to have window list draw its own focus indication.
Shift+F10 should pop up the context menu for the focused object. It is usuualy bound to popup-menu signal for GtkWidget. For accessibility and power user reasons, anything you can do with the mouse you ought be able to do with the keyboard. That is the rationale for an empty window list having focus. If a widget has focus, it needs focus indication drawn, otherwise how can we tell it has focus.
So I think I'll try modifying the window list to draw it's own focus indication when it's empty. This might be beyond my GTK-newbie abilities but I'll give it a shot.
*** Bug 144259 has been marked as a duplicate of this bug. ***
Created attachment 30100 [details] [review] patch The problem is that because a new button appearing in the window list is a grand-child of the applet (there is a tasklist widget in between), the hierarchy changed signal is not emitted, so the has_focusable_child variable is not updated. This patch gets rid of this mechanism and just recalculates everytime. Besides fixing the Fitt's law issue, the patch also makes keyboard navigation actually work when the applet was started empty. The reason the notification signal was set up was for performance (cf. bug 86330), but I doubt it makes any difference at all.
Soeren: sounds sane to me if you don't think there'll be a performance penatly. Please go ahead on HEAD
Sat Aug 7 02:18:35 2004 Soeren Sandmann <sandmann@daimi.au.dk> * panel-applet.c (container_has_focusable_child): Remove hierarchy-changed connection. Recalculate every time instead. #121239.
Nice! I tried this out on HEAD and it works great. Thanks!