views: Make resizable frameless window work.
authorCheng Zhao <zcbenz@gmail.com>
Mon, 7 Jul 2014 14:39:39 +0000 (22:39 +0800)
committerCheng Zhao <zcbenz@gmail.com>
Mon, 7 Jul 2014 14:40:26 +0000 (22:40 +0800)
atom/browser/native_window_views.cc
atom/browser/ui/views/linux_frame_view.cc
atom/browser/ui/views/linux_frame_view.h

index 37148e1..6cbd506 100644 (file)
@@ -14,6 +14,7 @@
 #include "content/public/browser/native_web_keyboard_event.h"
 #include "content/public/browser/web_contents_view.h"
 #include "native_mate/dictionary.h"
+#include "ui/base/hit_test.h"
 #include "ui/gfx/image/image.h"
 #include "ui/gfx/image/image_skia.h"
 #include "ui/views/background.h"
@@ -335,8 +336,18 @@ bool NativeWindowViews::ShouldDescendIntoChildForEventHandling(
     gfx::NativeView child,
     const gfx::Point& location) {
   // App window should claim mouse events that fall within the draggable region.
-  return !draggable_region_.get() ||
-         !draggable_region_->contains(location.x(), location.y());
+  if (draggable_region_.get() &&
+      draggable_region_->contains(location.x(), location.y()))
+    return false;
+
+  // And the events on border for dragging resizable frameless window.
+  if (!has_frame_ && CanResize()) {
+    LinuxFrameView* frame = static_cast<LinuxFrameView*>(
+        window_->non_client_view()->frame_view());
+    return frame->ResizingBorderHitTest(location) == HTNOWHERE;
+  }
+
+  return true;
 }
 
 views::ClientView* NativeWindowViews::CreateClientView(views::Widget* widget) {
index 3d31f5f..7832913 100644 (file)
@@ -84,7 +84,7 @@ LinuxFrameView::LinuxFrameView()
       restore_button_(NULL),
       close_button_(NULL),
       should_show_maximize_button_(false),
-      frame_background_(new views::FrameBackground()) {
+      frame_background_(new views::FrameBackground) {
 }
 
 LinuxFrameView::~LinuxFrameView() {
@@ -118,6 +118,12 @@ void LinuxFrameView::Init(NativeWindowViews* window, views::Widget* frame) {
   }
 }
 
+int LinuxFrameView::ResizingBorderHitTest(const gfx::Point& point) {
+  return GetHTComponentForFrame(point, FrameBorderThickness(),
+      FrameBorderThickness() + kClientEdgeThickness, kResizeAreaCornerSize,
+      kResizeAreaCornerSize, true);
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 // LinuxFrameView, NonClientFrameView implementation:
 
@@ -146,6 +152,13 @@ int LinuxFrameView::NonClientHitTest(const gfx::Point& point) {
   if (draggable_region && draggable_region->contains(point.x(), point.y()))
     return HTCAPTION;
 
+  // Support resizing frameless window by dragging the border.
+  if (!window_->has_frame() && frame_->widget_delegate()->CanResize()) {
+    int window_component = ResizingBorderHitTest(point);
+    if (window_component != HTNOWHERE)
+      return window_component;
+  }
+
   int frame_component = frame_->client_view()->NonClientHitTest(point);
 
   // See if we're in the sysmenu region.  (We check the ClientView first to be
index bb059aa..b1d8d70 100644 (file)
@@ -56,6 +56,9 @@ class LinuxFrameView : public views::NonClientFrameView,
   virtual void ButtonPressed(views::Button* sender,
                              const ui::Event& event) OVERRIDE;
 
+  // Returns whether the |point| is on frameless window's resizing border.
+  int ResizingBorderHitTest(const gfx::Point& point);
+
  private:
   // Returns the thickness of the border that makes up the window frame edges.
   // This does not include any client edge.