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 // This is the GTK implementation of InfoBubbles. InfoBubbles are like | 5 // This is the GTK implementation of InfoBubbles. InfoBubbles are like |
6 // dialogs, but they point to a given element on the screen. You should call | 6 // dialogs, but they point to a given element on the screen. You should call |
7 // InfoBubbleGtk::Show, which will create and display a bubble. The object is | 7 // InfoBubbleGtk::Show, which will create and display a bubble. The object is |
8 // self deleting, when the bubble is closed, you will be notified via | 8 // self deleting, when the bubble is closed, you will be notified via |
9 // InfoBubbleGtkDelegate::InfoBubbleClosing(). Then the widgets and the | 9 // InfoBubbleGtkDelegate::InfoBubbleClosing(). Then the widgets and the |
10 // underlying object will be destroyed. You can also close and destroy the | 10 // underlying object will be destroyed. You can also close and destroy the |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
54 // so it can point to any edge of |rect|. The bubble will host the |content| | 54 // so it can point to any edge of |rect|. The bubble will host the |content| |
55 // widget. Its arrow will be drawn at |arrow_location| if possible. The | 55 // widget. Its arrow will be drawn at |arrow_location| if possible. The |
56 // |delegate| will be notified when the bubble is closed. The bubble will | 56 // |delegate| will be notified when the bubble is closed. The bubble will |
57 // perform an X grab of the pointer and keyboard, and will close itself if a | 57 // perform an X grab of the pointer and keyboard, and will close itself if a |
58 // click is received outside of the bubble. | 58 // click is received outside of the bubble. |
59 static InfoBubbleGtk* Show(GtkWindow* toplevel_window, | 59 static InfoBubbleGtk* Show(GtkWindow* toplevel_window, |
60 const gfx::Rect& rect, | 60 const gfx::Rect& rect, |
61 GtkWidget* content, | 61 GtkWidget* content, |
62 ArrowLocationGtk arrow_location, | 62 ArrowLocationGtk arrow_location, |
63 bool match_system_theme, | 63 bool match_system_theme, |
| 64 bool grab_input, |
64 GtkThemeProvider* provider, | 65 GtkThemeProvider* provider, |
65 InfoBubbleGtkDelegate* delegate); | 66 InfoBubbleGtkDelegate* delegate); |
66 | 67 |
67 // Close the bubble if it's open. This will delete the widgets and object, | 68 // Close the bubble if it's open. This will delete the widgets and object, |
68 // so you shouldn't hold a InfoBubbleGtk pointer after calling Close(). | 69 // so you shouldn't hold a InfoBubbleGtk pointer after calling Close(). |
69 void Close() { CloseInternal(false); } | 70 void Close(); |
70 | 71 |
71 // NotificationObserver implementation. | 72 // NotificationObserver implementation. |
72 virtual void Observe(NotificationType type, | 73 virtual void Observe(NotificationType type, |
73 const NotificationSource& source, | 74 const NotificationSource& source, |
74 const NotificationDetails& details); | 75 const NotificationDetails& details); |
75 | 76 |
76 // If the content contains widgets that can steal our pointer and keyboard | 77 // If the content contains widgets that can steal our pointer and keyboard |
77 // grabs (e.g. GtkComboBox), this method should be called after a widget | 78 // grabs (e.g. GtkComboBox), this method should be called after a widget |
78 // releases the grabs so we can reacquire them. Note that this causes a race | 79 // releases the grabs so we can reacquire them. Note that this causes a race |
79 // condition; another client could grab them before we do (ideally, GDK would | 80 // condition; another client could grab them before we do (ideally, GDK would |
80 // transfer the grabs back to us when the widget releases them). The window | 81 // transfer the grabs back to us when the widget releases them). The window |
81 // is small, though, and the worst-case scenario for this seems to just be | 82 // is small, though, and the worst-case scenario for this seems to just be |
82 // that the content's widgets will appear inactive even after the user clicks | 83 // that the content's widgets will appear inactive even after the user clicks |
83 // in them. | 84 // in them. |
84 void HandlePointerAndKeyboardUngrabbedByContent(); | 85 void HandlePointerAndKeyboardUngrabbedByContent(); |
85 | 86 |
86 private: | 87 private: |
87 enum FrameType { | 88 enum FrameType { |
88 FRAME_MASK, | 89 FRAME_MASK, |
89 FRAME_STROKE, | 90 FRAME_STROKE, |
90 }; | 91 }; |
91 | 92 |
92 explicit InfoBubbleGtk(GtkThemeProvider* provider, bool match_system_theme); | 93 explicit InfoBubbleGtk(GtkThemeProvider* provider, bool match_system_theme); |
93 virtual ~InfoBubbleGtk(); | 94 virtual ~InfoBubbleGtk(); |
94 | 95 |
95 // Creates the InfoBubble. | 96 // Creates the InfoBubble. |
96 void Init(GtkWindow* toplevel_window, | 97 void Init(GtkWindow* toplevel_window, |
97 const gfx::Rect& rect, | 98 const gfx::Rect& rect, |
98 GtkWidget* content, | 99 GtkWidget* content, |
99 ArrowLocationGtk arrow_location); | 100 ArrowLocationGtk arrow_location, |
| 101 bool grab_input); |
100 | 102 |
101 // Make the points for our polygon frame, either for fill (the mask), or for | 103 // Make the points for our polygon frame, either for fill (the mask), or for |
102 // when we stroke the border. | 104 // when we stroke the border. |
103 static std::vector<GdkPoint> MakeFramePolygonPoints( | 105 static std::vector<GdkPoint> MakeFramePolygonPoints( |
104 ArrowLocationGtk arrow_location, | 106 ArrowLocationGtk arrow_location, |
105 int width, | 107 int width, |
106 int height, | 108 int height, |
107 FrameType type); | 109 FrameType type); |
108 | 110 |
109 // Get the location where the arrow should be placed (which is a function of | 111 // Get the location where the arrow should be placed (which is a function of |
(...skipping 16 matching lines...) Expand all Loading... |
126 // |toplevel_window_|'s position as of its most-recent ConfigureNotify event | 128 // |toplevel_window_|'s position as of its most-recent ConfigureNotify event |
127 // and |rect_|) and move it there. | 129 // and |rect_|) and move it there. |
128 void MoveWindow(); | 130 void MoveWindow(); |
129 | 131 |
130 // Restack the bubble's window directly above |toplevel_window_|. | 132 // Restack the bubble's window directly above |toplevel_window_|. |
131 void StackWindow(); | 133 void StackWindow(); |
132 | 134 |
133 // Sets the delegate. | 135 // Sets the delegate. |
134 void set_delegate(InfoBubbleGtkDelegate* delegate) { delegate_ = delegate; } | 136 void set_delegate(InfoBubbleGtkDelegate* delegate) { delegate_ = delegate; } |
135 | 137 |
136 // Closes the window and notifies the delegate. |closed_by_escape| is true if | |
137 // the close is the result of pressing escape. | |
138 void CloseInternal(bool closed_by_escape); | |
139 | |
140 // Grab (in the X sense) the pointer and keyboard. This is needed to make | 138 // Grab (in the X sense) the pointer and keyboard. This is needed to make |
141 // sure that we have the input focus. | 139 // sure that we have the input focus. |
142 void GrabPointerAndKeyboard(); | 140 void GrabPointerAndKeyboard(); |
143 | 141 |
144 static gboolean HandleEscapeThunk(GtkAccelGroup* group, | 142 static gboolean HandleEscapeThunk(GtkAccelGroup* group, |
145 GObject* acceleratable, | 143 GObject* acceleratable, |
146 guint keyval, | 144 guint keyval, |
147 GdkModifierType modifier, | 145 GdkModifierType modifier, |
148 gpointer user_data) { | 146 gpointer user_data) { |
149 return reinterpret_cast<InfoBubbleGtk*>(user_data)->HandleEscape(); | 147 return reinterpret_cast<InfoBubbleGtk*>(user_data)->HandleEscape(); |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
228 // Where would we prefer for the arrow be drawn relative to the bubble, and | 226 // Where would we prefer for the arrow be drawn relative to the bubble, and |
229 // where is it currently drawn? | 227 // where is it currently drawn? |
230 ArrowLocationGtk preferred_arrow_location_; | 228 ArrowLocationGtk preferred_arrow_location_; |
231 ArrowLocationGtk current_arrow_location_; | 229 ArrowLocationGtk current_arrow_location_; |
232 | 230 |
233 // Whether the background should match the system theme, when the system theme | 231 // Whether the background should match the system theme, when the system theme |
234 // is being used. For example, the bookmark bubble does, but extension popups | 232 // is being used. For example, the bookmark bubble does, but extension popups |
235 // do not. | 233 // do not. |
236 bool match_system_theme_; | 234 bool match_system_theme_; |
237 | 235 |
| 236 // If true, the popup owns all X input for the duration of its existence. |
| 237 // This will usually be true, the exception being when inspecting extension |
| 238 // popups with dev tools. |
| 239 bool grab_input_; |
| 240 |
| 241 bool closed_by_escape_; |
| 242 |
238 NotificationRegistrar registrar_; | 243 NotificationRegistrar registrar_; |
239 | 244 |
240 DISALLOW_COPY_AND_ASSIGN(InfoBubbleGtk); | 245 DISALLOW_COPY_AND_ASSIGN(InfoBubbleGtk); |
241 }; | 246 }; |
242 | 247 |
243 #endif // CHROME_BROWSER_GTK_INFO_BUBBLE_GTK_H_ | 248 #endif // CHROME_BROWSER_GTK_INFO_BUBBLE_GTK_H_ |
OLD | NEW |