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

Side by Side Diff: chrome/browser/ui/gtk/browser_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/browser_window_gtk.h" 5 #include "chrome/browser/ui/gtk/browser_window_gtk.h"
6 6
7 #include <gdk/gdkkeysyms.h> 7 #include <gdk/gdkkeysyms.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <string> 10 #include <string>
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after
291 render_area_floating_container_(NULL), 291 render_area_floating_container_(NULL),
292 render_area_event_box_(NULL), 292 render_area_event_box_(NULL),
293 toolbar_border_(NULL), 293 toolbar_border_(NULL),
294 browser_(browser), 294 browser_(browser),
295 state_(GDK_WINDOW_STATE_WITHDRAWN), 295 state_(GDK_WINDOW_STATE_WITHDRAWN),
296 devtools_dock_side_(DEVTOOLS_DOCK_SIDE_BOTTOM), 296 devtools_dock_side_(DEVTOOLS_DOCK_SIDE_BOTTOM),
297 contents_hsplit_(NULL), 297 contents_hsplit_(NULL),
298 contents_vsplit_(NULL), 298 contents_vsplit_(NULL),
299 frame_cursor_(NULL), 299 frame_cursor_(NULL),
300 is_active_(!ui::ActiveWindowWatcherX::WMSupportsActivation()), 300 is_active_(!ui::ActiveWindowWatcherX::WMSupportsActivation()),
301 last_click_time_(0),
302 show_state_after_show_(ui::SHOW_STATE_DEFAULT), 301 show_state_after_show_(ui::SHOW_STATE_DEFAULT),
303 suppress_window_raise_(false), 302 suppress_window_raise_(false),
304 accel_group_(NULL), 303 accel_group_(NULL),
305 fullscreen_exit_bubble_type_( 304 fullscreen_exit_bubble_type_(
306 FEB_TYPE_BROWSER_FULLSCREEN_EXIT_INSTRUCTION) { 305 FEB_TYPE_BROWSER_FULLSCREEN_EXIT_INSTRUCTION) {
307 } 306 }
308 307
309 BrowserWindowGtk::~BrowserWindowGtk() { 308 BrowserWindowGtk::~BrowserWindowGtk() {
310 ui::ActiveWindowWatcherX::RemoveObserver(this); 309 ui::ActiveWindowWatcherX::RemoveObserver(this);
311 310
(...skipping 1286 matching lines...) Expand 10 before | Expand all | Expand 10 after
1598 // set window_ to NULL, otherwise we will try to close the window again when 1597 // set window_ to NULL, otherwise we will try to close the window again when
1599 // we call Close() in the destructor. 1598 // we call Close() in the destructor.
1600 // 1599 //
1601 // We don't want to use DeleteSoon() here since it won't work on a nested pump 1600 // We don't want to use DeleteSoon() here since it won't work on a nested pump
1602 // (like in UI tests). 1601 // (like in UI tests).
1603 MessageLoop::current()->PostTask( 1602 MessageLoop::current()->PostTask(
1604 FROM_HERE, base::Bind(&base::DeletePointer<BrowserWindowGtk>, this)); 1603 FROM_HERE, base::Bind(&base::DeletePointer<BrowserWindowGtk>, this));
1605 } 1604 }
1606 1605
1607 void BrowserWindowGtk::UnMaximize() { 1606 void BrowserWindowGtk::UnMaximize() {
1608 gtk_window_unmaximize(window_); 1607 gtk_window_util::UnMaximize(window_, bounds_, restored_bounds_);
1609
1610 // It can happen that you end up with a window whose restore size is the same
1611 // as the size of the screen, so unmaximizing it merely remaximizes it due to
1612 // the same WM feature that SetWindowSize() works around. We try to detect
1613 // this and resize the window to work around the issue.
1614 if (bounds_.size() == restored_bounds_.size())
1615 gtk_window_resize(window_, bounds_.width(), bounds_.height() - 1);
1616 } 1608 }
1617 1609
1618 bool BrowserWindowGtk::CanClose() const { 1610 bool BrowserWindowGtk::CanClose() const {
1619 // You cannot close a frame for which there is an active originating drag 1611 // You cannot close a frame for which there is an active originating drag
1620 // session. 1612 // session.
1621 if (tabstrip_->IsDragSessionActive()) 1613 if (tabstrip_->IsDragSessionActive())
1622 return false; 1614 return false;
1623 1615
1624 // Give beforeunload handlers the chance to cancel the close before we hide 1616 // Give beforeunload handlers the chance to cancel the close before we hide
1625 // the window below. 1617 // the window below.
(...skipping 641 matching lines...) Expand 10 before | Expand all | Expand 10 after
2267 // If the toolbar is not showing, use the location of web contents as the 2259 // If the toolbar is not showing, use the location of web contents as the
2268 // boundary of where to ignore clicks. 2260 // boundary of where to ignore clicks.
2269 toolbar = render_area_vbox_; 2261 toolbar = render_area_vbox_;
2270 } 2262 }
2271 gint toolbar_y; 2263 gint toolbar_y;
2272 gtk_widget_get_pointer(toolbar, NULL, &toolbar_y); 2264 gtk_widget_get_pointer(toolbar, NULL, &toolbar_y);
2273 bool has_hit_titlebar = !IsFullscreen() && (toolbar_y < 0) 2265 bool has_hit_titlebar = !IsFullscreen() && (toolbar_y < 0)
2274 && !has_hit_edge; 2266 && !has_hit_edge;
2275 if (event->button == 1) { 2267 if (event->button == 1) {
2276 if (GDK_BUTTON_PRESS == event->type) { 2268 if (GDK_BUTTON_PRESS == event->type) {
2277 guint32 last_click_time = last_click_time_;
2278 gfx::Point last_click_position = last_click_position_;
2279 last_click_time_ = event->time;
2280 last_click_position_ = gfx::Point(static_cast<int>(event->x),
2281 static_cast<int>(event->y));
2282
2283 // Raise the window after a click on either the titlebar or the border to 2269 // Raise the window after a click on either the titlebar or the border to
2284 // match the behavior of most window managers, unless that behavior has 2270 // match the behavior of most window managers, unless that behavior has
2285 // been suppressed. 2271 // been suppressed.
2286 if ((has_hit_titlebar || has_hit_edge) && !suppress_window_raise_) 2272 if ((has_hit_titlebar || has_hit_edge) && !suppress_window_raise_)
2287 gdk_window_raise(gdk_window); 2273 gdk_window_raise(gdk_window);
2288 2274
2289 if (has_hit_titlebar) { 2275 if (has_hit_titlebar) {
2290 return HandleTitleBarLeftMousePress( 2276 return HandleTitleBarLeftMousePress(event);
2291 event, last_click_time, last_click_position);
2292 } else if (has_hit_edge) { 2277 } else if (has_hit_edge) {
2293 return HandleWindowEdgeLeftMousePress(window_, edge, event); 2278 return HandleWindowEdgeLeftMousePress(window_, edge, event);
2294 } 2279 }
2295 } else if (GDK_2BUTTON_PRESS == event->type) { 2280 } else if (GDK_2BUTTON_PRESS == event->type) {
2296 if (has_hit_titlebar) { 2281 if (has_hit_titlebar) {
2297 // Maximize/restore on double click. 2282 // Maximize/restore on double click.
2298 if (IsMaximized()) { 2283 if (IsMaximized()) {
2299 UnMaximize(); 2284 UnMaximize();
2300 } else { 2285 } else {
2301 gtk_window_maximize(window_); 2286 gtk_window_maximize(window_);
(...skipping 10 matching lines...) Expand all
2312 if (has_hit_titlebar) { 2297 if (has_hit_titlebar) {
2313 titlebar_->ShowContextMenu(event); 2298 titlebar_->ShowContextMenu(event);
2314 return TRUE; 2299 return TRUE;
2315 } 2300 }
2316 } 2301 }
2317 2302
2318 return FALSE; // Continue to propagate the event. 2303 return FALSE; // Continue to propagate the event.
2319 } 2304 }
2320 2305
2321 bool BrowserWindowGtk::HandleTitleBarLeftMousePress( 2306 bool BrowserWindowGtk::HandleTitleBarLeftMousePress(
2322 GdkEventButton* event, 2307 GdkEventButton* event) {
2323 guint32 last_click_time, 2308 return gtk_window_util::HandleTitleBarLeftMousePress(window_, bounds_, event);
2324 gfx::Point last_click_position) {
2325 // We want to start a move when the user single clicks, but not start a
2326 // move when the user double clicks. However, a double click sends the
2327 // following GDK events: GDK_BUTTON_PRESS, GDK_BUTTON_RELEASE,
2328 // GDK_BUTTON_PRESS, GDK_2BUTTON_PRESS, GDK_BUTTON_RELEASE. If we
2329 // start a gtk_window_begin_move_drag on the second GDK_BUTTON_PRESS,
2330 // the call to gtk_window_maximize fails. To work around this, we
2331 // keep track of the last click and if it's going to be a double click,
2332 // we don't call gtk_window_begin_move_drag.
2333 static GtkSettings* settings = gtk_settings_get_default();
2334 gint double_click_time = 250;
2335 gint double_click_distance = 5;
2336 g_object_get(G_OBJECT(settings),
2337 "gtk-double-click-time", &double_click_time,
2338 "gtk-double-click-distance", &double_click_distance,
2339 NULL);
2340
2341 guint32 click_time = event->time - last_click_time;
2342 int click_move_x = abs(event->x - last_click_position.x());
2343 int click_move_y = abs(event->y - last_click_position.y());
2344
2345 if (click_time > static_cast<guint32>(double_click_time) ||
2346 click_move_x > double_click_distance ||
2347 click_move_y > double_click_distance) {
2348 // Ignore drag requests if the window is the size of the screen.
2349 // We do this to avoid triggering fullscreen mode in metacity
2350 // (without the --no-force-fullscreen flag) and in compiz (with
2351 // Legacy Fullscreen Mode enabled).
2352 if (!BoundsMatchMonitorSize()) {
2353 gtk_window_begin_move_drag(window_, event->button,
2354 static_cast<gint>(event->x_root),
2355 static_cast<gint>(event->y_root),
2356 event->time);
2357 }
2358 return TRUE;
2359 }
2360 return FALSE;
2361 } 2309 }
2362 2310
2363 bool BrowserWindowGtk::HandleWindowEdgeLeftMousePress( 2311 bool BrowserWindowGtk::HandleWindowEdgeLeftMousePress(
2364 GtkWindow* window, 2312 GtkWindow* window,
2365 GdkWindowEdge edge, 2313 GdkWindowEdge edge,
2366 GdkEventButton* event) { 2314 GdkEventButton* event) {
2367 gtk_window_begin_resize_drag(window, edge, event->button, 2315 gtk_window_begin_resize_drag(window, edge, event->button,
2368 static_cast<gint>(event->x_root), 2316 static_cast<gint>(event->x_root),
2369 static_cast<gint>(event->y_root), 2317 static_cast<gint>(event->y_root),
2370 event->time); 2318 event->time);
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
2489 2437
2490 NOTREACHED(); 2438 NOTREACHED();
2491 return false; 2439 return false;
2492 } 2440 }
2493 2441
2494 bool BrowserWindowGtk::UseCustomFrame() const { 2442 bool BrowserWindowGtk::UseCustomFrame() const {
2495 // We don't use the custom frame for app mode windows or app window popups. 2443 // We don't use the custom frame for app mode windows or app window popups.
2496 return use_custom_frame_pref_.GetValue() && !browser_->is_app(); 2444 return use_custom_frame_pref_.GetValue() && !browser_->is_app();
2497 } 2445 }
2498 2446
2499 bool BrowserWindowGtk::BoundsMatchMonitorSize() {
2500 // A screen can be composed of multiple monitors.
2501 GdkScreen* screen = gtk_window_get_screen(window_);
2502 gint monitor_num = gdk_screen_get_monitor_at_window(screen,
2503 gtk_widget_get_window(GTK_WIDGET(window_)));
2504
2505 GdkRectangle monitor_size;
2506 gdk_screen_get_monitor_geometry(screen, monitor_num, &monitor_size);
2507 return bounds_.size() == gfx::Size(monitor_size.width, monitor_size.height);
2508 }
2509
2510 void BrowserWindowGtk::PlaceBookmarkBar(bool is_floating) { 2447 void BrowserWindowGtk::PlaceBookmarkBar(bool is_floating) {
2511 TRACE_EVENT0("ui::gtk", "BrowserWindowGtk::PlaceBookmarkBar"); 2448 TRACE_EVENT0("ui::gtk", "BrowserWindowGtk::PlaceBookmarkBar");
2512 2449
2513 GtkWidget* target_parent = NULL; 2450 GtkWidget* target_parent = NULL;
2514 if (!is_floating) { 2451 if (!is_floating) {
2515 // Place the bookmark bar at the end of |window_vbox_|; this happens after 2452 // Place the bookmark bar at the end of |window_vbox_|; this happens after
2516 // we have placed the render area at the end of |window_vbox_| so we will 2453 // we have placed the render area at the end of |window_vbox_| so we will
2517 // be above the render area. 2454 // be above the render area.
2518 target_parent = window_vbox_; 2455 target_parent = window_vbox_;
2519 } else { 2456 } else {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
2552 wm_type == ui::WM_OPENBOX || 2489 wm_type == ui::WM_OPENBOX ||
2553 wm_type == ui::WM_XFWM4); 2490 wm_type == ui::WM_XFWM4);
2554 } 2491 }
2555 2492
2556 // static 2493 // static
2557 BrowserWindow* BrowserWindow::CreateBrowserWindow(Browser* browser) { 2494 BrowserWindow* BrowserWindow::CreateBrowserWindow(Browser* browser) {
2558 BrowserWindowGtk* browser_window_gtk = new BrowserWindowGtk(browser); 2495 BrowserWindowGtk* browser_window_gtk = new BrowserWindowGtk(browser);
2559 browser_window_gtk->Init(); 2496 browser_window_gtk->Init();
2560 return browser_window_gtk; 2497 return browser_window_gtk;
2561 } 2498 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/gtk/browser_window_gtk.h ('k') | chrome/browser/ui/gtk/extensions/shell_window_gtk.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698