Skip to content

Commit

Permalink
[ozone/x11] Add window move/resize support.
Browse files Browse the repository at this point in the history
This patch adds a move/resize support to the Ozone/X11 platform.

Change-Id: Ie5b2a059f0024f12b3235272f43876379be041b6
  • Loading branch information
msisov authored and jkim-julie committed Nov 19, 2018
1 parent 2d947a1 commit aa554b2
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 1 deletion.
93 changes: 93 additions & 0 deletions ui/ozone/platform/x11/x11_window_ozone.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include "base/bind.h"
#include "ui/base/dragdrop/os_exchange_data.h"
#include "ui/base/hit_test.h"
#include "ui/base/x/x11_util.h"
#include "ui/events/event.h"
#include "ui/events/event_utils.h"
Expand All @@ -21,6 +22,60 @@

namespace ui {

namespace {

// These constants are defined in the Extended Window Manager Hints
// standard...and aren't in any header that I can find.
const int k_NET_WM_MOVERESIZE_SIZE_TOPLEFT = 0;
const int k_NET_WM_MOVERESIZE_SIZE_TOP = 1;
const int k_NET_WM_MOVERESIZE_SIZE_TOPRIGHT = 2;
const int k_NET_WM_MOVERESIZE_SIZE_RIGHT = 3;
const int k_NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT = 4;
const int k_NET_WM_MOVERESIZE_SIZE_BOTTOM = 5;
const int k_NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT = 6;
const int k_NET_WM_MOVERESIZE_SIZE_LEFT = 7;
const int k_NET_WM_MOVERESIZE_MOVE = 8;

// Identifies the direction of the "hittest" for X11.
bool IdentifyDirection(int hittest, int* direction) {
DCHECK(direction);
*direction = -1;
switch (hittest) {
case HTBOTTOM:
*direction = k_NET_WM_MOVERESIZE_SIZE_BOTTOM;
break;
case HTBOTTOMLEFT:
*direction = k_NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT;
break;
case HTBOTTOMRIGHT:
*direction = k_NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT;
break;
case HTCAPTION:
*direction = k_NET_WM_MOVERESIZE_MOVE;
break;
case HTLEFT:
*direction = k_NET_WM_MOVERESIZE_SIZE_LEFT;
break;
case HTRIGHT:
*direction = k_NET_WM_MOVERESIZE_SIZE_RIGHT;
break;
case HTTOP:
*direction = k_NET_WM_MOVERESIZE_SIZE_TOP;
break;
case HTTOPLEFT:
*direction = k_NET_WM_MOVERESIZE_SIZE_TOPLEFT;
break;
case HTTOPRIGHT:
*direction = k_NET_WM_MOVERESIZE_SIZE_TOPRIGHT;
break;
default:
return false;
}
return true;
}

} // namespace

X11WindowOzone::X11WindowOzone(X11WindowManagerOzone* window_manager,
PlatformWindowDelegate* delegate,
const gfx::Rect& bounds)
Expand All @@ -41,6 +96,10 @@ X11WindowOzone::X11WindowOzone(X11WindowManagerOzone* window_manager,
XChangeProperty(xdisplay(), xwindow(), gfx::GetAtom(kXdndAware), XA_ATOM, 32,
PropModeReplace,
reinterpret_cast<unsigned char*>(&xdnd_version), 1);

// Set a class property key, which allows |this| to be used for interactive
// events, e.g. move or resize.
SetWmMoveResizeHandler(this, AsWmMoveResizeHandler());
}

X11WindowOzone::~X11WindowOzone() {
Expand Down Expand Up @@ -175,6 +234,36 @@ void X11WindowOzone::OnDragSessionClose(int dnd_action) {
NOTIMPLEMENTED_LOG_ONCE();
}

void X11WindowOzone::DispatchHostWindowDragMovement(
int hittest,
const gfx::Point& pointer_location) {
int direction;
if (!IdentifyDirection(hittest, &direction))
return;

// We most likely have an implicit grab right here. We need to dump it
// because what we're about to do is tell the window manager
// that it's now responsible for moving the window around; it immediately
// grabs when it receives the event below.
XUngrabPointer(xdisplay(), x11::CurrentTime);

XEvent event;
memset(&event, 0, sizeof(event));
event.xclient.type = ClientMessage;
event.xclient.display = xdisplay();
event.xclient.window = xwindow();
event.xclient.message_type = gfx::GetAtom("_NET_WM_MOVERESIZE");
event.xclient.format = 32;
event.xclient.data.l[0] = pointer_location.x();
event.xclient.data.l[1] = pointer_location.y();
event.xclient.data.l[2] = direction;
event.xclient.data.l[3] = 0;
event.xclient.data.l[4] = 0;

XSendEvent(xdisplay(), xroot_window(), x11::False,
SubstructureRedirectMask | SubstructureNotifyMask, &event);
}

void X11WindowOzone::OnDragMotion(const gfx::PointF& screen_point,
int flags,
::Time event_time,
Expand Down Expand Up @@ -296,4 +385,8 @@ bool X11WindowOzone::ProcessDragDropEvent(XEvent* xev) {
return false;
}

WmMoveResizeHandler* X11WindowOzone::AsWmMoveResizeHandler() {
return static_cast<WmMoveResizeHandler*>(this);
}

} // namespace ui
11 changes: 10 additions & 1 deletion ui/ozone/platform/x11/x11_window_ozone.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "base/macros.h"
#include "ui/events/platform/platform_event_dispatcher.h"
#include "ui/events/platform/x11/x11_event_source_libevent.h"
#include "ui/platform_window/platform_window_handler/wm_move_resize_handler.h"
#include "ui/platform_window/x11/window_move_loop_client.h"
#include "ui/platform_window/x11/x11_window_base.h"

Expand All @@ -21,7 +22,8 @@ class X11WindowManagerOzone;
// PlatformWindow implementation for X11 Ozone. PlatformEvents are ui::Events.
class X11WindowOzone : public X11WindowBase,
public PlatformEventDispatcher,
public XEventDispatcher {
public XEventDispatcher,
public WmMoveResizeHandler {
public:
X11WindowOzone(X11WindowManagerOzone* window_manager,
PlatformWindowDelegate* delegate,
Expand Down Expand Up @@ -61,6 +63,11 @@ class X11WindowOzone : public X11WindowBase,
void OnMouseMoved(const gfx::Point& point, gfx::AcceleratedWidget* widget);
void OnDragSessionClose(int dnd_action);

// WmMoveResizeHandler
void DispatchHostWindowDragMovement(
int hittest,
const gfx::Point& pointer_location) override;

private:
enum SourceState {
// |source_current_window_| will receive a drop once we receive an
Expand All @@ -81,6 +88,8 @@ class X11WindowOzone : public X11WindowBase,
uint32_t DispatchEvent(const PlatformEvent& event) override;
bool ProcessDragDropEvent(XEvent* xev);

WmMoveResizeHandler* AsWmMoveResizeHandler();

X11WindowManagerOzone* window_manager_;

// TODO(msisov, tonikitoo): Add a dummy implementation for chromeos.
Expand Down
1 change: 1 addition & 0 deletions ui/platform_window/x11/x11_window_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ class X11_WINDOW_EXPORT X11WindowBase : public PlatformWindow,

XDisplay* xdisplay() { return xdisplay_; }
XID xwindow() const { return xwindow_; }
XID xroot_window() const { return xroot_window_; }

void UnConfineCursor();

Expand Down

0 comments on commit aa554b2

Please sign in to comment.