Merge lp:~mterry/unity-greeter/focus-main-window-on-unmap into lp:unity-greeter

Proposed by Michael Terry
Status: Merged
Approved by: Robert Ancell
Approved revision: 577
Merged at revision: 604
Proposed branch: lp:~mterry/unity-greeter/focus-main-window-on-unmap
Merge into: lp:unity-greeter
Diff against target: 41 lines (+24/-1)
1 file modified
src/unity-greeter.vala (+24/-1)
To merge this branch: bzr merge lp:~mterry/unity-greeter/focus-main-window-on-unmap
Reviewer Review Type Date Requested Status
Unity Greeter Development Team Pending
Review via email: mp+124544@code.launchpad.net

Description of the change

Currently, if you open a dialog like the Switch Off one, then close it, you lose the focus-styling around the user list's entry box (though keyboard presses still go to it).

Calling main_window.get_window ().focus () after an UnmapEvent fixes it (just as if main_window received a MapEvent).

But how to tell when to do that? After every Unmap seems extreme. And ideally we'd only do it in cases where the user list is receiving keyboard presses but not focused (this weird halfway-focus GTK is giving us). As far as GTK/GDK/X are concerned, the window doesn't seem to have the focus in that state.

The closest I came is asking X directly, what has the focus. In this state, it gives back an odd pointer value like 0xaf and a revert_to value of X.RevertTo.None. So I'm using the revert_to value as a key that no other window has a claim to the focus.

This branch seems to work for me, but it feels a little black magicky.

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/unity-greeter.vala'
--- src/unity-greeter.vala 2012-09-04 14:45:06 +0000
+++ src/unity-greeter.vala 2012-09-15 03:30:25 +0000
@@ -262,7 +262,7 @@
262 var xevent = (X.Event*)gxevent;262 var xevent = (X.Event*)gxevent;
263 if (xevent.type == X.EventType.MapNotify)263 if (xevent.type == X.EventType.MapNotify)
264 {264 {
265 var display = Gdk.Display.get_default ();265 var display = Gdk.x11_lookup_xdisplay (xevent.xmap.display);
266 var xwin = xevent.xmap.window;266 var xwin = xevent.xmap.window;
267 var win = Gdk.X11Window.foreign_new_for_display (display, xwin);267 var win = Gdk.X11Window.foreign_new_for_display (display, xwin);
268268
@@ -280,6 +280,29 @@
280 main_window.menubar.keyboard_window.get_window ().raise ();280 main_window.menubar.keyboard_window.get_window ().raise ();
281 }281 }
282 }282 }
283 else if (xevent.type == X.EventType.UnmapNotify)
284 {
285 // Since we aren't keeping track of focus (for example, we don't
286 // track the Z stack of windows) like a normal WM would, when we
287 // decide here where to return focus after another window unmaps,
288 // we don't have much to go on. X will tell us if we should take
289 // focus back. (I could not find an obvious way to determine this,
290 // but checking if the X input focus is RevertTo.None seems
291 // reliable.)
292
293 X.Window xwin;
294 int revert_to;
295 xevent.xunmap.display.get_input_focus (out xwin, out revert_to);
296
297 if (revert_to == X.RevertTo.None)
298 {
299 main_window.get_window ().focus (Gdk.CURRENT_TIME);
300
301 /* Make sure to keep keyboard above */
302 if (main_window.menubar.keyboard_window != null)
303 main_window.menubar.keyboard_window.get_window ().raise ();
304 }
305 }
283 return Gdk.FilterReturn.CONTINUE;306 return Gdk.FilterReturn.CONTINUE;
284 }307 }
285308

Subscribers

People subscribed via source and target branches