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

Unified Diff: chrome/browser/gtk/browser_window_gtk.cc

Issue 140026: Add the ability to resize the window when over the custom frame. (Closed)
Patch Set: fix tab offset Created 11 years, 6 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/gtk/browser_window_gtk.h ('k') | chrome/browser/gtk/tabs/tab_renderer_gtk.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/gtk/browser_window_gtk.cc
diff --git a/chrome/browser/gtk/browser_window_gtk.cc b/chrome/browser/gtk/browser_window_gtk.cc
index 32b40b401ac23c1c5ecd21b679f7a9243e9598fc..9d1facd43147dc5a8765658fad2c33f4babdb71b 100644
--- a/chrome/browser/gtk/browser_window_gtk.cc
+++ b/chrome/browser/gtk/browser_window_gtk.cc
@@ -59,8 +59,18 @@ const int kLoadingAnimationFrameTimeMs = 30;
const char* kBrowserWindowKey = "__BROWSER_WINDOW_GTK__";
-// The width of the custom frame.
-const int kCustomFrameWidth = 3;
+// The frame border is only visible in restored mode and is hardcoded to 4 px
+// on each side regardless of the system window border size.
+const int kFrameBorderThickness = 4;
+// While resize areas on Windows are normally the same size as the window
+// borders, our top area is shrunk by 1 px to make it easier to move the window
+// around with our thinner top grabbable strip. (Incidentally, our side and
+// bottom resize areas don't match the frame border thickness either -- they
+// span the whole nonclient area, so there's no "dead zone" for the mouse.)
+const int kTopResizeAdjust = 1;
+// In the window corners, the resize areas don't actually expand bigger, but
+// the 16 px at the end of each edge triggers diagonal resizing.
+const int kResizeAreaCornerSize = 16;
gboolean MainWindowConfigured(GtkWindow* window, GdkEventConfigure* event,
BrowserWindowGtk* browser_win) {
@@ -267,25 +277,35 @@ gboolean OnKeyPress(GtkWindow* window, GdkEventKey* event, Browser* browser) {
}
}
-gboolean OnButtonPressEvent(GtkWidget* widget, GdkEventButton* event,
- Browser* browser) {
- // TODO(jhawkins): Investigate the possibility of the button numbers being
- // different for other mice.
- if (event->button == 8) {
- browser->GoBack(CURRENT_TAB);
- return TRUE;
- } else if (event->button == 9) {
- browser->GoForward(CURRENT_TAB);
- return TRUE;
- }
- return FALSE;
-}
-
gboolean OnFocusIn(GtkWidget* widget, GdkEventFocus* event, Browser* browser) {
BrowserList::SetLastActive(browser);
return FALSE;
}
+GdkCursorType GdkWindowEdgeToGdkCursorType(GdkWindowEdge edge) {
+ switch (edge) {
+ case GDK_WINDOW_EDGE_NORTH_WEST:
+ return GDK_TOP_LEFT_CORNER;
+ case GDK_WINDOW_EDGE_NORTH:
+ return GDK_TOP_SIDE;
+ case GDK_WINDOW_EDGE_NORTH_EAST:
+ return GDK_TOP_RIGHT_CORNER;
+ case GDK_WINDOW_EDGE_WEST:
+ return GDK_LEFT_SIDE;
+ case GDK_WINDOW_EDGE_EAST:
+ return GDK_RIGHT_SIDE;
+ case GDK_WINDOW_EDGE_SOUTH_WEST:
+ return GDK_BOTTOM_LEFT_CORNER;
+ case GDK_WINDOW_EDGE_SOUTH:
+ return GDK_BOTTOM_SIDE;
+ case GDK_WINDOW_EDGE_SOUTH_EAST:
+ return GDK_BOTTOM_RIGHT_CORNER;
+ default:
+ NOTREACHED();
+ }
+ return GDK_LAST_CURSOR;
+}
+
} // namespace
std::map<XID, GtkWindow*> BrowserWindowGtk::xid_map_;
@@ -293,11 +313,14 @@ std::map<XID, GtkWindow*> BrowserWindowGtk::xid_map_;
BrowserWindowGtk::BrowserWindowGtk(Browser* browser)
: browser_(browser),
full_screen_(false),
- drag_active_(false) {
+ drag_active_(false),
+ frame_cursor_(NULL) {
use_custom_frame_.Init(prefs::kUseCustomChromeFrame,
browser_->profile()->GetPrefs(), this);
window_ = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL));
g_object_set_data(G_OBJECT(window_), kBrowserWindowKey, this);
+ gtk_widget_add_events(GTK_WIDGET(window_), GDK_BUTTON_PRESS_MASK |
+ GDK_POINTER_MOTION_MASK);
SetWindowIcon();
SetBackgroundColor();
@@ -315,6 +338,11 @@ BrowserWindowGtk::BrowserWindowGtk(Browser* browser)
BrowserWindowGtk::~BrowserWindowGtk() {
browser_->tabstrip_model()->RemoveObserver(this);
+
+ if (frame_cursor_) {
+ gdk_cursor_unref(frame_cursor_);
+ frame_cursor_ = NULL;
+ }
}
void BrowserWindowGtk::HandleAccelerator(guint keyval,
@@ -774,6 +802,15 @@ void BrowserWindowGtk::AddFindBar(FindBarGtk* findbar) {
gtk_box_reorder_child(GTK_BOX(render_area_vbox_), findbar->widget(), 0);
}
+void BrowserWindowGtk::ResetCustomFrameCursor() {
+ if (!frame_cursor_)
+ return;
+
+ gdk_cursor_unref(frame_cursor_);
+ frame_cursor_ = NULL;
+ gdk_window_set_cursor(GTK_WIDGET(window_)->window, NULL);
+}
+
// static
BrowserWindowGtk* BrowserWindowGtk::GetBrowserWindowForNativeWindow(
gfx::NativeWindow window) {
@@ -833,8 +870,10 @@ void BrowserWindowGtk::ConnectHandlersToSignals() {
G_CALLBACK(MainWindowUnMapped), this);
g_signal_connect(window_, "key-press-event",
G_CALLBACK(OnKeyPress), browser_.get());
+ g_signal_connect(window_, "motion-notify-event",
+ G_CALLBACK(OnMouseMoveEvent), this);
g_signal_connect(window_, "button-press-event",
- G_CALLBACK(OnButtonPressEvent), browser_.get());
+ G_CALLBACK(OnButtonPressEvent), this);
g_signal_connect(window_, "focus-in-event",
G_CALLBACK(OnFocusIn), browser_.get());
}
@@ -977,7 +1016,7 @@ void BrowserWindowGtk::UpdateCustomFrame() {
UpdateWindowShape(bounds_.width(), bounds_.height());
if (enable) {
gtk_alignment_set_padding(GTK_ALIGNMENT(window_container_), 1,
- kCustomFrameWidth, kCustomFrameWidth, kCustomFrameWidth);
+ kFrameBorderThickness, kFrameBorderThickness, kFrameBorderThickness);
} else {
gtk_alignment_set_padding(GTK_ALIGNMENT(window_container_), 0, 0, 0, 0);
}
@@ -1021,6 +1060,93 @@ gboolean BrowserWindowGtk::OnGtkAccelerator(GtkAccelGroup* accel_group,
}
// static
+gboolean BrowserWindowGtk::OnMouseMoveEvent(GtkWidget* widget,
+ GdkEventMotion* event, BrowserWindowGtk* browser) {
+ // Update the cursor if we're on the custom frame border.
+ GdkWindowEdge edge;
+ bool has_hit_edge = browser->GetWindowEdge(static_cast<int>(event->x),
+ static_cast<int>(event->y), &edge);
+ GdkCursorType new_cursor = GDK_LAST_CURSOR;
+ if (has_hit_edge)
+ new_cursor = GdkWindowEdgeToGdkCursorType(edge);
+
+ GdkCursorType last_cursor = GDK_LAST_CURSOR;
+ if (browser->frame_cursor_)
+ last_cursor = browser->frame_cursor_->type;
+
+ if (last_cursor != new_cursor) {
+ if (browser->frame_cursor_) {
+ gdk_cursor_unref(browser->frame_cursor_);
+ browser->frame_cursor_ = NULL;
+ }
+ if (has_hit_edge) {
+ browser->frame_cursor_ = gdk_cursor_new(new_cursor);
+ gdk_window_set_cursor(GTK_WIDGET(browser->window_)->window,
+ browser->frame_cursor_);
+ } else {
+ gdk_window_set_cursor(GTK_WIDGET(browser->window_)->window, NULL);
+ }
+ }
+ return FALSE;
+}
+
+// static
+gboolean BrowserWindowGtk::OnButtonPressEvent(GtkWidget* widget,
+ GdkEventButton* event, BrowserWindowGtk* browser) {
+ // Handle back/forward.
+ // TODO(jhawkins): Investigate the possibility of the button numbers being
+ // different for other mice.
+ if (event->button == 8) {
+ browser->browser_->GoBack(CURRENT_TAB);
+ return TRUE;
+ } else if (event->button == 9) {
+ browser->browser_->GoForward(CURRENT_TAB);
+ return TRUE;
+ }
+
+ // Handle left and right clicks. In particular, we care about clicks in the
+ // custom frame border and clicks in the titlebar.
+ GdkWindowEdge edge;
+ bool has_hit_edge = browser->GetWindowEdge(static_cast<int>(event->x),
+ static_cast<int>(event->y), &edge);
+ // Ignore clicks that are in/below the tab strip.
+ gint tabstrip_y;
+ gtk_widget_get_pointer(browser->toolbar_->widget(), NULL, &tabstrip_y);
+ bool has_hit_titlebar = !browser->IsFullscreen() && (tabstrip_y < 0)
+ && !has_hit_edge;
+ if (event->button == 1) {
+ if (GDK_BUTTON_PRESS == event->type) {
+ if (has_hit_titlebar) {
+ gtk_window_begin_move_drag(browser->window_, event->button,
+ event->x_root, event->y_root, event->time);
+ return TRUE;
+ } else if (has_hit_edge) {
+ gtk_window_begin_resize_drag(browser->window_, edge, event->button,
+ event->x_root, event->y_root, event->time);
+ return TRUE;
+ }
+ } else if (GDK_2BUTTON_PRESS == event->type) {
+ if (has_hit_titlebar) {
+ // Maximize/restore on double click.
+ if (browser->IsMaximized()) {
+ gtk_window_unmaximize(browser->window_);
+ } else {
+ gtk_window_maximize(browser->window_);
+ }
+ return TRUE;
+ }
+ }
+ } else if (event->button == 3) {
+ if (has_hit_titlebar) {
+ browser->titlebar_->ShowContextMenu();
+ return TRUE;
+ }
+ }
+
+ return FALSE; // Continue to propagate the event.
+}
+
+// static
void BrowserWindowGtk::MainWindowMapped(GtkWidget* widget,
BrowserWindowGtk* window) {
// Map the X Window ID of the window to our window.
@@ -1076,3 +1202,58 @@ bool BrowserWindowGtk::IsToolbarSupported() {
bool BrowserWindowGtk::IsBookmarkBarSupported() {
return browser_->SupportsWindowFeature(Browser::FEATURE_BOOKMARKBAR);
}
+
+bool BrowserWindowGtk::GetWindowEdge(int x, int y, GdkWindowEdge* edge) {
+ if (!use_custom_frame_.GetValue())
+ return false;
+
+ if (IsMaximized() || IsFullscreen())
+ return false;
+
+ if (x < kFrameBorderThickness) {
+ // Left edge.
+ if (y < kResizeAreaCornerSize - kTopResizeAdjust) {
+ *edge = GDK_WINDOW_EDGE_NORTH_WEST;
+ } else if (y < bounds_.height() - kResizeAreaCornerSize) {
+ *edge = GDK_WINDOW_EDGE_WEST;
+ } else {
+ *edge = GDK_WINDOW_EDGE_SOUTH_WEST;
+ }
+ return true;
+ } else if (x < bounds_.width() - kFrameBorderThickness) {
+ if (y < kFrameBorderThickness - kTopResizeAdjust) {
+ // Top edge.
+ if (x < kResizeAreaCornerSize) {
+ *edge = GDK_WINDOW_EDGE_NORTH_WEST;
+ } else if (x < x < bounds_.width() - kResizeAreaCornerSize) {
+ *edge = GDK_WINDOW_EDGE_NORTH;
+ } else {
+ *edge = GDK_WINDOW_EDGE_NORTH_EAST;
+ }
+ } else if (y < bounds_.height() - kFrameBorderThickness) {
+ // Ignore the middle content area.
+ return false;
+ } else {
+ // Bottom edge.
+ if (x < kResizeAreaCornerSize) {
+ *edge = GDK_WINDOW_EDGE_SOUTH_WEST;
+ } else if (x < bounds_.width() - kResizeAreaCornerSize) {
+ *edge = GDK_WINDOW_EDGE_SOUTH;
+ } else {
+ *edge = GDK_WINDOW_EDGE_SOUTH_EAST;
+ }
+ }
+ return true;
+ } else {
+ // Right edge.
+ if (y < kResizeAreaCornerSize - kTopResizeAdjust) {
+ *edge = GDK_WINDOW_EDGE_NORTH_EAST;
+ } else if (y < bounds_.height() - kResizeAreaCornerSize) {
+ *edge = GDK_WINDOW_EDGE_EAST;
+ } else {
+ *edge = GDK_WINDOW_EDGE_SOUTH_EAST;
+ }
+ return true;
+ }
+ NOTREACHED();
+}
« no previous file with comments | « chrome/browser/gtk/browser_window_gtk.h ('k') | chrome/browser/gtk/tabs/tab_renderer_gtk.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698