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

Side by Side Diff: chrome/browser/ui/gtk/extensions/shell_window_gtk.cc

Issue 10834205: Draggable region support for frameless app window on GTK. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Created 8 years, 4 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/ui/gtk/extensions/shell_window_gtk.h" 5 #include "chrome/browser/ui/gtk/extensions/shell_window_gtk.h"
6 6
7 #include "chrome/browser/profiles/profile.h" 7 #include "chrome/browser/profiles/profile.h"
8 #include "chrome/browser/ui/gtk/gtk_window_util.h"
9 #include "chrome/common/extensions/draggable_region.h"
8 #include "chrome/common/extensions/extension.h" 10 #include "chrome/common/extensions/extension.h"
9 #include "content/public/browser/render_view_host.h" 11 #include "content/public/browser/render_view_host.h"
10 #include "content/public/browser/render_widget_host_view.h" 12 #include "content/public/browser/render_widget_host_view.h"
11 #include "content/public/browser/web_contents.h" 13 #include "content/public/browser/web_contents.h"
12 #include "content/public/browser/web_contents_view.h" 14 #include "content/public/browser/web_contents_view.h"
13 #include "ui/base/x/active_window_watcher_x.h" 15 #include "ui/base/x/active_window_watcher_x.h"
14 #include "ui/gfx/rect.h" 16 #include "ui/gfx/rect.h"
15 17
16 ShellWindowGtk::ShellWindowGtk(ShellWindow* shell_window, 18 ShellWindowGtk::ShellWindowGtk(ShellWindow* shell_window,
17 const ShellWindow::CreateParams& params) 19 const ShellWindow::CreateParams& params)
18 : shell_window_(shell_window), 20 : shell_window_(shell_window),
19 state_(GDK_WINDOW_STATE_WITHDRAWN), 21 state_(GDK_WINDOW_STATE_WITHDRAWN),
20 is_active_(!ui::ActiveWindowWatcherX::WMSupportsActivation()), 22 is_active_(!ui::ActiveWindowWatcherX::WMSupportsActivation()),
21 content_thinks_its_fullscreen_(false) { 23 content_thinks_its_fullscreen_(false),
24 frameless_(params.frame == ShellWindow::CreateParams::FRAME_NONE) {
22 window_ = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL)); 25 window_ = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL));
23 26
24 gfx::NativeView native_view = 27 gfx::NativeView native_view =
25 web_contents()->GetView()->GetNativeView(); 28 web_contents()->GetView()->GetNativeView();
26 gtk_container_add(GTK_CONTAINER(window_), native_view); 29 gtk_container_add(GTK_CONTAINER(window_), native_view);
27 30
28 gtk_window_set_default_size( 31 gtk_window_set_default_size(
29 window_, params.bounds.width(), params.bounds.height()); 32 window_, params.bounds.width(), params.bounds.height());
30 33
31 // Hide titlebar when {frame: 'none'} specified on ShellWindow. 34 // Hide titlebar when {frame: 'none'} specified on ShellWindow.
32 if (params.frame == ShellWindow::CreateParams::FRAME_NONE) 35 if (frameless_)
33 gtk_window_set_decorated(window_, false); 36 gtk_window_set_decorated(window_, false);
34 37
35 int min_width = params.minimum_size.width(); 38 int min_width = params.minimum_size.width();
36 int min_height = params.minimum_size.height(); 39 int min_height = params.minimum_size.height();
37 int max_width = params.maximum_size.width(); 40 int max_width = params.maximum_size.width();
38 int max_height = params.maximum_size.height(); 41 int max_height = params.maximum_size.height();
39 GdkGeometry hints; 42 GdkGeometry hints;
40 int hints_mask = 0; 43 int hints_mask = 0;
41 if (min_width || min_height) { 44 if (min_width || min_height) {
42 hints.min_height = min_height; 45 hints.min_height = min_height;
43 hints.min_width = min_width; 46 hints.min_width = min_width;
44 hints_mask |= GDK_HINT_MIN_SIZE; 47 hints_mask |= GDK_HINT_MIN_SIZE;
45 } 48 }
46 if (max_width || max_height) { 49 if (max_width || max_height) {
47 hints.max_height = max_height ? max_height : G_MAXINT; 50 hints.max_height = max_height ? max_height : G_MAXINT;
48 hints.max_width = max_width ? max_width : G_MAXINT; 51 hints.max_width = max_width ? max_width : G_MAXINT;
49 hints_mask |= GDK_HINT_MAX_SIZE; 52 hints_mask |= GDK_HINT_MAX_SIZE;
50 } 53 }
51 if (hints_mask) { 54 if (hints_mask) {
52 gtk_window_set_geometry_hints( 55 gtk_window_set_geometry_hints(
53 window_, 56 window_,
54 GTK_WIDGET(window_), 57 GTK_WIDGET(window_),
55 &hints, 58 &hints,
56 static_cast<GdkWindowHints>(hints_mask)); 59 static_cast<GdkWindowHints>(hints_mask));
57 } 60 }
58 61
62 // In some (older) versions of compiz, raising top-level windows when they
63 // are partially off-screen causes them to get snapped back on screen, not
64 // always even on the current virtual desktop. If we are running under
65 // compiz, suppress such raises, as they are not necessary in compiz anyway.
66 if (ui::GuessWindowManager() == ui::WM_COMPIZ)
67 suppress_window_raise_ = true;
68
59 // TODO(mihaip): Mirror contents of <title> tag in window title 69 // TODO(mihaip): Mirror contents of <title> tag in window title
60 gtk_window_set_title(window_, extension()->name().c_str()); 70 gtk_window_set_title(window_, extension()->name().c_str());
61 71
62 g_signal_connect(window_, "delete-event", 72 g_signal_connect(window_, "delete-event",
63 G_CALLBACK(OnMainWindowDeleteEventThunk), this); 73 G_CALLBACK(OnMainWindowDeleteEventThunk), this);
64 g_signal_connect(window_, "configure-event", 74 g_signal_connect(window_, "configure-event",
65 G_CALLBACK(OnConfigureThunk), this); 75 G_CALLBACK(OnConfigureThunk), this);
66 g_signal_connect(window_, "window-state-event", 76 g_signal_connect(window_, "window-state-event",
67 G_CALLBACK(OnWindowStateThunk), this); 77 G_CALLBACK(OnWindowStateThunk), this);
78 if (frameless_) {
79 g_signal_connect(window_, "button-press-event",
80 G_CALLBACK(OnButtonPressThunk), this);
81 }
68 82
69 ui::ActiveWindowWatcherX::AddObserver(this); 83 ui::ActiveWindowWatcherX::AddObserver(this);
70 } 84 }
71 85
72 ShellWindowGtk::~ShellWindowGtk() { 86 ShellWindowGtk::~ShellWindowGtk() {
73 ui::ActiveWindowWatcherX::RemoveObserver(this); 87 ui::ActiveWindowWatcherX::RemoveObserver(this);
74 } 88 }
75 89
76 bool ShellWindowGtk::IsActive() const { 90 bool ShellWindowGtk::IsActive() const {
77 return is_active_; 91 return is_active_;
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 !(state_ & GDK_WINDOW_STATE_FULLSCREEN)) { 213 !(state_ & GDK_WINDOW_STATE_FULLSCREEN)) {
200 content_thinks_its_fullscreen_ = false; 214 content_thinks_its_fullscreen_ = false;
201 content::RenderViewHost* rvh = web_contents()->GetRenderViewHost(); 215 content::RenderViewHost* rvh = web_contents()->GetRenderViewHost();
202 if (rvh) 216 if (rvh)
203 rvh->ExitFullscreen(); 217 rvh->ExitFullscreen();
204 } 218 }
205 219
206 return FALSE; 220 return FALSE;
207 } 221 }
208 222
223 gboolean ShellWindowGtk::OnButtonPress(GtkWidget* widget,
224 GdkEventButton* event) {
225 if (!draggable_region_.isEmpty() &&
226 draggable_region_.contains(event->x, event->y)) {
227 if (event->button == 1) {
228 if (GDK_BUTTON_PRESS == event->type) {
229 if (!suppress_window_raise_)
230 gdk_window_raise(GTK_WIDGET(widget)->window);
231
232 return gtk_window_util::HandleTitleBarLeftMousePress(
233 GTK_WINDOW(widget), bounds_, event);
234 } else if (GDK_2BUTTON_PRESS == event->type) {
235 bool is_maximized = gdk_window_get_state(GTK_WIDGET(widget)->window) &
236 GDK_WINDOW_STATE_MAXIMIZED;
237 if (is_maximized) {
238 gtk_window_util::UnMaximize(GTK_WINDOW(widget),
239 bounds_, restored_bounds_);
240 } else {
241 gtk_window_maximize(GTK_WINDOW(widget));
242 }
243 return TRUE;
244 }
245 } else if (event->button == 2) {
246 gdk_window_lower(GTK_WIDGET(widget)->window);
247 return TRUE;
248 }
249 }
250
251 return FALSE;
252 }
253
209 void ShellWindowGtk::SetFullscreen(bool fullscreen) { 254 void ShellWindowGtk::SetFullscreen(bool fullscreen) {
210 content_thinks_its_fullscreen_ = fullscreen; 255 content_thinks_its_fullscreen_ = fullscreen;
211 if (fullscreen) 256 if (fullscreen)
212 gtk_window_fullscreen(window_); 257 gtk_window_fullscreen(window_);
213 else 258 else
214 gtk_window_unfullscreen(window_); 259 gtk_window_unfullscreen(window_);
215 } 260 }
216 261
217 bool ShellWindowGtk::IsFullscreenOrPending() const { 262 bool ShellWindowGtk::IsFullscreenOrPending() const {
218 return content_thinks_its_fullscreen_; 263 return content_thinks_its_fullscreen_;
219 } 264 }
220 265
221 void ShellWindowGtk::UpdateWindowTitle() { 266 void ShellWindowGtk::UpdateWindowTitle() {
222 // TODO(jeremya): implement. 267 // TODO(jeremya): implement.
223 } 268 }
224 269
270 void ShellWindowGtk::UpdateDraggableRegions(
271 const std::vector<extensions::DraggableRegion>& regions) {
272 // Draggable region is not supported for non-frameless window.
273 if (!frameless_)
274 return;
275
276 SkRegion draggable_region;
277
278 // By default, the whole window is draggable.
279 gfx::Rect bounds = GetBounds();
280 draggable_region.op(0, 0, bounds.right(), bounds.bottom(),
281 SkRegion::kUnion_Op);
282
283 // Exclude those designated as non-draggable.
284 for (std::vector<extensions::DraggableRegion>::const_iterator iter =
285 regions.begin();
286 iter != regions.end(); ++iter) {
287 const extensions::DraggableRegion& region = *iter;
288 draggable_region.op(region.bounds.x(),
289 region.bounds.y(),
290 region.bounds.right(),
291 region.bounds.bottom(),
292 SkRegion::kDifference_Op);
293 }
294
295 draggable_region_ = draggable_region;
296 }
297
225 // static 298 // static
226 NativeShellWindow* NativeShellWindow::Create( 299 NativeShellWindow* NativeShellWindow::Create(
227 ShellWindow* shell_window, const ShellWindow::CreateParams& params) { 300 ShellWindow* shell_window, const ShellWindow::CreateParams& params) {
228 return new ShellWindowGtk(shell_window, params); 301 return new ShellWindowGtk(shell_window, params);
229 } 302 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/gtk/extensions/shell_window_gtk.h ('k') | chrome/browser/ui/gtk/gtk_window_util.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698