summaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
Diffstat (limited to 'ui')
-rw-r--r--ui/aura/client/window_move_client.h9
-rw-r--r--ui/aura/root_window.cc11
-rw-r--r--ui/aura/root_window.h4
-rw-r--r--ui/aura/root_window_host.h3
-rw-r--r--ui/aura/root_window_host_delegate.h2
-rw-r--r--ui/aura/root_window_host_linux.cc35
-rw-r--r--ui/aura/root_window_host_linux.h4
-rw-r--r--ui/aura/root_window_host_win.cc4
-rw-r--r--ui/aura/root_window_host_win.h1
-rw-r--r--ui/aura/root_window_observer.h5
-rw-r--r--ui/aura/window_observer.h1
-rw-r--r--ui/base/cocoa/events_mac.mm7
-rw-r--r--ui/base/event.cc12
-rw-r--r--ui/base/event.h20
-rw-r--r--ui/base/events.h4
-rw-r--r--ui/base/win/events_win.cc7
-rw-r--r--ui/base/x/events_x.cc29
-rw-r--r--ui/views/views.gyp2
-rw-r--r--ui/views/widget/desktop_native_widget_helper_aura.cc41
-rw-r--r--ui/views/widget/desktop_native_widget_helper_aura.h16
-rw-r--r--ui/views/widget/native_widget_aura.cc11
-rw-r--r--ui/views/widget/native_widget_aura.h3
-rw-r--r--ui/views/widget/native_widget_helper_aura.h3
-rw-r--r--ui/views/widget/native_widget_private.h2
-rw-r--r--ui/views/widget/native_widget_win.cc3
-rw-r--r--ui/views/widget/native_widget_win.h3
-rw-r--r--ui/views/widget/widget.cc4
-rw-r--r--ui/views/widget/widget.h6
-rw-r--r--ui/views/widget/x11_desktop_window_move_client.cc123
-rw-r--r--ui/views/widget/x11_desktop_window_move_client.h55
-rw-r--r--ui/views/widget/x11_window_event_filter.cc21
31 files changed, 391 insertions, 60 deletions
diff --git a/ui/aura/client/window_move_client.h b/ui/aura/client/window_move_client.h
index b6f32a0..048e572 100644
--- a/ui/aura/client/window_move_client.h
+++ b/ui/aura/client/window_move_client.h
@@ -7,6 +7,10 @@
#include "ui/aura/aura_export.h"
+namespace gfx {
+class Point;
+}
+
namespace aura {
class Window;
namespace client {
@@ -15,8 +19,9 @@ namespace client {
// window moving.
class AURA_EXPORT WindowMoveClient {
public:
- // Starts a nested message loop for moving the window.
- virtual void RunMoveLoop(Window* window) = 0;
+ // Starts a nested message loop for moving the window. |drag_offset| is the
+ // offset from the window origin to the cursor when the drag was started.
+ virtual void RunMoveLoop(Window* window, const gfx::Point& drag_offset) = 0;
// Ends a previously started move loop.
virtual void EndMoveLoop() = 0;
diff --git a/ui/aura/root_window.cc b/ui/aura/root_window.cc
index f53cfb4..e12e36c 100644
--- a/ui/aura/root_window.cc
+++ b/ui/aura/root_window.cc
@@ -180,6 +180,10 @@ void RootWindow::ShowRootWindow() {
host_->Show();
}
+void RootWindow::HideRootWindow() {
+ host_->Hide();
+}
+
RootWindowHostDelegate* RootWindow::AsRootWindowHostDelegate() {
return this;
}
@@ -528,6 +532,7 @@ void RootWindow::UpdateCapture(Window* old_capture,
// Send a capture changed event with bogus location data.
ui::MouseEvent event(ui::ET_MOUSE_CAPTURE_CHANGED, gfx::Point(),
gfx::Point(), 0);
+
ProcessMouseEvent(old_capture, &event);
old_capture->delegate()->OnCaptureLost();
@@ -921,6 +926,11 @@ void RootWindow::OnHostPaint() {
Draw();
}
+void RootWindow::OnHostMoved(const gfx::Point& origin) {
+ FOR_EACH_OBSERVER(RootWindowObserver, observers_,
+ OnRootWindowMoved(this, origin));
+}
+
void RootWindow::OnHostResized(const gfx::Size& size) {
DispatchHeldMouseMove();
// The compositor should have the same size as the native root window host.
@@ -1039,6 +1049,7 @@ void RootWindow::SynthesizeMouseMoveEvent() {
orig_mouse_location,
orig_mouse_location,
ui::EF_IS_SYNTHESIZED);
+ event.set_system_location(Env::GetInstance()->last_mouse_location());
OnHostMouseEvent(&event);
#endif
}
diff --git a/ui/aura/root_window.h b/ui/aura/root_window.h
index 9236269..9f4b9f1 100644
--- a/ui/aura/root_window.h
+++ b/ui/aura/root_window.h
@@ -109,6 +109,9 @@ class AURA_EXPORT RootWindow : public ui::CompositorDelegate,
// Shows the root window host.
void ShowRootWindow();
+ // Hides the root window host.
+ void HideRootWindow();
+
RootWindowHostDelegate* AsRootWindowHostDelegate();
// Sets the size of the root window.
@@ -304,6 +307,7 @@ class AURA_EXPORT RootWindow : public ui::CompositorDelegate,
virtual bool OnHostTouchEvent(ui::TouchEvent* event) OVERRIDE;
virtual void OnHostLostCapture() OVERRIDE;
virtual void OnHostPaint() OVERRIDE;
+ virtual void OnHostMoved(const gfx::Point& origin) OVERRIDE;
virtual void OnHostResized(const gfx::Size& size) OVERRIDE;
virtual float GetDeviceScaleFactor() OVERRIDE;
virtual RootWindow* AsRootWindow() OVERRIDE;
diff --git a/ui/aura/root_window_host.h b/ui/aura/root_window_host.h
index 65a3f19..74502bf 100644
--- a/ui/aura/root_window_host.h
+++ b/ui/aura/root_window_host.h
@@ -50,6 +50,9 @@ class RootWindowHost {
// Shows the RootWindowHost.
virtual void Show() = 0;
+ // Hides the RootWindowHost.
+ virtual void Hide() = 0;
+
// Toggles the host's full screen state.
virtual void ToggleFullScreen() = 0;
diff --git a/ui/aura/root_window_host_delegate.h b/ui/aura/root_window_host_delegate.h
index 6bc5852..13c4f71 100644
--- a/ui/aura/root_window_host_delegate.h
+++ b/ui/aura/root_window_host_delegate.h
@@ -6,6 +6,7 @@
#define UI_AURA_ROOT_WINDOW_HOST_DELEGATE_H_
namespace gfx {
+class Point;
class Size;
}
@@ -33,6 +34,7 @@ class AURA_EXPORT RootWindowHostDelegate {
virtual void OnHostPaint() = 0;
+ virtual void OnHostMoved(const gfx::Point& origin) = 0;
virtual void OnHostResized(const gfx::Size& size) = 0;
virtual float GetDeviceScaleFactor() = 0;
diff --git a/ui/aura/root_window_host_linux.cc b/ui/aura/root_window_host_linux.cc
index 4dd801e..c7d4281 100644
--- a/ui/aura/root_window_host_linux.cc
+++ b/ui/aura/root_window_host_linux.cc
@@ -473,6 +473,7 @@ RootWindowHostLinux::RootWindowHostLinux(RootWindowHostDelegate* delegate,
xwindow_(0),
x_root_window_(DefaultRootWindow(xdisplay_)),
current_cursor_(ui::kCursorNull),
+ window_mapped_(false),
cursor_shown_(true),
bounds_(bounds),
focus_when_shown_(false),
@@ -619,6 +620,7 @@ bool RootWindowHostLinux::Dispatch(const base::NativeEvent& event) {
gfx::Rect bounds(xev->xconfigure.x, xev->xconfigure.y,
xev->xconfigure.width, xev->xconfigure.height);
bool size_changed = bounds_.size() != bounds.size();
+ bool origin_changed = bounds_.origin() != bounds.origin();
bounds_ = bounds;
// Update barrier and mouse location when the root window has
// moved/resized.
@@ -630,6 +632,8 @@ bool RootWindowHostLinux::Dispatch(const base::NativeEvent& event) {
}
if (size_changed)
delegate_->OnHostResized(bounds.size());
+ if (origin_changed)
+ delegate_->OnHostMoved(bounds_.origin());
break;
}
case GenericEvent: {
@@ -781,15 +785,30 @@ void RootWindowHostLinux::Show() {
// The device scale factor is now accessible, so load cursors now.
image_cursors_->Reload(delegate_->GetDeviceScaleFactor());
- // Before we map the window, set size hints. Otherwise, some window managers
- // will ignore toplevel XMoveWindow commands.
- XSizeHints size_hints;
- size_hints.flags = PPosition;
- size_hints.x = bounds_.x();
- size_hints.y = bounds_.y();
- XSetWMNormalHints(xdisplay_, xwindow_, &size_hints);
+ if (!window_mapped_) {
+ // Before we map the window, set size hints. Otherwise, some window managers
+ // will ignore toplevel XMoveWindow commands.
+ XSizeHints size_hints;
+ size_hints.flags = PPosition;
+ size_hints.x = bounds_.x();
+ size_hints.y = bounds_.y();
+ XSetWMNormalHints(xdisplay_, xwindow_, &size_hints);
+
+ XMapWindow(xdisplay_, xwindow_);
+
+ // We now block until our window is mapped. Some X11 APIs will crash and
+ // burn if passed |xwindow_| before the window is mapped, and XMapWindow is
+ // asynchronous.
+ base::MessagePumpAuraX11::Current()->BlockUntilWindowMapped(xwindow_);
+ window_mapped_ = true;
+ }
+}
- XMapWindow(xdisplay_, xwindow_);
+void RootWindowHostLinux::Hide() {
+ if (window_mapped_) {
+ XWithdrawWindow(xdisplay_, xwindow_, 0);
+ window_mapped_ = false;
+ }
}
void RootWindowHostLinux::ToggleFullScreen() {
diff --git a/ui/aura/root_window_host_linux.h b/ui/aura/root_window_host_linux.h
index 94b6781..8e91c4d 100644
--- a/ui/aura/root_window_host_linux.h
+++ b/ui/aura/root_window_host_linux.h
@@ -37,6 +37,7 @@ class RootWindowHostLinux : public RootWindowHost,
virtual RootWindow* GetRootWindow() OVERRIDE;
virtual gfx::AcceleratedWidget GetAcceleratedWidget() OVERRIDE;
virtual void Show() OVERRIDE;
+ virtual void Hide() OVERRIDE;
virtual void ToggleFullScreen() OVERRIDE;
virtual gfx::Rect GetBounds() const OVERRIDE;
virtual void SetBounds(const gfx::Rect& bounds) OVERRIDE;
@@ -77,6 +78,9 @@ class RootWindowHostLinux : public RootWindowHost,
// Current Aura cursor.
gfx::NativeCursor current_cursor_;
+ // Is the window mapped to the screen?
+ bool window_mapped_;
+
// Is the cursor currently shown?
bool cursor_shown_;
diff --git a/ui/aura/root_window_host_win.cc b/ui/aura/root_window_host_win.cc
index fa336a3..db7209c 100644
--- a/ui/aura/root_window_host_win.cc
+++ b/ui/aura/root_window_host_win.cc
@@ -153,6 +153,10 @@ void RootWindowHostWin::Show() {
ShowWindow(hwnd(), SW_SHOWNORMAL);
}
+void RootWindowHostWin::Hide() {
+ NOTIMPLEMENTED();
+}
+
void RootWindowHostWin::ToggleFullScreen() {
gfx::Rect target_rect;
if (!fullscreen_) {
diff --git a/ui/aura/root_window_host_win.h b/ui/aura/root_window_host_win.h
index dcd2556..fdc5d9b 100644
--- a/ui/aura/root_window_host_win.h
+++ b/ui/aura/root_window_host_win.h
@@ -25,6 +25,7 @@ class RootWindowHostWin : public RootWindowHost, public ui::WindowImpl {
virtual RootWindow* GetRootWindow() OVERRIDE;
virtual gfx::AcceleratedWidget GetAcceleratedWidget() OVERRIDE;
virtual void Show() OVERRIDE;
+ virtual void Hide() OVERRIDE;
virtual void ToggleFullScreen() OVERRIDE;
virtual gfx::Rect GetBounds() const OVERRIDE;
virtual void SetBounds(const gfx::Rect& bounds) OVERRIDE;
diff --git a/ui/aura/root_window_observer.h b/ui/aura/root_window_observer.h
index 31bd37f..81dcad9 100644
--- a/ui/aura/root_window_observer.h
+++ b/ui/aura/root_window_observer.h
@@ -8,6 +8,7 @@
#include "ui/aura/aura_export.h"
namespace gfx {
+class Point;
class Size;
}
@@ -21,6 +22,10 @@ class AURA_EXPORT RootWindowObserver {
virtual void OnRootWindowResized(const RootWindow* root,
const gfx::Size& old_size) {}
+ // Invoked after the RootWindow has been moved on screen.
+ virtual void OnRootWindowMoved(const RootWindow* root,
+ const gfx::Point& new_origin) {}
+
// Invoked when the native windowing system sends us a request to close our
// window.
virtual void OnRootWindowHostCloseRequested(const RootWindow* root) {}
diff --git a/ui/aura/window_observer.h b/ui/aura/window_observer.h
index fa5c4f8..376564a 100644
--- a/ui/aura/window_observer.h
+++ b/ui/aura/window_observer.h
@@ -5,6 +5,7 @@
#ifndef UI_AURA_WINDOW_OBSERVER_H_
#define UI_AURA_WINDOW_OBSERVER_H_
+#include "base/basictypes.h"
#include "ui/aura/aura_export.h"
namespace gfx {
diff --git a/ui/base/cocoa/events_mac.mm b/ui/base/cocoa/events_mac.mm
index 437b465..4471882 100644
--- a/ui/base/cocoa/events_mac.mm
+++ b/ui/base/cocoa/events_mac.mm
@@ -128,6 +128,13 @@ gfx::Point EventLocationFromNative(const base::NativeEvent& native_event) {
return gfx::Point(NSPointToCGPoint(location));
}
+gfx::Point EventSystemLocationFromNative(
+ const base::NativeEvent& native_event) {
+ // TODO(port): Needs to always return screen position here. Returning normal
+ // origin for now since that's obviously wrong.
+ return gfx::Point(0, 0);
+}
+
KeyboardCode KeyboardCodeFromNative(const base::NativeEvent& native_event) {
return ui::KeyboardCodeFromNSEvent(native_event);
}
diff --git a/ui/base/event.cc b/ui/base/event.cc
index f8ab8b6..0294ddd 100644
--- a/ui/base/event.cc
+++ b/ui/base/event.cc
@@ -100,7 +100,9 @@ LocatedEvent::LocatedEvent(const base::NativeEvent& native_event)
EventTypeFromNative(native_event),
EventFlagsFromNative(native_event)),
location_(EventLocationFromNative(native_event)),
- root_location_(location_) {
+ root_location_(location_),
+ valid_system_location_(true),
+ system_location_(ui::EventSystemLocationFromNative(native_event)) {
}
LocatedEvent::LocatedEvent(EventType type,
@@ -109,13 +111,17 @@ LocatedEvent::LocatedEvent(EventType type,
int flags)
: Event(type, flags),
location_(location),
- root_location_(root_location) {
+ root_location_(root_location),
+ valid_system_location_(false),
+ system_location_(0, 0) {
}
LocatedEvent::LocatedEvent(const LocatedEvent& model)
: Event(model),
location_(model.location_),
- root_location_(model.root_location_) {
+ root_location_(model.root_location_),
+ valid_system_location_(model.valid_system_location_),
+ system_location_(model.system_location_) {
}
void LocatedEvent::UpdateForRootTransform(const Transform& root_transform) {
diff --git a/ui/base/event.h b/ui/base/event.h
index 43fb253..d7b2c2c 100644
--- a/ui/base/event.h
+++ b/ui/base/event.h
@@ -136,6 +136,13 @@ class UI_EXPORT LocatedEvent : public Event {
gfx::Point location() const { return location_; }
gfx::Point root_location() const { return root_location_; }
+ bool valid_system_location() const { return valid_system_location_; }
+ void set_system_location(const gfx::Point& loc) {
+ valid_system_location_ = true;
+ system_location_ = loc;
+ }
+ const gfx::Point& system_location() const { return system_location_; }
+
// Applies |root_transform| to the event.
// This is applied to both |location_| and |root_location_|.
virtual void UpdateForRootTransform(const Transform& root_transform);
@@ -150,7 +157,11 @@ class UI_EXPORT LocatedEvent : public Event {
LocatedEvent(const LocatedEvent& model, T* source, T* target)
: Event(model),
location_(model.location_),
- root_location_(model.root_location_) {
+ root_location_(model.root_location_),
+ valid_system_location_(model.valid_system_location_),
+ system_location_(model.system_location_) {
+ // TODO(erg): May need to create system_location_ by converting location to
+ // system coordinates here.
if (target && target != source)
T::ConvertPointToTarget(source, target, &location_);
}
@@ -166,7 +177,14 @@ class UI_EXPORT LocatedEvent : public Event {
gfx::Point location_;
+ // |location_| multiplied by an optional transformation matrix for
+ // rotations, animations and skews.
gfx::Point root_location_;
+
+ // |location_| in underlying system screen coordinates. This can be invalid
+ // |during synthesized events if a location isn't explicitly set.
+ bool valid_system_location_;
+ gfx::Point system_location_;
};
class UI_EXPORT MouseEvent : public LocatedEvent {
diff --git a/ui/base/events.h b/ui/base/events.h
index 9c6a36d..69d04f8 100644
--- a/ui/base/events.h
+++ b/ui/base/events.h
@@ -141,6 +141,10 @@ UI_EXPORT base::TimeDelta EventTimeFromNative(
UI_EXPORT gfx::Point EventLocationFromNative(
const base::NativeEvent& native_event);
+// Gets the location in native system coordinate space.
+UI_EXPORT gfx::Point EventSystemLocationFromNative(
+ const base::NativeEvent& native_event);
+
#if defined(USE_X11)
// Returns the 'real' button for an event. The button reported in slave events
// does not take into account any remapping (e.g. using xmodmap), while the
diff --git a/ui/base/win/events_win.cc b/ui/base/win/events_win.cc
index 984e7ca..5cf937c 100644
--- a/ui/base/win/events_win.cc
+++ b/ui/base/win/events_win.cc
@@ -215,6 +215,13 @@ gfx::Point EventLocationFromNative(const base::NativeEvent& native_event) {
return gfx::Point(native_point);
}
+gfx::Point EventSystemLocationFromNative(
+ const base::NativeEvent& native_event) {
+ // TODO(ben): Needs to always return screen position here. Returning normal
+ // origin for now since that's obviously wrong.
+ return gfx::Point(0, 0);
+}
+
KeyboardCode KeyboardCodeFromNative(const base::NativeEvent& native_event) {
return KeyboardCodeForWindowsKeyCode(native_event.wParam);
}
diff --git a/ui/base/x/events_x.cc b/ui/base/x/events_x.cc
index 1b8816a..8c2dff2 100644
--- a/ui/base/x/events_x.cc
+++ b/ui/base/x/events_x.cc
@@ -684,12 +684,13 @@ EventType EventTypeFromNative(const base::NativeEvent& native_event) {
bool is_cancel;
if (GetFlingData(native_event, &vx, &vy, &is_cancel)) {
return is_cancel ? ET_SCROLL_FLING_CANCEL : ET_SCROLL_FLING_START;
- } else if (GetScrollOffsets(native_event, NULL, NULL))
+ } else if (GetScrollOffsets(native_event, NULL, NULL)) {
return ET_SCROLL;
- else if (GetButtonMaskForX2Event(xievent)) {
+ } else if (GetButtonMaskForX2Event(xievent)) {
return ET_MOUSE_DRAGGED;
- } else
+ } else {
return ET_MOUSE_MOVED;
+ }
}
}
}
@@ -830,6 +831,28 @@ gfx::Point EventLocationFromNative(const base::NativeEvent& native_event) {
return gfx::Point();
}
+gfx::Point EventSystemLocationFromNative(
+ const base::NativeEvent& native_event) {
+ switch (native_event->type) {
+ case ButtonPress:
+ case ButtonRelease: {
+ return gfx::Point(native_event->xbutton.x_root,
+ native_event->xbutton.y_root);
+ }
+ case MotionNotify: {
+ return gfx::Point(native_event->xmotion.x_root,
+ native_event->xmotion.y_root);
+ }
+ case GenericEvent: {
+ XIDeviceEvent* xievent =
+ static_cast<XIDeviceEvent*>(native_event->xcookie.data);
+ return gfx::Point(xievent->root_x, xievent->root_y);
+ }
+ }
+
+ return gfx::Point();
+}
+
int EventButtonFromNative(const base::NativeEvent& native_event) {
CHECK_EQ(GenericEvent, native_event->type);
XIDeviceEvent* xievent =
diff --git a/ui/views/views.gyp b/ui/views/views.gyp
index 9e385fc..acd8338 100644
--- a/ui/views/views.gyp
+++ b/ui/views/views.gyp
@@ -353,6 +353,8 @@
'widget/widget_observer.h',
'widget/x11_desktop_handler.cc',
'widget/x11_desktop_handler.h',
+ 'widget/x11_desktop_window_move_client.cc',
+ 'widget/x11_desktop_window_move_client.h',
'widget/x11_window_event_filter.cc',
'widget/x11_window_event_filter.h',
'window/client_view.cc',
diff --git a/ui/views/widget/desktop_native_widget_helper_aura.cc b/ui/views/widget/desktop_native_widget_helper_aura.cc
index b2618f8..598b366 100644
--- a/ui/views/widget/desktop_native_widget_helper_aura.cc
+++ b/ui/views/widget/desktop_native_widget_helper_aura.cc
@@ -22,6 +22,7 @@
#include "ui/views/widget/widget_message_filter.h"
#elif defined(USE_X11)
#include "ui/views/widget/x11_desktop_handler.h"
+#include "ui/views/widget/x11_desktop_window_move_client.h"
#include "ui/views/widget/x11_window_event_filter.h"
#endif
@@ -91,13 +92,18 @@ class DesktopScreenPositionClient
DesktopNativeWidgetHelperAura::DesktopNativeWidgetHelperAura(
NativeWidgetAura* widget)
: widget_(widget),
+ window_(NULL),
root_window_event_filter_(NULL),
is_embedded_window_(false) {
}
DesktopNativeWidgetHelperAura::~DesktopNativeWidgetHelperAura() {
+ if (window_)
+ window_->RemoveObserver(this);
+
if (root_window_event_filter_) {
#if defined(USE_X11)
+ root_window_event_filter_->RemoveFilter(x11_window_move_client_.get());
root_window_event_filter_->RemoveFilter(x11_window_event_filter_.get());
#endif
@@ -178,9 +184,19 @@ void DesktopNativeWidgetHelperAura::PreInitialize(
root_window_->AddRootWindowObserver(this);
+ window_ = window;
+ window_->AddObserver(this);
+
aura::client::SetActivationClient(root_window_.get(), activation_client);
aura::client::SetDispatcherClient(root_window_.get(),
new aura::DesktopDispatcherClient);
+#if defined(USE_X11)
+ // TODO(ben): A window implementation of this will need to be written.
+ x11_window_move_client_.reset(new X11DesktopWindowMoveClient);
+ root_window_event_filter_->AddFilter(x11_window_move_client_.get());
+ aura::client::SetWindowMoveClient(root_window_.get(),
+ x11_window_move_client_.get());
+#endif
position_client_.reset(new DesktopScreenPositionClient());
aura::client::SetScreenPositionClient(root_window_.get(),
@@ -197,11 +213,6 @@ void DesktopNativeWidgetHelperAura::PostInitialize() {
#endif
}
-void DesktopNativeWidgetHelperAura::ShowRootWindow() {
- if (root_window_.get())
- root_window_->ShowRootWindow();
-}
-
aura::RootWindow* DesktopNativeWidgetHelperAura::GetRootWindow() {
return root_window_.get();
}
@@ -232,6 +243,20 @@ gfx::Rect DesktopNativeWidgetHelperAura::ModifyAndSetBounds(
}
////////////////////////////////////////////////////////////////////////////////
+// DesktopNativeWidgetHelperAura, aura::WindowObserver implementation:
+void DesktopNativeWidgetHelperAura::OnWindowVisibilityChanged(
+ aura::Window* window,
+ bool visible) {
+ DCHECK_EQ(window, window_);
+
+ // Since we're trying to hide the main window, hide the OS level root as well.
+ if (visible)
+ root_window_->ShowRootWindow();
+ else
+ root_window_->HideRootWindow();
+}
+
+////////////////////////////////////////////////////////////////////////////////
// DesktopNativeWidgetHelperAura, aura::RootWindowObserver implementation:
void DesktopNativeWidgetHelperAura::OnRootWindowResized(
@@ -248,4 +273,10 @@ void DesktopNativeWidgetHelperAura::OnRootWindowHostCloseRequested(
widget_->GetWidget()->Close();
}
+void DesktopNativeWidgetHelperAura::OnRootWindowMoved(
+ const aura::RootWindow* root,
+ const gfx::Point& new_origin) {
+ widget_->GetWidget()->OnNativeWidgetMove();
+}
+
} // namespace views
diff --git a/ui/views/widget/desktop_native_widget_helper_aura.h b/ui/views/widget/desktop_native_widget_helper_aura.h
index 43e2232..e4130de 100644
--- a/ui/views/widget/desktop_native_widget_helper_aura.h
+++ b/ui/views/widget/desktop_native_widget_helper_aura.h
@@ -6,6 +6,7 @@
#define UI_VIEWS_WIDGET_DESKTOP_NATIVE_WIDGET_HELPER_AURA_H_
#include "ui/aura/root_window_observer.h"
+#include "ui/aura/window_observer.h"
#include "ui/gfx/rect.h"
#include "ui/views/views_export.h"
#include "ui/views/widget/native_widget_helper_aura.h"
@@ -14,6 +15,7 @@
namespace aura {
class RootWindow;
class DesktopCursorClient;
+class DesktopWindowMoveClient;
namespace client {
class ScreenPositionClient;
}
@@ -34,6 +36,7 @@ namespace views {
class NativeWidgetAura;
class WidgetMessageFilter;
#if defined(USE_X11)
+class X11DesktopWindowMoveClient;
class X11WindowEventFilter;
#endif
@@ -41,6 +44,7 @@ class X11WindowEventFilter;
// NativeWidgetAuras to work in a traditional desktop environment.
class VIEWS_EXPORT DesktopNativeWidgetHelperAura
: public NativeWidgetHelperAura,
+ public aura::WindowObserver,
public aura::RootWindowObserver {
public:
explicit DesktopNativeWidgetHelperAura(NativeWidgetAura* widget);
@@ -55,13 +59,16 @@ class VIEWS_EXPORT DesktopNativeWidgetHelperAura
virtual void PreInitialize(aura::Window* window,
const Widget::InitParams& params) OVERRIDE;
virtual void PostInitialize() OVERRIDE;
- virtual void ShowRootWindow() OVERRIDE;
virtual aura::RootWindow* GetRootWindow() OVERRIDE;
virtual gfx::Rect ModifyAndSetBounds(const gfx::Rect& bounds) OVERRIDE;
// Overridden from aura::RootWindowObserver:
virtual void OnRootWindowResized(const aura::RootWindow* root,
const gfx::Size& old_size) OVERRIDE;
+ virtual void OnRootWindowMoved(const aura::RootWindow* root,
+ const gfx::Point& new_origin) OVERRIDE;
+ virtual void OnWindowVisibilityChanged(aura::Window* window,
+ bool visible) OVERRIDE;
virtual void OnRootWindowHostCloseRequested(
const aura::RootWindow* root) OVERRIDE;
@@ -69,6 +76,10 @@ class VIEWS_EXPORT DesktopNativeWidgetHelperAura
// A weak pointer back to our owning widget.
NativeWidgetAura* widget_;
+ // The window from the NativeWidgetAura. We observe events on it, and proxy
+ // visibility stuff to it.
+ aura::Window* window_;
+
// Optionally, a RootWindow that we attach ourselves to.
scoped_ptr<aura::RootWindow> root_window_;
@@ -94,10 +105,13 @@ class VIEWS_EXPORT DesktopNativeWidgetHelperAura
// A simple cursor client which just forwards events to the RootWindow.
scoped_ptr<aura::DesktopCursorClient> cursor_client_;
+ // Handles spinning up the nested run loop for tab dragging.
+
#if defined(OS_WIN)
scoped_ptr<ui::HWNDMessageFilter> hwnd_message_filter_;
#elif defined(USE_X11)
scoped_ptr<X11WindowEventFilter> x11_window_event_filter_;
+ scoped_ptr<X11DesktopWindowMoveClient> x11_window_move_client_;
#endif
DISALLOW_COPY_AND_ASSIGN(DesktopNativeWidgetHelperAura);
diff --git a/ui/views/widget/native_widget_aura.cc b/ui/views/widget/native_widget_aura.cc
index 8dea0d2..fa5ee73 100644
--- a/ui/views/widget/native_widget_aura.cc
+++ b/ui/views/widget/native_widget_aura.cc
@@ -233,11 +233,8 @@ void NativeWidgetAura::InitNativeWidget(const Widget::InitParams& params) {
aura::client::SetActivationDelegate(window_, this);
- if (desktop_helper_.get()) {
+ if (desktop_helper_.get())
desktop_helper_->PostInitialize();
- // TODO(erg): Move this somewhere else?
- desktop_helper_->ShowRootWindow();
- }
}
NonClientFrameView* NativeWidgetAura::CreateNonClientFrameView() {
@@ -664,11 +661,13 @@ void NativeWidgetAura::SetInactiveRenderingDisabled(bool value) {
active_window_observer_.reset(new ActiveWindowObserver(this));
}
-Widget::MoveLoopResult NativeWidgetAura::RunMoveLoop() {
+Widget::MoveLoopResult NativeWidgetAura::RunMoveLoop(
+ const gfx::Point& drag_offset) {
if (window_->parent() &&
aura::client::GetWindowMoveClient(window_->parent())) {
SetCapture();
- aura::client::GetWindowMoveClient(window_->parent())->RunMoveLoop(window_);
+ aura::client::GetWindowMoveClient(window_->parent())->RunMoveLoop(
+ window_, drag_offset);
return Widget::MOVE_LOOP_SUCCESSFUL;
}
return Widget::MOVE_LOOP_CANCELED;
diff --git a/ui/views/widget/native_widget_aura.h b/ui/views/widget/native_widget_aura.h
index 129334a..ea34d7e 100644
--- a/ui/views/widget/native_widget_aura.h
+++ b/ui/views/widget/native_widget_aura.h
@@ -119,7 +119,8 @@ class VIEWS_EXPORT NativeWidgetAura : public internal::NativeWidgetPrivate,
virtual void FocusNativeView(gfx::NativeView native_view) OVERRIDE;
virtual gfx::Rect GetWorkAreaBoundsInScreen() const OVERRIDE;
virtual void SetInactiveRenderingDisabled(bool value) OVERRIDE;
- virtual Widget::MoveLoopResult RunMoveLoop() OVERRIDE;
+ virtual Widget::MoveLoopResult RunMoveLoop(
+ const gfx::Point& drag_offset) OVERRIDE;
virtual void EndMoveLoop() OVERRIDE;
virtual void SetVisibilityChangedAnimationsEnabled(bool value) OVERRIDE;
diff --git a/ui/views/widget/native_widget_helper_aura.h b/ui/views/widget/native_widget_helper_aura.h
index 4c21b34..54da578 100644
--- a/ui/views/widget/native_widget_helper_aura.h
+++ b/ui/views/widget/native_widget_helper_aura.h
@@ -25,9 +25,6 @@ class VIEWS_EXPORT NativeWidgetHelperAura {
// aura::Window has been initialized.
virtual void PostInitialize() = 0;
- // Passes through a message to show the RootWindow, if it exists.
- virtual void ShowRootWindow() = 0;
-
// If we own a RootWindow, return it. Otherwise NULL.
virtual aura::RootWindow* GetRootWindow() = 0;
diff --git a/ui/views/widget/native_widget_private.h b/ui/views/widget/native_widget_private.h
index 725f561..38265d2 100644
--- a/ui/views/widget/native_widget_private.h
+++ b/ui/views/widget/native_widget_private.h
@@ -210,7 +210,7 @@ class VIEWS_EXPORT NativeWidgetPrivate : public NativeWidget,
virtual void FocusNativeView(gfx::NativeView native_view) = 0;
virtual gfx::Rect GetWorkAreaBoundsInScreen() const = 0;
virtual void SetInactiveRenderingDisabled(bool value) = 0;
- virtual Widget::MoveLoopResult RunMoveLoop() = 0;
+ virtual Widget::MoveLoopResult RunMoveLoop(const gfx::Point& drag_offset) = 0;
virtual void EndMoveLoop() = 0;
virtual void SetVisibilityChangedAnimationsEnabled(bool value) = 0;
diff --git a/ui/views/widget/native_widget_win.cc b/ui/views/widget/native_widget_win.cc
index 9cdd593..3fef80f 100644
--- a/ui/views/widget/native_widget_win.cc
+++ b/ui/views/widget/native_widget_win.cc
@@ -1177,7 +1177,8 @@ gfx::Rect NativeWidgetWin::GetWorkAreaBoundsInScreen() const {
void NativeWidgetWin::SetInactiveRenderingDisabled(bool value) {
}
-Widget::MoveLoopResult NativeWidgetWin::RunMoveLoop() {
+Widget::MoveLoopResult NativeWidgetWin::RunMoveLoop(
+ const gfx::Point& drag_offset) {
ReleaseCapture();
MoveLoopMouseWatcher watcher(this);
SendMessage(hwnd(), WM_SYSCOMMAND, SC_MOVE | 0x0002, GetMessagePos());
diff --git a/ui/views/widget/native_widget_win.h b/ui/views/widget/native_widget_win.h
index c17d523..260da92 100644
--- a/ui/views/widget/native_widget_win.h
+++ b/ui/views/widget/native_widget_win.h
@@ -261,7 +261,8 @@ class VIEWS_EXPORT NativeWidgetWin : public ui::WindowImpl,
virtual void FocusNativeView(gfx::NativeView native_view) OVERRIDE;
virtual gfx::Rect GetWorkAreaBoundsInScreen() const OVERRIDE;
virtual void SetInactiveRenderingDisabled(bool value) OVERRIDE;
- virtual Widget::MoveLoopResult RunMoveLoop() OVERRIDE;
+ virtual Widget::MoveLoopResult RunMoveLoop(
+ const gfx::Point& drag_offset) OVERRIDE;
virtual void EndMoveLoop() OVERRIDE;
virtual void SetVisibilityChangedAnimationsEnabled(bool value) OVERRIDE;
diff --git a/ui/views/widget/widget.cc b/ui/views/widget/widget.cc
index 5c57283..2b9d3d1 100644
--- a/ui/views/widget/widget.cc
+++ b/ui/views/widget/widget.cc
@@ -457,8 +457,8 @@ void Widget::SetVisibilityChangedAnimationsEnabled(bool value) {
native_widget_->SetVisibilityChangedAnimationsEnabled(value);
}
-Widget::MoveLoopResult Widget::RunMoveLoop() {
- return native_widget_->RunMoveLoop();
+Widget::MoveLoopResult Widget::RunMoveLoop(const gfx::Point& drag_offset) {
+ return native_widget_->RunMoveLoop(drag_offset);
}
void Widget::EndMoveLoop() {
diff --git a/ui/views/widget/widget.h b/ui/views/widget/widget.h
index 9e5918b..ee6e6e6 100644
--- a/ui/views/widget/widget.h
+++ b/ui/views/widget/widget.h
@@ -319,8 +319,10 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate,
// Starts a nested message loop that moves the window. This can be used to
// start a window move operation from a mouse moved event. This returns when
- // the move completes.
- MoveLoopResult RunMoveLoop();
+ // the move completes. |drag_offset| is the offset from the top left corner
+ // of the window to the point where the cursor is dragging, and is used to
+ // offset the bounds of the window from the cursor.
+ MoveLoopResult RunMoveLoop(const gfx::Point& drag_offset);
// Stops a previously started move loop. This is not immediate.
void EndMoveLoop();
diff --git a/ui/views/widget/x11_desktop_window_move_client.cc b/ui/views/widget/x11_desktop_window_move_client.cc
new file mode 100644
index 0000000..7d5e535
--- /dev/null
+++ b/ui/views/widget/x11_desktop_window_move_client.cc
@@ -0,0 +1,123 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/views/widget/x11_desktop_window_move_client.h"
+
+#include <X11/Xlib.h>
+// Get rid of a macro from Xlib.h that conflicts with Aura's RootWindow class.
+#undef RootWindow
+
+#include "base/message_loop.h"
+#include "base/message_pump_aurax11.h"
+#include "base/run_loop.h"
+#include "ui/aura/env.h"
+#include "ui/aura/root_window.h"
+#include "ui/base/event.h"
+#include "ui/base/x/x11_util.h"
+#include "ui/gfx/screen.h"
+
+namespace views {
+
+X11DesktopWindowMoveClient::X11DesktopWindowMoveClient()
+ : in_move_loop_(false) {
+}
+
+X11DesktopWindowMoveClient::~X11DesktopWindowMoveClient() {}
+
+bool X11DesktopWindowMoveClient::PreHandleKeyEvent(aura::Window* target,
+ ui::KeyEvent* event) {
+ return false;
+}
+
+bool X11DesktopWindowMoveClient::PreHandleMouseEvent(aura::Window* target,
+ ui::MouseEvent* event) {
+ if (in_move_loop_) {
+ switch (event->type()) {
+ case ui::ET_MOUSE_DRAGGED:
+ case ui::ET_MOUSE_MOVED: {
+ DCHECK(event->valid_system_location());
+ gfx::Point system_loc =
+ event->system_location().Subtract(window_offset_);
+ aura::RootWindow* root_window = target->GetRootWindow();
+ root_window->SetHostBounds(gfx::Rect(
+ system_loc, root_window->GetHostSize()));
+ return true;
+ }
+ case ui::ET_MOUSE_CAPTURE_CHANGED:
+ case ui::ET_MOUSE_RELEASED: {
+ EndMoveLoop();
+ return true;
+ }
+ default:
+ break;
+ }
+ }
+
+ return false;
+}
+
+ui::TouchStatus X11DesktopWindowMoveClient::PreHandleTouchEvent(
+ aura::Window* target,
+ ui::TouchEvent* event) {
+ return ui::TOUCH_STATUS_UNKNOWN;
+}
+
+ui::GestureStatus X11DesktopWindowMoveClient::PreHandleGestureEvent(
+ aura::Window* target,
+ ui::GestureEvent* event) {
+ return ui::GESTURE_STATUS_UNKNOWN;
+}
+
+void X11DesktopWindowMoveClient::RunMoveLoop(aura::Window* source,
+ const gfx::Point& drag_offset) {
+ DCHECK(!in_move_loop_); // Can only handle one nested loop at a time.
+ in_move_loop_ = true;
+ window_offset_ = drag_offset;
+
+ source->GetRootWindow()->ShowRootWindow();
+
+ Display* display = base::MessagePumpAuraX11::GetDefaultXDisplay();
+ XGrabServer(display);
+ XUngrabPointer(display, CurrentTime);
+
+ aura::RootWindow* root_window = source->GetRootWindow();
+ int ret = XGrabPointer(display,
+ root_window->GetAcceleratedWidget(),
+ False,
+ ButtonReleaseMask | PointerMotionMask,
+ GrabModeAsync,
+ GrabModeAsync,
+ None,
+ None,
+ CurrentTime);
+ XUngrabServer(display);
+ if (ret != GrabSuccess) {
+ DLOG(ERROR) << "Grabbing new tab for dragging failed: " << ret;
+ return;
+ }
+
+ MessageLoopForUI* loop = MessageLoopForUI::current();
+ MessageLoop::ScopedNestableTaskAllower allow_nested(loop);
+ base::RunLoop run_loop(aura::Env::GetInstance()->GetDispatcher());
+ quit_closure_ = run_loop.QuitClosure();
+ run_loop.Run();
+}
+
+void X11DesktopWindowMoveClient::EndMoveLoop() {
+ if (!in_move_loop_)
+ return;
+
+ // TODO(erg): Is this ungrab the cause of having to click to give input focus
+ // on drawn out windows? Not ungrabbing here screws the X server until I kill
+ // the chrome process.
+
+ // Ungrab before we let go of the window.
+ Display* display = base::MessagePumpAuraX11::GetDefaultXDisplay();
+ XUngrabPointer(display, CurrentTime);
+
+ in_move_loop_ = false;
+ quit_closure_.Run();
+}
+
+} // namespace views
diff --git a/ui/views/widget/x11_desktop_window_move_client.h b/ui/views/widget/x11_desktop_window_move_client.h
new file mode 100644
index 0000000..b0e910c
--- /dev/null
+++ b/ui/views/widget/x11_desktop_window_move_client.h
@@ -0,0 +1,55 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_VIEWS_WIDGET_X11_DESKTOP_WINDOW_MOVE_CLIENT_H_
+#define UI_VIEWS_WIDGET_X11_DESKTOP_WINDOW_MOVE_CLIENT_H_
+
+#include "base/callback.h"
+#include "base/compiler_specific.h"
+#include "ui/aura/client/window_move_client.h"
+#include "ui/aura/event_filter.h"
+#include "ui/views/views_export.h"
+#include "ui/gfx/point.h"
+
+namespace views {
+
+// When we're dragging tabs, we need to manually position our window.
+class VIEWS_EXPORT X11DesktopWindowMoveClient
+ : public aura::EventFilter,
+ public aura::client::WindowMoveClient {
+ public:
+ X11DesktopWindowMoveClient();
+ virtual ~X11DesktopWindowMoveClient();
+
+ // Overridden from aura::EventFilter:
+ virtual bool PreHandleKeyEvent(aura::Window* target,
+ ui::KeyEvent* event) OVERRIDE;
+ virtual bool PreHandleMouseEvent(aura::Window* target,
+ ui::MouseEvent* event) OVERRIDE;
+ virtual ui::TouchStatus PreHandleTouchEvent(aura::Window* target,
+ ui::TouchEvent* event) OVERRIDE;
+ virtual ui::GestureStatus PreHandleGestureEvent(
+ aura::Window* target,
+ ui::GestureEvent* event) OVERRIDE;
+
+ // Overridden from aura::client::WindowMoveClient:
+ virtual void RunMoveLoop(aura::Window* window,
+ const gfx::Point& drag_offset) OVERRIDE;
+ virtual void EndMoveLoop() OVERRIDE;
+
+ private:
+ // Are we running a nested message loop from RunMoveLoop()?
+ bool in_move_loop_;
+
+ // Our cursor offset from the top left window origin when the drag
+ // started. Used to calculate the window's new bounds relative to the current
+ // location of the cursor.
+ gfx::Point window_offset_;
+
+ base::Closure quit_closure_;
+};
+
+} // namespace views
+
+#endif // UI_VIEWS_WIDGET_X11_DESKTOP_WINDOW_MOVE_CLIENT_H_
diff --git a/ui/views/widget/x11_window_event_filter.cc b/ui/views/widget/x11_window_event_filter.cc
index 472383c..8edf91d 100644
--- a/ui/views/widget/x11_window_event_filter.cc
+++ b/ui/views/widget/x11_window_event_filter.cc
@@ -106,26 +106,7 @@ bool X11WindowEventFilter::PreHandleMouseEvent(aura::Window* target,
return false;
// Get the |x_root_window_| location out of the native event.
- gfx::Point root_location;
- const base::NativeEvent& native_event = event->native_event();
- switch (native_event->type) {
- case ButtonPress: {
- root_location.SetPoint(native_event->xbutton.x_root,
- native_event->xbutton.y_root);
- break;
- }
- case GenericEvent: {
- XIDeviceEvent* xievent =
- static_cast<XIDeviceEvent*>(native_event->xcookie.data);
- root_location.SetPoint(xievent->root_x, xievent->root_y);
- break;
- }
- default: {
- NOTREACHED();
- return false;
- }
- }
-
+ gfx::Point root_location = event->system_location();
return DispatchHostWindowDragMovement(component, root_location);
}