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
1=== modified file 'src/unity-greeter.vala'
2--- src/unity-greeter.vala 2012-09-04 14:45:06 +0000
3+++ src/unity-greeter.vala 2012-09-15 03:30:25 +0000
4@@ -262,7 +262,7 @@
5 var xevent = (X.Event*)gxevent;
6 if (xevent.type == X.EventType.MapNotify)
7 {
8- var display = Gdk.Display.get_default ();
9+ var display = Gdk.x11_lookup_xdisplay (xevent.xmap.display);
10 var xwin = xevent.xmap.window;
11 var win = Gdk.X11Window.foreign_new_for_display (display, xwin);
12
13@@ -280,6 +280,29 @@
14 main_window.menubar.keyboard_window.get_window ().raise ();
15 }
16 }
17+ else if (xevent.type == X.EventType.UnmapNotify)
18+ {
19+ // Since we aren't keeping track of focus (for example, we don't
20+ // track the Z stack of windows) like a normal WM would, when we
21+ // decide here where to return focus after another window unmaps,
22+ // we don't have much to go on. X will tell us if we should take
23+ // focus back. (I could not find an obvious way to determine this,
24+ // but checking if the X input focus is RevertTo.None seems
25+ // reliable.)
26+
27+ X.Window xwin;
28+ int revert_to;
29+ xevent.xunmap.display.get_input_focus (out xwin, out revert_to);
30+
31+ if (revert_to == X.RevertTo.None)
32+ {
33+ main_window.get_window ().focus (Gdk.CURRENT_TIME);
34+
35+ /* Make sure to keep keyboard above */
36+ if (main_window.menubar.keyboard_window != null)
37+ main_window.menubar.keyboard_window.get_window ().raise ();
38+ }
39+ }
40 return Gdk.FilterReturn.CONTINUE;
41 }
42

Subscribers

People subscribed via source and target branches