| OLD | NEW |
| 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/gtk_window_util.h" | 5 #include "chrome/browser/ui/gtk/gtk_window_util.h" |
| 6 | 6 |
| 7 #include <dlfcn.h> | 7 #include <dlfcn.h> |
| 8 #include "content/public/browser/render_view_host.h" | 8 #include "content/public/browser/render_view_host.h" |
| 9 #include "content/public/browser/web_contents.h" | 9 #include "content/public/browser/web_contents.h" |
| 10 | 10 |
| 11 using content::RenderWidgetHost; | 11 using content::RenderWidgetHost; |
| 12 using content::WebContents; | 12 using content::WebContents; |
| 13 | 13 |
| 14 namespace gtk_window_util { | 14 namespace gtk_window_util { |
| 15 | 15 |
| 16 // Keep track of the last click time and the last click position so we can |
| 17 // filter out extra GDK_BUTTON_PRESS events when a double click happens. |
| 18 static guint32 last_click_time; |
| 19 static int last_click_x; |
| 20 static int last_click_y; |
| 21 |
| 16 // Performs Cut/Copy/Paste operation on the |window|. | 22 // Performs Cut/Copy/Paste operation on the |window|. |
| 17 // If the current render view is focused, then just call the specified |method| | 23 // If the current render view is focused, then just call the specified |method| |
| 18 // against the current render view host, otherwise emit the specified |signal| | 24 // against the current render view host, otherwise emit the specified |signal| |
| 19 // against the focused widget. | 25 // against the focused widget. |
| 20 // TODO(suzhe): This approach does not work for plugins. | 26 // TODO(suzhe): This approach does not work for plugins. |
| 21 void DoCutCopyPaste(GtkWindow* window, | 27 void DoCutCopyPaste(GtkWindow* window, |
| 22 WebContents* web_contents, | 28 WebContents* web_contents, |
| 23 void (RenderWidgetHost::*method)(), | 29 void (RenderWidgetHost::*method)(), |
| 24 const char* signal) { | 30 const char* signal) { |
| 25 GtkWidget* widget = gtk_window_get_focus(window); | 31 GtkWidget* widget = gtk_window_get_focus(window); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 87 case GDK_WINDOW_EDGE_SOUTH: | 93 case GDK_WINDOW_EDGE_SOUTH: |
| 88 return GDK_BOTTOM_SIDE; | 94 return GDK_BOTTOM_SIDE; |
| 89 case GDK_WINDOW_EDGE_SOUTH_EAST: | 95 case GDK_WINDOW_EDGE_SOUTH_EAST: |
| 90 return GDK_BOTTOM_RIGHT_CORNER; | 96 return GDK_BOTTOM_RIGHT_CORNER; |
| 91 default: | 97 default: |
| 92 NOTREACHED(); | 98 NOTREACHED(); |
| 93 } | 99 } |
| 94 return GDK_LAST_CURSOR; | 100 return GDK_LAST_CURSOR; |
| 95 } | 101 } |
| 96 | 102 |
| 103 bool BoundsMatchMonitorSize(GtkWindow* window, gfx::Rect bounds) { |
| 104 // A screen can be composed of multiple monitors. |
| 105 GdkScreen* screen = gtk_window_get_screen(window); |
| 106 gint monitor_num = gdk_screen_get_monitor_at_window(screen, |
| 107 gtk_widget_get_window(GTK_WIDGET(window))); |
| 108 |
| 109 GdkRectangle monitor_size; |
| 110 gdk_screen_get_monitor_geometry(screen, monitor_num, &monitor_size); |
| 111 return bounds.size() == gfx::Size(monitor_size.width, monitor_size.height); |
| 112 } |
| 113 |
| 114 bool HandleTitleBarLeftMousePress( |
| 115 GtkWindow* window, |
| 116 const gfx::Rect& bounds, |
| 117 GdkEventButton* event) { |
| 118 // We want to start a move when the user single clicks, but not start a |
| 119 // move when the user double clicks. However, a double click sends the |
| 120 // following GDK events: GDK_BUTTON_PRESS, GDK_BUTTON_RELEASE, |
| 121 // GDK_BUTTON_PRESS, GDK_2BUTTON_PRESS, GDK_BUTTON_RELEASE. If we |
| 122 // start a gtk_window_begin_move_drag on the second GDK_BUTTON_PRESS, |
| 123 // the call to gtk_window_maximize fails. To work around this, we |
| 124 // keep track of the last click and if it's going to be a double click, |
| 125 // we don't call gtk_window_begin_move_drag. |
| 126 DCHECK(event->type == GDK_BUTTON_PRESS); |
| 127 DCHECK(event->button == 1); |
| 128 |
| 129 static GtkSettings* settings = gtk_settings_get_default(); |
| 130 gint double_click_time = 250; |
| 131 gint double_click_distance = 5; |
| 132 g_object_get(G_OBJECT(settings), |
| 133 "gtk-double-click-time", &double_click_time, |
| 134 "gtk-double-click-distance", &double_click_distance, |
| 135 NULL); |
| 136 |
| 137 guint32 click_time = event->time - last_click_time; |
| 138 int click_move_x = abs(event->x - last_click_x); |
| 139 int click_move_y = abs(event->y - last_click_y); |
| 140 |
| 141 last_click_time = event->time; |
| 142 last_click_x = static_cast<int>(event->x); |
| 143 last_click_y = static_cast<int>(event->y); |
| 144 |
| 145 if (click_time > static_cast<guint32>(double_click_time) || |
| 146 click_move_x > double_click_distance || |
| 147 click_move_y > double_click_distance) { |
| 148 // Ignore drag requests if the window is the size of the screen. |
| 149 // We do this to avoid triggering fullscreen mode in metacity |
| 150 // (without the --no-force-fullscreen flag) and in compiz (with |
| 151 // Legacy Fullscreen Mode enabled). |
| 152 if (!BoundsMatchMonitorSize(window, bounds)) { |
| 153 gtk_window_begin_move_drag(window, event->button, |
| 154 static_cast<gint>(event->x_root), |
| 155 static_cast<gint>(event->y_root), |
| 156 event->time); |
| 157 } |
| 158 return TRUE; |
| 159 } |
| 160 return FALSE; |
| 161 } |
| 162 |
| 163 void UnMaximize(GtkWindow* window, |
| 164 const gfx::Rect& bounds, |
| 165 const gfx::Rect& restored_bounds) { |
| 166 gtk_window_unmaximize(window); |
| 167 |
| 168 // It can happen that you end up with a window whose restore size is the same |
| 169 // as the size of the screen, so unmaximizing it merely remaximizes it due to |
| 170 // the same WM feature that SetWindowSize() works around. We try to detect |
| 171 // this and resize the window to work around the issue. |
| 172 if (bounds.size() == restored_bounds.size()) |
| 173 gtk_window_resize(window, bounds.width(), bounds.height() - 1); |
| 174 } |
| 175 |
| 97 } // namespace gtk_window_util | 176 } // namespace gtk_window_util |
| OLD | NEW |