Merge lp:~tombeckmann/granite/popover-focus-out into lp:~elementary-pantheon/granite/granite

Proposed by Tom Beckmann
Status: Merged
Merged at revision: 353
Proposed branch: lp:~tombeckmann/granite/popover-focus-out
Merge into: lp:~elementary-pantheon/granite/granite
Diff against target: 78 lines (+51/-16)
1 file modified
lib/Widgets/PopOver.vala (+51/-16)
To merge this branch: bzr merge lp:~tombeckmann/granite/popover-focus-out
Reviewer Review Type Date Requested Status
Andrea Basso (community) Approve
Review via email: mp+120243@code.launchpad.net

Description of the change

This will solve all focus problems we had with popovers and slingshot in particular by doing a grab on the window like a GtkMenu does.

To post a comment you must log in.
Revision history for this message
Andrea Basso (voluntatefaber) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/Widgets/PopOver.vala'
2--- lib/Widgets/PopOver.vala 2012-07-09 13:38:14 +0000
3+++ lib/Widgets/PopOver.vala 2012-08-17 21:54:17 +0000
4@@ -153,23 +153,58 @@
5 menu.get_style_context().add_class("popover_bg");
6
7 size_allocate.connect(on_size_allocate);
8-
9- focus_out_event.connect_after((f) =>
10- {
11- foreach(Gtk.Window window in Gtk.Window.list_toplevels())
12- {
13- if((window.type_hint == Gdk.WindowTypeHint.POPUP_MENU || window.type_hint == Gdk.WindowTypeHint.MENU) && window.visible && window != this)
14- {
15- return false;
16- }
17- }
18- hide ();
19-
20- return false;
21- });
22-
23- hide.connect( () => { response(Gtk.ResponseType.CANCEL); });
24 }
25+
26+ public override void hide ()
27+ {
28+ var pointer = Gdk.Display.get_default ().get_device_manager ().get_client_pointer ();
29+
30+ Gtk.device_grab_remove (this, pointer);
31+ pointer.ungrab (Gdk.CURRENT_TIME);
32+
33+ base.hide ();
34+ }
35+
36+ public override bool map_event (Gdk.EventAny event)
37+ {
38+ var pointer = Gdk.Display.get_default ().get_device_manager ().get_client_pointer ();
39+
40+ var ret = pointer.grab (get_window (), Gdk.GrabOwnership.WINDOW, true, Gdk.EventMask.SMOOTH_SCROLL_MASK |
41+ Gdk.EventMask.BUTTON_PRESS_MASK | Gdk.EventMask.BUTTON_RELEASE_MASK |
42+ Gdk.EventMask.ENTER_NOTIFY_MASK | Gdk.EventMask.LEAVE_NOTIFY_MASK |
43+ Gdk.EventMask.POINTER_MOTION_MASK,
44+ null, Gdk.CURRENT_TIME);
45+ Gtk.device_grab_add (this, pointer, true);
46+
47+ return false;
48+ }
49+
50+ public override bool button_press_event (Gdk.EventButton event)
51+ {
52+ if (event_in_window (event))
53+ return true;
54+
55+ return base.button_press_event (event);
56+ }
57+
58+ public override bool button_release_event (Gdk.EventButton event)
59+ {
60+ if (event_in_window (event))
61+ return true;
62+
63+ hide ();
64+ return false;
65+ }
66+
67+ bool event_in_window (Gdk.EventButton event)
68+ {
69+ int x, y, w, h;
70+ get_position (out x, out y);
71+ get_size (out w, out h);
72+
73+ return event.x_root >= x && event.x_root <= x + w &&
74+ event.y_root >= y && event.y_root <= y + h;
75+ }
76
77 /* May be null if the screen is not composited */
78 protected Granite.Drawing.BufferSurface? main_buffer = null;

Subscribers

People subscribed via source and target branches