Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(335)

Side by Side Diff: chrome/browser/gtk/info_bubble_gtk.cc

Issue 99276: Improvements to Linux InfoBubble and BookmarkBubble. (Closed)
Patch Set: Review feedback. Created 11 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/browser/gtk/info_bubble_gtk.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #include "chrome/browser/gtk/info_bubble_gtk.h" 5 #include "chrome/browser/gtk/info_bubble_gtk.h"
6 6
7 #include <gtk/gtk.h> 7 #include <gtk/gtk.h>
8 8
9 #include "base/basictypes.h" 9 #include "base/basictypes.h"
10 #include "base/gfx/gtk_util.h" 10 #include "base/gfx/gtk_util.h"
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 widget->allocation.width, widget->allocation.height, FRAME_STROKE); 109 widget->allocation.width, widget->allocation.height, FRAME_STROKE);
110 gdk_draw_polygon(drawable, gc, FALSE, &points[0], points.size()); 110 gdk_draw_polygon(drawable, gc, FALSE, &points[0], points.size());
111 111
112 g_object_unref(gc); 112 g_object_unref(gc);
113 return FALSE; // Propagate so our children paint, etc. 113 return FALSE; // Propagate so our children paint, etc.
114 } 114 }
115 115
116 } // namespace 116 } // namespace
117 117
118 // static 118 // static
119 InfoBubbleGtk* InfoBubbleGtk::Show(const gfx::Rect& rect, GtkWidget* content) { 119 InfoBubbleGtk* InfoBubbleGtk::Show(const gfx::Rect& rect,
120 GtkWidget* content,
121 InfoBubbleGtkDelegate* delegate) {
120 InfoBubbleGtk* bubble = new InfoBubbleGtk(); 122 InfoBubbleGtk* bubble = new InfoBubbleGtk();
121 bubble->Init(rect, content); 123 bubble->Init(rect, content);
124 bubble->set_delegate(delegate);
122 return bubble; 125 return bubble;
123 } 126 }
124 127
125 InfoBubbleGtk::InfoBubbleGtk() 128 InfoBubbleGtk::InfoBubbleGtk()
126 : window_(NULL), 129 : delegate_(NULL),
130 window_(NULL),
127 screen_x_(0), 131 screen_x_(0),
128 screen_y_(0), 132 screen_y_(0) {
129 closed_(false) { 133
130 } 134 }
131 135
132 InfoBubbleGtk::~InfoBubbleGtk() { 136 InfoBubbleGtk::~InfoBubbleGtk() {
133 } 137 }
134 138
135 void InfoBubbleGtk::Init(const gfx::Rect& rect, GtkWidget* content) { 139 void InfoBubbleGtk::Init(const gfx::Rect& rect, GtkWidget* content) {
136 DCHECK(!window_); 140 DCHECK(!window_);
137 screen_x_ = rect.x() + (rect.width() / 2) - kArrowX; 141 screen_x_ = rect.x() + (rect.width() / 2) - kArrowX;
138 screen_y_ = rect.y() + rect.height() + kArrowToContentPadding; 142 screen_y_ = rect.y() + rect.height() + kArrowToContentPadding;
139 143
(...skipping 26 matching lines...) Expand all
166 GDK_BUTTON_RELEASE_MASK); 170 GDK_BUTTON_RELEASE_MASK);
167 171
168 g_signal_connect(window_, "size-allocate", 172 g_signal_connect(window_, "size-allocate",
169 G_CALLBACK(HandleSizeAllocate), NULL); 173 G_CALLBACK(HandleSizeAllocate), NULL);
170 g_signal_connect(window_, "expose-event", 174 g_signal_connect(window_, "expose-event",
171 G_CALLBACK(HandleExpose), NULL); 175 G_CALLBACK(HandleExpose), NULL);
172 g_signal_connect(window_, "configure-event", 176 g_signal_connect(window_, "configure-event",
173 G_CALLBACK(&HandleConfigureThunk), this); 177 G_CALLBACK(&HandleConfigureThunk), this);
174 g_signal_connect(window_, "button-press-event", 178 g_signal_connect(window_, "button-press-event",
175 G_CALLBACK(&HandleButtonPressThunk), this); 179 G_CALLBACK(&HandleButtonPressThunk), this);
180 g_signal_connect(window_, "destroy",
181 G_CALLBACK(&HandleDestroyThunk), this);
176 182
177 gtk_widget_show_all(window_); 183 gtk_widget_show_all(window_);
184 // Make sure our window has focus, is brought to the top, etc.
178 gtk_window_present(GTK_WINDOW(window_)); 185 gtk_window_present(GTK_WINDOW(window_));
186 // We add a GTK (application level) grab. This means we will get all
187 // keyboard and mouse events for our application, even if they were delivered
188 // on another window. This allows us to close when the user clicks outside
189 // of the info bubble. We don't use an X grab since that would steal
190 // keystrokes from your window manager, prevent you from interacting with
191 // other applications, etc.
179 gtk_grab_add(window_); 192 gtk_grab_add(window_);
180 } 193 }
181 194
182 void InfoBubbleGtk::Close() { 195 void InfoBubbleGtk::Close(bool closed_by_escape) {
183 DCHECK(!closed_); 196 // Notify the delegate that we're about to close. This gives the chance
197 // to save state / etc from the hosted widget before it's destroyed.
198 if (delegate_)
199 delegate_->InfoBubbleClosing(this, closed_by_escape);
200
184 DCHECK(window_); 201 DCHECK(window_);
185 gtk_widget_destroy(window_); 202 gtk_widget_destroy(window_);
186 window_ = NULL; 203 // |this| has been deleted, see HandleDestroy.
187 closed_ = true;
188 } 204 }
189 205
190 gboolean InfoBubbleGtk::HandleConfigure(GdkEventConfigure* event) { 206 gboolean InfoBubbleGtk::HandleConfigure(GdkEventConfigure* event) {
191 // If the window is moved someplace besides where we want it, move it back. 207 // If the window is moved someplace besides where we want it, move it back.
192 // TODO(deanm): In the end, I will probably remove this code and just let 208 // TODO(deanm): In the end, I will probably remove this code and just let
193 // the user move around the bubble like a normal dialog. I want to try 209 // the user move around the bubble like a normal dialog. I want to try
194 // this for now and see if it causes problems when any window managers. 210 // this for now and see if it causes problems when any window managers.
195 if (event->x != screen_x_ || event->y != screen_y_) 211 if (event->x != screen_x_ || event->y != screen_y_)
196 gtk_window_move(GTK_WINDOW(window_), screen_x_, screen_y_); 212 gtk_window_move(GTK_WINDOW(window_), screen_x_, screen_y_);
197 return FALSE; 213 return FALSE;
198 } 214 }
199 215
200 gboolean InfoBubbleGtk::HandleButtonPress(GdkEventButton* event) { 216 gboolean InfoBubbleGtk::HandleButtonPress(GdkEventButton* event) {
201 // If we got a click in our own window, that's ok. 217 // If we got a click in our own window, that's ok.
202 if (event->window == window_->window) 218 if (event->window == window_->window)
203 return FALSE; // Propagate. 219 return FALSE; // Propagate.
204 220
205 // Otherwise we had a click outside of our window, close ourself. 221 // Otherwise we had a click outside of our window, close ourself.
206 Close(); 222 Close();
207 return TRUE; 223 return TRUE;
208 } 224 }
225
226 gboolean InfoBubbleGtk::HandleDestroy() {
227 // We are self deleting, we have a destroy signal setup to catch when we
228 // destroy the widget manually, or the window was closed via X. This will
229 // delete the InfoBubbleGtk object.
230 delete this;
231 return FALSE; // Propagate.
232 }
OLDNEW
« no previous file with comments | « chrome/browser/gtk/info_bubble_gtk.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698