| 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 #include "chrome/browser/gtk/browser_window_gtk.h" | 5 #include "chrome/browser/gtk/browser_window_gtk.h" |
| 6 | 6 |
| 7 #include <gdk/gdkkeysyms.h> | 7 #include <gdk/gdkkeysyms.h> |
| 8 | 8 |
| 9 #include "app/resource_bundle.h" | 9 #include "app/resource_bundle.h" |
| 10 #include "app/theme_provider.h" | 10 #include "app/theme_provider.h" |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 52 #include "chrome/browser/views/tabs/tab_overview_types.h" | 52 #include "chrome/browser/views/tabs/tab_overview_types.h" |
| 53 #endif | 53 #endif |
| 54 | 54 |
| 55 namespace { | 55 namespace { |
| 56 | 56 |
| 57 // The number of milliseconds between loading animation frames. | 57 // The number of milliseconds between loading animation frames. |
| 58 const int kLoadingAnimationFrameTimeMs = 30; | 58 const int kLoadingAnimationFrameTimeMs = 30; |
| 59 | 59 |
| 60 const char* kBrowserWindowKey = "__BROWSER_WINDOW_GTK__"; | 60 const char* kBrowserWindowKey = "__BROWSER_WINDOW_GTK__"; |
| 61 | 61 |
| 62 // The width of the custom frame. | 62 // The frame border is only visible in restored mode and is hardcoded to 4 px |
| 63 const int kCustomFrameWidth = 3; | 63 // on each side regardless of the system window border size. |
| 64 const int kFrameBorderThickness = 4; |
| 65 // While resize areas on Windows are normally the same size as the window |
| 66 // borders, our top area is shrunk by 1 px to make it easier to move the window |
| 67 // around with our thinner top grabbable strip. (Incidentally, our side and |
| 68 // bottom resize areas don't match the frame border thickness either -- they |
| 69 // span the whole nonclient area, so there's no "dead zone" for the mouse.) |
| 70 const int kTopResizeAdjust = 1; |
| 71 // In the window corners, the resize areas don't actually expand bigger, but |
| 72 // the 16 px at the end of each edge triggers diagonal resizing. |
| 73 const int kResizeAreaCornerSize = 16; |
| 64 | 74 |
| 65 gboolean MainWindowConfigured(GtkWindow* window, GdkEventConfigure* event, | 75 gboolean MainWindowConfigured(GtkWindow* window, GdkEventConfigure* event, |
| 66 BrowserWindowGtk* browser_win) { | 76 BrowserWindowGtk* browser_win) { |
| 67 gfx::Rect bounds = gfx::Rect(event->x, event->y, event->width, event->height); | 77 gfx::Rect bounds = gfx::Rect(event->x, event->y, event->width, event->height); |
| 68 browser_win->OnBoundsChanged(bounds); | 78 browser_win->OnBoundsChanged(bounds); |
| 69 return FALSE; | 79 return FALSE; |
| 70 } | 80 } |
| 71 | 81 |
| 72 gboolean MainWindowStateChanged(GtkWindow* window, GdkEventWindowState* event, | 82 gboolean MainWindowStateChanged(GtkWindow* window, GdkEventWindowState* event, |
| 73 BrowserWindowGtk* browser_win) { | 83 BrowserWindowGtk* browser_win) { |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 260 } | 270 } |
| 261 | 271 |
| 262 return gtk_window_propagate_key_event(window, event); | 272 return gtk_window_propagate_key_event(window, event); |
| 263 } else { | 273 } else { |
| 264 bool rv = gtk_window_propagate_key_event(window, event); | 274 bool rv = gtk_window_propagate_key_event(window, event); |
| 265 DCHECK(rv); | 275 DCHECK(rv); |
| 266 return TRUE; | 276 return TRUE; |
| 267 } | 277 } |
| 268 } | 278 } |
| 269 | 279 |
| 270 gboolean OnButtonPressEvent(GtkWidget* widget, GdkEventButton* event, | |
| 271 Browser* browser) { | |
| 272 // TODO(jhawkins): Investigate the possibility of the button numbers being | |
| 273 // different for other mice. | |
| 274 if (event->button == 8) { | |
| 275 browser->GoBack(CURRENT_TAB); | |
| 276 return TRUE; | |
| 277 } else if (event->button == 9) { | |
| 278 browser->GoForward(CURRENT_TAB); | |
| 279 return TRUE; | |
| 280 } | |
| 281 return FALSE; | |
| 282 } | |
| 283 | |
| 284 gboolean OnFocusIn(GtkWidget* widget, GdkEventFocus* event, Browser* browser) { | 280 gboolean OnFocusIn(GtkWidget* widget, GdkEventFocus* event, Browser* browser) { |
| 285 BrowserList::SetLastActive(browser); | 281 BrowserList::SetLastActive(browser); |
| 286 return FALSE; | 282 return FALSE; |
| 287 } | 283 } |
| 288 | 284 |
| 285 GdkCursorType GdkWindowEdgeToGdkCursorType(GdkWindowEdge edge) { |
| 286 switch (edge) { |
| 287 case GDK_WINDOW_EDGE_NORTH_WEST: |
| 288 return GDK_TOP_LEFT_CORNER; |
| 289 case GDK_WINDOW_EDGE_NORTH: |
| 290 return GDK_TOP_SIDE; |
| 291 case GDK_WINDOW_EDGE_NORTH_EAST: |
| 292 return GDK_TOP_RIGHT_CORNER; |
| 293 case GDK_WINDOW_EDGE_WEST: |
| 294 return GDK_LEFT_SIDE; |
| 295 case GDK_WINDOW_EDGE_EAST: |
| 296 return GDK_RIGHT_SIDE; |
| 297 case GDK_WINDOW_EDGE_SOUTH_WEST: |
| 298 return GDK_BOTTOM_LEFT_CORNER; |
| 299 case GDK_WINDOW_EDGE_SOUTH: |
| 300 return GDK_BOTTOM_SIDE; |
| 301 case GDK_WINDOW_EDGE_SOUTH_EAST: |
| 302 return GDK_BOTTOM_RIGHT_CORNER; |
| 303 default: |
| 304 NOTREACHED(); |
| 305 } |
| 306 return GDK_LAST_CURSOR; |
| 307 } |
| 308 |
| 289 } // namespace | 309 } // namespace |
| 290 | 310 |
| 291 std::map<XID, GtkWindow*> BrowserWindowGtk::xid_map_; | 311 std::map<XID, GtkWindow*> BrowserWindowGtk::xid_map_; |
| 292 | 312 |
| 293 BrowserWindowGtk::BrowserWindowGtk(Browser* browser) | 313 BrowserWindowGtk::BrowserWindowGtk(Browser* browser) |
| 294 : browser_(browser), | 314 : browser_(browser), |
| 295 full_screen_(false), | 315 full_screen_(false), |
| 296 drag_active_(false) { | 316 drag_active_(false), |
| 317 frame_cursor_(NULL) { |
| 297 use_custom_frame_.Init(prefs::kUseCustomChromeFrame, | 318 use_custom_frame_.Init(prefs::kUseCustomChromeFrame, |
| 298 browser_->profile()->GetPrefs(), this); | 319 browser_->profile()->GetPrefs(), this); |
| 299 window_ = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL)); | 320 window_ = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL)); |
| 300 g_object_set_data(G_OBJECT(window_), kBrowserWindowKey, this); | 321 g_object_set_data(G_OBJECT(window_), kBrowserWindowKey, this); |
| 322 gtk_widget_add_events(GTK_WIDGET(window_), GDK_BUTTON_PRESS_MASK | |
| 323 GDK_POINTER_MOTION_MASK); |
| 301 | 324 |
| 302 SetWindowIcon(); | 325 SetWindowIcon(); |
| 303 SetBackgroundColor(); | 326 SetBackgroundColor(); |
| 304 SetGeometryHints(); | 327 SetGeometryHints(); |
| 305 ConnectHandlersToSignals(); | 328 ConnectHandlersToSignals(); |
| 306 ConnectAccelerators(); | 329 ConnectAccelerators(); |
| 307 bounds_ = GetInitialWindowBounds(window_); | 330 bounds_ = GetInitialWindowBounds(window_); |
| 308 | 331 |
| 309 InitWidgets(); | 332 InitWidgets(); |
| 310 HideUnsupportedWindowFeatures(); | 333 HideUnsupportedWindowFeatures(); |
| 311 | 334 |
| 312 registrar_.Add(this, NotificationType::BOOKMARK_BAR_VISIBILITY_PREF_CHANGED, | 335 registrar_.Add(this, NotificationType::BOOKMARK_BAR_VISIBILITY_PREF_CHANGED, |
| 313 NotificationService::AllSources()); | 336 NotificationService::AllSources()); |
| 314 } | 337 } |
| 315 | 338 |
| 316 BrowserWindowGtk::~BrowserWindowGtk() { | 339 BrowserWindowGtk::~BrowserWindowGtk() { |
| 317 browser_->tabstrip_model()->RemoveObserver(this); | 340 browser_->tabstrip_model()->RemoveObserver(this); |
| 341 |
| 342 if (frame_cursor_) { |
| 343 gdk_cursor_unref(frame_cursor_); |
| 344 frame_cursor_ = NULL; |
| 345 } |
| 318 } | 346 } |
| 319 | 347 |
| 320 void BrowserWindowGtk::HandleAccelerator(guint keyval, | 348 void BrowserWindowGtk::HandleAccelerator(guint keyval, |
| 321 GdkModifierType modifier) { | 349 GdkModifierType modifier) { |
| 322 if (!HandleCustomAccelerator(keyval, modifier, browser_.get())) { | 350 if (!HandleCustomAccelerator(keyval, modifier, browser_.get())) { |
| 323 // Pass the accelerator on to GTK. | 351 // Pass the accelerator on to GTK. |
| 324 gtk_accel_groups_activate(G_OBJECT(window_), keyval, modifier); | 352 gtk_accel_groups_activate(G_OBJECT(window_), keyval, modifier); |
| 325 } | 353 } |
| 326 } | 354 } |
| 327 | 355 |
| (...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 767 bool BrowserWindowGtk::ShouldShowWindowIcon() const { | 795 bool BrowserWindowGtk::ShouldShowWindowIcon() const { |
| 768 return browser_->SupportsWindowFeature(Browser::FEATURE_TITLEBAR); | 796 return browser_->SupportsWindowFeature(Browser::FEATURE_TITLEBAR); |
| 769 } | 797 } |
| 770 | 798 |
| 771 void BrowserWindowGtk::AddFindBar(FindBarGtk* findbar) { | 799 void BrowserWindowGtk::AddFindBar(FindBarGtk* findbar) { |
| 772 gtk_box_pack_start(GTK_BOX(render_area_vbox_), findbar->widget(), | 800 gtk_box_pack_start(GTK_BOX(render_area_vbox_), findbar->widget(), |
| 773 FALSE, FALSE, 0); | 801 FALSE, FALSE, 0); |
| 774 gtk_box_reorder_child(GTK_BOX(render_area_vbox_), findbar->widget(), 0); | 802 gtk_box_reorder_child(GTK_BOX(render_area_vbox_), findbar->widget(), 0); |
| 775 } | 803 } |
| 776 | 804 |
| 805 void BrowserWindowGtk::ResetCustomFrameCursor() { |
| 806 if (!frame_cursor_) |
| 807 return; |
| 808 |
| 809 gdk_cursor_unref(frame_cursor_); |
| 810 frame_cursor_ = NULL; |
| 811 gdk_window_set_cursor(GTK_WIDGET(window_)->window, NULL); |
| 812 } |
| 813 |
| 777 // static | 814 // static |
| 778 BrowserWindowGtk* BrowserWindowGtk::GetBrowserWindowForNativeWindow( | 815 BrowserWindowGtk* BrowserWindowGtk::GetBrowserWindowForNativeWindow( |
| 779 gfx::NativeWindow window) { | 816 gfx::NativeWindow window) { |
| 780 if (window) { | 817 if (window) { |
| 781 return static_cast<BrowserWindowGtk*>( | 818 return static_cast<BrowserWindowGtk*>( |
| 782 g_object_get_data(G_OBJECT(window), kBrowserWindowKey)); | 819 g_object_get_data(G_OBJECT(window), kBrowserWindowKey)); |
| 783 } | 820 } |
| 784 | 821 |
| 785 return NULL; | 822 return NULL; |
| 786 } | 823 } |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 826 g_signal_connect(window_, "configure-event", | 863 g_signal_connect(window_, "configure-event", |
| 827 G_CALLBACK(MainWindowConfigured), this); | 864 G_CALLBACK(MainWindowConfigured), this); |
| 828 g_signal_connect(window_, "window-state-event", | 865 g_signal_connect(window_, "window-state-event", |
| 829 G_CALLBACK(MainWindowStateChanged), this); | 866 G_CALLBACK(MainWindowStateChanged), this); |
| 830 g_signal_connect(window_, "map", | 867 g_signal_connect(window_, "map", |
| 831 G_CALLBACK(MainWindowMapped), this); | 868 G_CALLBACK(MainWindowMapped), this); |
| 832 g_signal_connect(window_, "unmap", | 869 g_signal_connect(window_, "unmap", |
| 833 G_CALLBACK(MainWindowUnMapped), this); | 870 G_CALLBACK(MainWindowUnMapped), this); |
| 834 g_signal_connect(window_, "key-press-event", | 871 g_signal_connect(window_, "key-press-event", |
| 835 G_CALLBACK(OnKeyPress), browser_.get()); | 872 G_CALLBACK(OnKeyPress), browser_.get()); |
| 873 g_signal_connect(window_, "motion-notify-event", |
| 874 G_CALLBACK(OnMouseMoveEvent), this); |
| 836 g_signal_connect(window_, "button-press-event", | 875 g_signal_connect(window_, "button-press-event", |
| 837 G_CALLBACK(OnButtonPressEvent), browser_.get()); | 876 G_CALLBACK(OnButtonPressEvent), this); |
| 838 g_signal_connect(window_, "focus-in-event", | 877 g_signal_connect(window_, "focus-in-event", |
| 839 G_CALLBACK(OnFocusIn), browser_.get()); | 878 G_CALLBACK(OnFocusIn), browser_.get()); |
| 840 } | 879 } |
| 841 | 880 |
| 842 void BrowserWindowGtk::InitWidgets() { | 881 void BrowserWindowGtk::InitWidgets() { |
| 843 // This vbox encompasses all of the widgets within the browser, including the | 882 // This vbox encompasses all of the widgets within the browser, including the |
| 844 // tabstrip and the content vbox. The vbox is put in a floating container | 883 // tabstrip and the content vbox. The vbox is put in a floating container |
| 845 // (see gtk_floating_container.h) so we can position the | 884 // (see gtk_floating_container.h) so we can position the |
| 846 // minimize/maximize/close buttons. The floating container is then put in an | 885 // minimize/maximize/close buttons. The floating container is then put in an |
| 847 // alignment so we can do custom frame drawing if the user turns of window | 886 // alignment so we can do custom frame drawing if the user turns of window |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 970 } | 1009 } |
| 971 } | 1010 } |
| 972 | 1011 |
| 973 void BrowserWindowGtk::UpdateCustomFrame() { | 1012 void BrowserWindowGtk::UpdateCustomFrame() { |
| 974 bool enable = use_custom_frame_.GetValue() && !full_screen_; | 1013 bool enable = use_custom_frame_.GetValue() && !full_screen_; |
| 975 gtk_window_set_decorated(window_, !enable); | 1014 gtk_window_set_decorated(window_, !enable); |
| 976 titlebar_->UpdateCustomFrame(enable); | 1015 titlebar_->UpdateCustomFrame(enable); |
| 977 UpdateWindowShape(bounds_.width(), bounds_.height()); | 1016 UpdateWindowShape(bounds_.width(), bounds_.height()); |
| 978 if (enable) { | 1017 if (enable) { |
| 979 gtk_alignment_set_padding(GTK_ALIGNMENT(window_container_), 1, | 1018 gtk_alignment_set_padding(GTK_ALIGNMENT(window_container_), 1, |
| 980 kCustomFrameWidth, kCustomFrameWidth, kCustomFrameWidth); | 1019 kFrameBorderThickness, kFrameBorderThickness, kFrameBorderThickness); |
| 981 } else { | 1020 } else { |
| 982 gtk_alignment_set_padding(GTK_ALIGNMENT(window_container_), 0, 0, 0, 0); | 1021 gtk_alignment_set_padding(GTK_ALIGNMENT(window_container_), 0, 0, 0, 0); |
| 983 } | 1022 } |
| 984 } | 1023 } |
| 985 | 1024 |
| 986 void BrowserWindowGtk::SaveWindowPosition() { | 1025 void BrowserWindowGtk::SaveWindowPosition() { |
| 987 // Browser::SaveWindowPlacement is used for session restore. | 1026 // Browser::SaveWindowPlacement is used for session restore. |
| 988 if (browser_->ShouldSaveWindowPlacement()) | 1027 if (browser_->ShouldSaveWindowPlacement()) |
| 989 browser_->SaveWindowPlacement(bounds_, IsMaximized()); | 1028 browser_->SaveWindowPlacement(bounds_, IsMaximized()); |
| 990 | 1029 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1014 guint keyval, | 1053 guint keyval, |
| 1015 GdkModifierType modifier, | 1054 GdkModifierType modifier, |
| 1016 BrowserWindowGtk* browser_window) { | 1055 BrowserWindowGtk* browser_window) { |
| 1017 int command_id = GetCommandId(keyval, modifier); | 1056 int command_id = GetCommandId(keyval, modifier); |
| 1018 browser_window->ExecuteBrowserCommand(command_id); | 1057 browser_window->ExecuteBrowserCommand(command_id); |
| 1019 | 1058 |
| 1020 return TRUE; | 1059 return TRUE; |
| 1021 } | 1060 } |
| 1022 | 1061 |
| 1023 // static | 1062 // static |
| 1063 gboolean BrowserWindowGtk::OnMouseMoveEvent(GtkWidget* widget, |
| 1064 GdkEventMotion* event, BrowserWindowGtk* browser) { |
| 1065 // Update the cursor if we're on the custom frame border. |
| 1066 GdkWindowEdge edge; |
| 1067 bool has_hit_edge = browser->GetWindowEdge(static_cast<int>(event->x), |
| 1068 static_cast<int>(event->y), &edge); |
| 1069 GdkCursorType new_cursor = GDK_LAST_CURSOR; |
| 1070 if (has_hit_edge) |
| 1071 new_cursor = GdkWindowEdgeToGdkCursorType(edge); |
| 1072 |
| 1073 GdkCursorType last_cursor = GDK_LAST_CURSOR; |
| 1074 if (browser->frame_cursor_) |
| 1075 last_cursor = browser->frame_cursor_->type; |
| 1076 |
| 1077 if (last_cursor != new_cursor) { |
| 1078 if (browser->frame_cursor_) { |
| 1079 gdk_cursor_unref(browser->frame_cursor_); |
| 1080 browser->frame_cursor_ = NULL; |
| 1081 } |
| 1082 if (has_hit_edge) { |
| 1083 browser->frame_cursor_ = gdk_cursor_new(new_cursor); |
| 1084 gdk_window_set_cursor(GTK_WIDGET(browser->window_)->window, |
| 1085 browser->frame_cursor_); |
| 1086 } else { |
| 1087 gdk_window_set_cursor(GTK_WIDGET(browser->window_)->window, NULL); |
| 1088 } |
| 1089 } |
| 1090 return FALSE; |
| 1091 } |
| 1092 |
| 1093 // static |
| 1094 gboolean BrowserWindowGtk::OnButtonPressEvent(GtkWidget* widget, |
| 1095 GdkEventButton* event, BrowserWindowGtk* browser) { |
| 1096 // Handle back/forward. |
| 1097 // TODO(jhawkins): Investigate the possibility of the button numbers being |
| 1098 // different for other mice. |
| 1099 if (event->button == 8) { |
| 1100 browser->browser_->GoBack(CURRENT_TAB); |
| 1101 return TRUE; |
| 1102 } else if (event->button == 9) { |
| 1103 browser->browser_->GoForward(CURRENT_TAB); |
| 1104 return TRUE; |
| 1105 } |
| 1106 |
| 1107 // Handle left and right clicks. In particular, we care about clicks in the |
| 1108 // custom frame border and clicks in the titlebar. |
| 1109 GdkWindowEdge edge; |
| 1110 bool has_hit_edge = browser->GetWindowEdge(static_cast<int>(event->x), |
| 1111 static_cast<int>(event->y), &edge); |
| 1112 // Ignore clicks that are in/below the tab strip. |
| 1113 gint tabstrip_y; |
| 1114 gtk_widget_get_pointer(browser->toolbar_->widget(), NULL, &tabstrip_y); |
| 1115 bool has_hit_titlebar = !browser->IsFullscreen() && (tabstrip_y < 0) |
| 1116 && !has_hit_edge; |
| 1117 if (event->button == 1) { |
| 1118 if (GDK_BUTTON_PRESS == event->type) { |
| 1119 if (has_hit_titlebar) { |
| 1120 gtk_window_begin_move_drag(browser->window_, event->button, |
| 1121 event->x_root, event->y_root, event->time); |
| 1122 return TRUE; |
| 1123 } else if (has_hit_edge) { |
| 1124 gtk_window_begin_resize_drag(browser->window_, edge, event->button, |
| 1125 event->x_root, event->y_root, event->time); |
| 1126 return TRUE; |
| 1127 } |
| 1128 } else if (GDK_2BUTTON_PRESS == event->type) { |
| 1129 if (has_hit_titlebar) { |
| 1130 // Maximize/restore on double click. |
| 1131 if (browser->IsMaximized()) { |
| 1132 gtk_window_unmaximize(browser->window_); |
| 1133 } else { |
| 1134 gtk_window_maximize(browser->window_); |
| 1135 } |
| 1136 return TRUE; |
| 1137 } |
| 1138 } |
| 1139 } else if (event->button == 3) { |
| 1140 if (has_hit_titlebar) { |
| 1141 browser->titlebar_->ShowContextMenu(); |
| 1142 return TRUE; |
| 1143 } |
| 1144 } |
| 1145 |
| 1146 return FALSE; // Continue to propagate the event. |
| 1147 } |
| 1148 |
| 1149 // static |
| 1024 void BrowserWindowGtk::MainWindowMapped(GtkWidget* widget, | 1150 void BrowserWindowGtk::MainWindowMapped(GtkWidget* widget, |
| 1025 BrowserWindowGtk* window) { | 1151 BrowserWindowGtk* window) { |
| 1026 // Map the X Window ID of the window to our window. | 1152 // Map the X Window ID of the window to our window. |
| 1027 XID xid = x11_util::GetX11WindowFromGtkWidget(widget); | 1153 XID xid = x11_util::GetX11WindowFromGtkWidget(widget); |
| 1028 BrowserWindowGtk::xid_map_.insert( | 1154 BrowserWindowGtk::xid_map_.insert( |
| 1029 std::pair<XID, GtkWindow*>(xid, GTK_WINDOW(widget))); | 1155 std::pair<XID, GtkWindow*>(xid, GTK_WINDOW(widget))); |
| 1030 } | 1156 } |
| 1031 | 1157 |
| 1032 // static | 1158 // static |
| 1033 void BrowserWindowGtk::MainWindowUnMapped(GtkWidget* widget, | 1159 void BrowserWindowGtk::MainWindowUnMapped(GtkWidget* widget, |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1069 } | 1195 } |
| 1070 | 1196 |
| 1071 bool BrowserWindowGtk::IsToolbarSupported() { | 1197 bool BrowserWindowGtk::IsToolbarSupported() { |
| 1072 return browser_->SupportsWindowFeature(Browser::FEATURE_TOOLBAR) || | 1198 return browser_->SupportsWindowFeature(Browser::FEATURE_TOOLBAR) || |
| 1073 browser_->SupportsWindowFeature(Browser::FEATURE_LOCATIONBAR); | 1199 browser_->SupportsWindowFeature(Browser::FEATURE_LOCATIONBAR); |
| 1074 } | 1200 } |
| 1075 | 1201 |
| 1076 bool BrowserWindowGtk::IsBookmarkBarSupported() { | 1202 bool BrowserWindowGtk::IsBookmarkBarSupported() { |
| 1077 return browser_->SupportsWindowFeature(Browser::FEATURE_BOOKMARKBAR); | 1203 return browser_->SupportsWindowFeature(Browser::FEATURE_BOOKMARKBAR); |
| 1078 } | 1204 } |
| 1205 |
| 1206 bool BrowserWindowGtk::GetWindowEdge(int x, int y, GdkWindowEdge* edge) { |
| 1207 if (!use_custom_frame_.GetValue()) |
| 1208 return false; |
| 1209 |
| 1210 if (IsMaximized() || IsFullscreen()) |
| 1211 return false; |
| 1212 |
| 1213 if (x < kFrameBorderThickness) { |
| 1214 // Left edge. |
| 1215 if (y < kResizeAreaCornerSize - kTopResizeAdjust) { |
| 1216 *edge = GDK_WINDOW_EDGE_NORTH_WEST; |
| 1217 } else if (y < bounds_.height() - kResizeAreaCornerSize) { |
| 1218 *edge = GDK_WINDOW_EDGE_WEST; |
| 1219 } else { |
| 1220 *edge = GDK_WINDOW_EDGE_SOUTH_WEST; |
| 1221 } |
| 1222 return true; |
| 1223 } else if (x < bounds_.width() - kFrameBorderThickness) { |
| 1224 if (y < kFrameBorderThickness - kTopResizeAdjust) { |
| 1225 // Top edge. |
| 1226 if (x < kResizeAreaCornerSize) { |
| 1227 *edge = GDK_WINDOW_EDGE_NORTH_WEST; |
| 1228 } else if (x < x < bounds_.width() - kResizeAreaCornerSize) { |
| 1229 *edge = GDK_WINDOW_EDGE_NORTH; |
| 1230 } else { |
| 1231 *edge = GDK_WINDOW_EDGE_NORTH_EAST; |
| 1232 } |
| 1233 } else if (y < bounds_.height() - kFrameBorderThickness) { |
| 1234 // Ignore the middle content area. |
| 1235 return false; |
| 1236 } else { |
| 1237 // Bottom edge. |
| 1238 if (x < kResizeAreaCornerSize) { |
| 1239 *edge = GDK_WINDOW_EDGE_SOUTH_WEST; |
| 1240 } else if (x < bounds_.width() - kResizeAreaCornerSize) { |
| 1241 *edge = GDK_WINDOW_EDGE_SOUTH; |
| 1242 } else { |
| 1243 *edge = GDK_WINDOW_EDGE_SOUTH_EAST; |
| 1244 } |
| 1245 } |
| 1246 return true; |
| 1247 } else { |
| 1248 // Right edge. |
| 1249 if (y < kResizeAreaCornerSize - kTopResizeAdjust) { |
| 1250 *edge = GDK_WINDOW_EDGE_NORTH_EAST; |
| 1251 } else if (y < bounds_.height() - kResizeAreaCornerSize) { |
| 1252 *edge = GDK_WINDOW_EDGE_EAST; |
| 1253 } else { |
| 1254 *edge = GDK_WINDOW_EDGE_SOUTH_EAST; |
| 1255 } |
| 1256 return true; |
| 1257 } |
| 1258 NOTREACHED(); |
| 1259 } |
| OLD | NEW |