summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-04 05:42:11 +0000
committerben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-04 05:42:11 +0000
commit0e7992cbfcf2922eb42cc85a4ccc8a9dfce2d252 (patch)
treea023736d890db05978a3403d4b010c2e948a72c3
parent08df0f2fc34a4abc51e7d5f5f37bcdaaef82cab6 (diff)
downloadchromium_src-0e7992cbfcf2922eb42cc85a4ccc8a9dfce2d252.zip
chromium_src-0e7992cbfcf2922eb42cc85a4ccc8a9dfce2d252.tar.gz
chromium_src-0e7992cbfcf2922eb42cc85a4ccc8a9dfce2d252.tar.bz2
Allow WindowGtks to be moved and sized when the mouse is over the caption or sizing border.
BUG=none TEST=none Review URL: http://codereview.chromium.org/118218 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@17608 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/views/frame/browser_view.cc17
-rw-r--r--views/window/window_gtk.cc109
-rw-r--r--views/window/window_gtk.h2
3 files changed, 119 insertions, 9 deletions
diff --git a/chrome/browser/views/frame/browser_view.cc b/chrome/browser/views/frame/browser_view.cc
index 9d41882..d122af1 100644
--- a/chrome/browser/views/frame/browser_view.cc
+++ b/chrome/browser/views/frame/browser_view.cc
@@ -57,17 +57,19 @@
#include "grit/theme_resources.h"
#include "grit/webkit_resources.h"
#include "views/controls/menu/menu.h"
+#if defined(OS_WIN)
+#include "views/controls/scrollbar/native_scroll_bar.h"
+#endif
#include "views/fill_layout.h"
#include "views/view.h"
#include "views/widget/root_view.h"
#include "views/window/dialog_delegate.h"
+#if !defined(OS_WIN)
+#include "views/window/hit_test.h"
+#endif
#include "views/window/non_client_view.h"
#include "views/window/window.h"
-#if defined(OS_WIN)
-#include "views/controls/scrollbar/native_scroll_bar.h"
-#endif
-
using base::TimeDelta;
// static
@@ -1177,7 +1179,6 @@ bool BrowserView::CanClose() const {
}
int BrowserView::NonClientHitTest(const gfx::Point& point) {
-#if defined(OS_WIN)
// Since the TabStrip only renders in some parts of the top of the window,
// the un-obscured area is considered to be part of the non-client caption
// area of the window. So we need to treat hit-tests in these regions as
@@ -1185,6 +1186,7 @@ int BrowserView::NonClientHitTest(const gfx::Point& point) {
if (!frame_->GetWindow()->IsMaximized() &&
!frame_->GetWindow()->IsFullscreen()) {
+#if defined(OS_WIN)
CRect client_rect;
::GetClientRect(frame_->GetWindow()->GetNativeWindow(), &client_rect);
gfx::Size resize_corner_size = ResizeCorner::GetSize();
@@ -1199,6 +1201,7 @@ int BrowserView::NonClientHitTest(const gfx::Point& point) {
return HTBOTTOMLEFT;
return HTBOTTOMRIGHT;
}
+#endif
}
// Determine if the TabStrip exists and is capable of being clicked on. We
@@ -1254,10 +1257,6 @@ int BrowserView::NonClientHitTest(const gfx::Point& point) {
// If the point is somewhere else, delegate to the default implementation.
return views::ClientView::NonClientHitTest(point);
-#else
- NOTIMPLEMENTED();
- return 0;
-#endif
}
gfx::Size BrowserView::GetMinimumSize() {
diff --git a/views/window/window_gtk.cc b/views/window/window_gtk.cc
index 51c726c..138fef9 100644
--- a/views/window/window_gtk.cc
+++ b/views/window/window_gtk.cc
@@ -7,10 +7,71 @@
#include "app/gfx/path.h"
#include "app/l10n_util.h"
#include "base/gfx/rect.h"
+#include "views/widget/root_view.h"
#include "views/window/custom_frame_view.h"
+#include "views/window/hit_test.h"
#include "views/window/non_client_view.h"
#include "views/window/window_delegate.h"
+namespace {
+
+// Converts a Windows-style hit test result code into a GDK window edge.
+GdkWindowEdge HitTestCodeToGDKWindowEdge(int hittest_code) {
+ switch (hittest_code) {
+ case HTBOTTOM:
+ return GDK_WINDOW_EDGE_SOUTH;
+ case HTBOTTOMLEFT:
+ return GDK_WINDOW_EDGE_SOUTH_WEST;
+ case HTBOTTOMRIGHT:
+ case HTGROWBOX:
+ return GDK_WINDOW_EDGE_SOUTH_EAST;
+ case HTLEFT:
+ return GDK_WINDOW_EDGE_WEST;
+ case HTRIGHT:
+ return GDK_WINDOW_EDGE_EAST;
+ case HTTOP:
+ return GDK_WINDOW_EDGE_NORTH;
+ case HTTOPLEFT:
+ return GDK_WINDOW_EDGE_NORTH_WEST;
+ case HTTOPRIGHT:
+ return GDK_WINDOW_EDGE_NORTH_EAST;
+ default:
+ NOTREACHED();
+ break;
+ }
+ // Default to something defaultish.
+ return HitTestCodeToGDKWindowEdge(HTGROWBOX);
+}
+
+// Converts a Windows-style hit test result code into a GDK cursor type.
+GdkCursorType HitTestCodeToGdkCursorType(int hittest_code) {
+ switch (hittest_code) {
+ case HTBOTTOM:
+ return GDK_BOTTOM_SIDE;
+ case HTBOTTOMLEFT:
+ return GDK_BOTTOM_LEFT_CORNER;
+ case HTBOTTOMRIGHT:
+ case HTGROWBOX:
+ return GDK_BOTTOM_RIGHT_CORNER;
+ case HTLEFT:
+ return GDK_LEFT_SIDE;
+ case HTRIGHT:
+ return GDK_RIGHT_SIDE;
+ case HTTOP:
+ return GDK_TOP_SIDE;
+ case HTTOPLEFT:
+ return GDK_TOP_LEFT_CORNER;
+ case HTTOPRIGHT:
+ return GDK_TOP_RIGHT_CORNER;
+ default:
+ break;
+ }
+ // Default to something defaultish.
+ return GDK_ARROW;
+}
+
+} // namespace
+
namespace views {
WindowGtk::~WindowGtk() {
@@ -188,6 +249,54 @@ void WindowGtk::FrameTypeChanged() {
////////////////////////////////////////////////////////////////////////////////
// WindowGtk, WidgetGtk overrides:
+gboolean WindowGtk::OnButtonPress(GtkWidget* widget, GdkEventButton* event) {
+ int hittest_code =
+ non_client_view_->NonClientHitTest(gfx::Point(event->x, event->y));
+ switch (hittest_code) {
+ case HTCAPTION: {
+ gfx::Point screen_point(event->x, event->y);
+ View::ConvertPointToScreen(GetRootView(), &screen_point);
+ gtk_window_begin_move_drag(GetNativeWindow(), event->button,
+ screen_point.x(), screen_point.y(),
+ event->time);
+ return TRUE;
+ }
+ case HTBOTTOM:
+ case HTBOTTOMLEFT:
+ case HTBOTTOMRIGHT:
+ case HTGROWBOX:
+ case HTLEFT:
+ case HTRIGHT:
+ case HTTOP:
+ case HTTOPLEFT:
+ case HTTOPRIGHT: {
+ gfx::Point screen_point(event->x, event->y);
+ View::ConvertPointToScreen(GetRootView(), &screen_point);
+ gtk_window_begin_resize_drag(GetNativeWindow(),
+ HitTestCodeToGDKWindowEdge(hittest_code),
+ event->button, screen_point.x(),
+ screen_point.y(), event->time);
+ return TRUE;
+ }
+ default:
+ // Everything else falls into standard client event handling...
+ break;
+ }
+ return WidgetGtk::OnButtonPress(widget, event);
+}
+
+gboolean WindowGtk::OnMotionNotify(GtkWidget* widget, GdkEventMotion* event) {
+ // Update the cursor for the screen edge.
+ int hittest_code =
+ non_client_view_->NonClientHitTest(gfx::Point(event->x, event->y));
+ GdkCursorType cursor_type = HitTestCodeToGdkCursorType(hittest_code);
+ GdkCursor* cursor = gdk_cursor_new(cursor_type);
+ gdk_window_set_cursor(widget->window, cursor);
+ gdk_cursor_destroy(cursor);
+
+ return WidgetGtk::OnMotionNotify(widget, event);
+}
+
void WindowGtk::OnSizeAllocate(GtkWidget* widget, GtkAllocation* allocation) {
WidgetGtk::OnSizeAllocate(widget, allocation);
diff --git a/views/window/window_gtk.h b/views/window/window_gtk.h
index 94cca05..5012718 100644
--- a/views/window/window_gtk.h
+++ b/views/window/window_gtk.h
@@ -62,6 +62,8 @@ class WindowGtk : public WidgetGtk, public Window {
virtual const Window* AsWindow() const { return this; }
// Overridden from WidgetGtk:
+ virtual gboolean OnButtonPress(GtkWidget* widget, GdkEventButton* event);
+ virtual gboolean OnMotionNotify(GtkWidget* widget, GdkEventMotion* event);
virtual void OnSizeAllocate(GtkWidget* widget, GtkAllocation* allocation);
protected: