OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 | 5 |
6 #include "views/controls/menu/menu_host_gtk.h" | 6 #include "views/controls/menu/menu_host_gtk.h" |
7 | 7 |
8 #include <gdk/gdk.h> | 8 #include <gdk/gdk.h> |
9 | 9 |
10 #include "views/controls/menu/menu_controller.h" | 10 #include "views/controls/menu/menu_controller.h" |
11 #include "views/controls/menu/menu_host_root_view.h" | 11 #include "views/controls/menu/menu_host_root_view.h" |
12 #include "views/controls/menu/menu_item_view.h" | 12 #include "views/controls/menu/menu_item_view.h" |
13 #include "views/controls/menu/submenu_view.h" | 13 #include "views/controls/menu/submenu_view.h" |
14 | 14 |
15 namespace views { | 15 namespace views { |
16 | 16 |
17 MenuHost::MenuHost(SubmenuView* submenu) | 17 MenuHost::MenuHost(SubmenuView* submenu) |
18 : WidgetGtk(WidgetGtk::TYPE_POPUP), | 18 : WidgetGtk(WidgetGtk::TYPE_POPUP), |
19 closed_(false), | 19 closed_(false), |
20 submenu_(submenu), | 20 submenu_(submenu), |
21 did_pointer_grab_(false) { | 21 did_pointer_grab_(false) { |
22 GdkModifierType current_event_mod; | 22 GdkEvent* event = gtk_get_current_event(); |
23 if (gtk_get_current_event_state(¤t_event_mod)) { | 23 if (event) { |
24 set_mouse_down( | 24 if (event->type == GDK_BUTTON_PRESS || event->type == GDK_2BUTTON_PRESS || |
25 (current_event_mod & GDK_BUTTON1_MASK) || | 25 event->type == GDK_3BUTTON_PRESS) { |
26 (current_event_mod & GDK_BUTTON2_MASK) || | 26 set_mouse_down(true); |
27 (current_event_mod & GDK_BUTTON3_MASK) || | 27 } |
28 (current_event_mod & GDK_BUTTON4_MASK) || | 28 gdk_event_free(event); |
29 (current_event_mod & GDK_BUTTON5_MASK)); | |
30 } | 29 } |
31 } | 30 } |
32 | 31 |
33 void MenuHost::Init(gfx::NativeWindow parent, | 32 void MenuHost::Init(gfx::NativeWindow parent, |
34 const gfx::Rect& bounds, | 33 const gfx::Rect& bounds, |
35 View* contents_view, | 34 View* contents_view, |
36 bool do_capture) { | 35 bool do_capture) { |
37 WidgetGtk::Init(GTK_WIDGET(parent), bounds); | 36 WidgetGtk::Init(GTK_WIDGET(parent), bounds); |
38 SetContentsView(contents_view); | 37 SetContentsView(contents_view); |
39 // TODO(sky): see if there is some way to show without changing focus. | |
40 Show(); | 38 Show(); |
41 if (do_capture) { | 39 if (do_capture) |
42 // Release the current grab. | 40 DoCapture(); |
43 GtkWidget* current_grab_window = gtk_grab_get_current(); | |
44 if (current_grab_window) | |
45 gtk_grab_remove(current_grab_window); | |
46 | |
47 // Make sure all app mouse events are targetted at us only. | |
48 DoGrab(); | |
49 | |
50 // And do a grab. | |
51 // NOTE: we do this to ensure we get mouse events from other apps, a grab | |
52 // done with gtk_grab_add doesn't get events from other apps. | |
53 GdkGrabStatus grab_status = | |
54 gdk_pointer_grab(window_contents()->window, FALSE, | |
55 static_cast<GdkEventMask>( | |
56 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | | |
57 GDK_POINTER_MOTION_MASK), | |
58 NULL, NULL, GDK_CURRENT_TIME); | |
59 did_pointer_grab_ = (grab_status == GDK_GRAB_SUCCESS); | |
60 DCHECK(did_pointer_grab_); | |
61 // need keyboard grab. | |
62 #ifdef DEBUG_MENU | |
63 DLOG(INFO) << "Doing capture"; | |
64 #endif | |
65 } | |
66 } | 41 } |
67 | 42 |
68 gfx::NativeWindow MenuHost::GetNativeWindow() { | 43 gfx::NativeWindow MenuHost::GetNativeWindow() { |
69 return GTK_WINDOW(GetNativeView()); | 44 return GTK_WINDOW(GetNativeView()); |
70 } | 45 } |
71 | 46 |
72 void MenuHost::Show() { | 47 void MenuHost::Show() { |
73 WidgetGtk::Show(); | 48 WidgetGtk::Show(); |
74 } | 49 } |
75 | 50 |
(...skipping 12 matching lines...) Expand all Loading... |
88 closed_ = true; | 63 closed_ = true; |
89 WidgetGtk::Hide(); | 64 WidgetGtk::Hide(); |
90 } | 65 } |
91 | 66 |
92 void MenuHost::HideWindow() { | 67 void MenuHost::HideWindow() { |
93 // Make sure we release capture before hiding. | 68 // Make sure we release capture before hiding. |
94 ReleaseGrab(); | 69 ReleaseGrab(); |
95 WidgetGtk::Hide(); | 70 WidgetGtk::Hide(); |
96 } | 71 } |
97 | 72 |
| 73 void MenuHost::DoCapture() { |
| 74 // Release the current grab. |
| 75 GtkWidget* current_grab_window = gtk_grab_get_current(); |
| 76 if (current_grab_window) |
| 77 gtk_grab_remove(current_grab_window); |
| 78 |
| 79 // Make sure all app mouse events are targetted at us only. |
| 80 DoGrab(); |
| 81 |
| 82 // And do a grab. |
| 83 // NOTE: we do this to ensure we get mouse events from other apps, a grab |
| 84 // done with gtk_grab_add doesn't get events from other apps. |
| 85 GdkGrabStatus grab_status = |
| 86 gdk_pointer_grab(window_contents()->window, FALSE, |
| 87 static_cast<GdkEventMask>( |
| 88 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | |
| 89 GDK_POINTER_MOTION_MASK), |
| 90 NULL, NULL, GDK_CURRENT_TIME); |
| 91 did_pointer_grab_ = (grab_status == GDK_GRAB_SUCCESS); |
| 92 DCHECK(did_pointer_grab_); |
| 93 // need keyboard grab. |
| 94 #ifdef DEBUG_MENU |
| 95 DLOG(INFO) << "Doing capture"; |
| 96 #endif |
| 97 } |
| 98 |
98 void MenuHost::ReleaseCapture() { | 99 void MenuHost::ReleaseCapture() { |
99 ReleaseGrab(); | 100 ReleaseGrab(); |
100 } | 101 } |
101 | 102 |
102 RootView* MenuHost::CreateRootView() { | 103 RootView* MenuHost::CreateRootView() { |
103 return new MenuHostRootView(this, submenu_); | 104 return new MenuHostRootView(this, submenu_); |
104 } | 105 } |
105 | 106 |
106 gboolean MenuHost::OnGrabBrokeEvent(GtkWidget* widget, GdkEvent* event) { | 107 gboolean MenuHost::OnGrabBrokeEvent(GtkWidget* widget, GdkEvent* event) { |
107 // Grab breaking only happens when drag and drop starts. So, we don't try | 108 // Grab breaking only happens when drag and drop starts. So, we don't try |
(...skipping 10 matching lines...) Expand all Loading... |
118 | 119 |
119 void MenuHost::ReleaseGrab() { | 120 void MenuHost::ReleaseGrab() { |
120 WidgetGtk::ReleaseGrab(); | 121 WidgetGtk::ReleaseGrab(); |
121 if (did_pointer_grab_) { | 122 if (did_pointer_grab_) { |
122 did_pointer_grab_ = false; | 123 did_pointer_grab_ = false; |
123 gdk_pointer_ungrab(GDK_CURRENT_TIME); | 124 gdk_pointer_ungrab(GDK_CURRENT_TIME); |
124 } | 125 } |
125 } | 126 } |
126 | 127 |
127 } // namespace views | 128 } // namespace views |
OLD | NEW |