From 14eea7fce571ed6b1592af382aa4440b87c62b56 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Ingo=20B=C3=BCrk?= Date: Fri, 13 Jan 2017 18:30:50 +0100 Subject: [PATCH] Added support for _NET_MOVERESIZE_WINDOW. (#2634) fixes #2603 --- include/atoms_NET_SUPPORTED.xmacro | 1 + src/handlers.c | 34 +++++++ testcases/t/266-net-moveresize-window.t | 117 ++++++++++++++++++++++++ 3 files changed, 152 insertions(+) create mode 100644 testcases/t/266-net-moveresize-window.t diff --git a/include/atoms_NET_SUPPORTED.xmacro b/include/atoms_NET_SUPPORTED.xmacro index 1358e0f1..a7b9676d 100644 --- a/include/atoms_NET_SUPPORTED.xmacro +++ b/include/atoms_NET_SUPPORTED.xmacro @@ -31,3 +31,4 @@ xmacro(_NET_DESKTOP_NAMES) xmacro(_NET_DESKTOP_VIEWPORT) xmacro(_NET_ACTIVE_WINDOW) xmacro(_NET_CLOSE_WINDOW) +xmacro(_NET_MOVERESIZE_WINDOW) diff --git a/src/handlers.c b/src/handlers.c index 9b248058..e02a1ee5 100644 --- a/src/handlers.c +++ b/src/handlers.c @@ -637,6 +637,11 @@ static void handle_expose_event(xcb_expose_event_t *event) { #define _NET_WM_MOVERESIZE_MOVE_KEYBOARD 10 /* move via keyboard */ #define _NET_WM_MOVERESIZE_CANCEL 11 /* cancel operation */ +#define _NET_MOVERESIZE_WINDOW_X (1 << 8) +#define _NET_MOVERESIZE_WINDOW_Y (1 << 9) +#define _NET_MOVERESIZE_WINDOW_WIDTH (1 << 10) +#define _NET_MOVERESIZE_WINDOW_HEIGHT (1 << 11) + /* * Handle client messages (EWMH) * @@ -897,6 +902,35 @@ static void handle_client_message(xcb_client_message_event_t *event) { DLOG("_NET_WM_MOVERESIZE direction %d not implemented\n", direction); break; } + } else if (event->type == A__NET_MOVERESIZE_WINDOW) { + DLOG("Received _NET_MOVE_RESIZE_WINDOW. Handling by faking a configure request.\n"); + + void *_generated_event = scalloc(32, 1); + xcb_configure_request_event_t *generated_event = _generated_event; + + generated_event->window = event->window; + generated_event->response_type = XCB_CONFIGURE_REQUEST; + + generated_event->value_mask = 0; + if (event->data.data32[0] & _NET_MOVERESIZE_WINDOW_X) { + generated_event->value_mask |= XCB_CONFIG_WINDOW_X; + generated_event->x = event->data.data32[1]; + } + if (event->data.data32[0] & _NET_MOVERESIZE_WINDOW_Y) { + generated_event->value_mask |= XCB_CONFIG_WINDOW_Y; + generated_event->y = event->data.data32[2]; + } + if (event->data.data32[0] & _NET_MOVERESIZE_WINDOW_WIDTH) { + generated_event->value_mask |= XCB_CONFIG_WINDOW_WIDTH; + generated_event->width = event->data.data32[3]; + } + if (event->data.data32[0] & _NET_MOVERESIZE_WINDOW_HEIGHT) { + generated_event->value_mask |= XCB_CONFIG_WINDOW_HEIGHT; + generated_event->height = event->data.data32[4]; + } + + handle_configure_request(generated_event); + FREE(generated_event); } else { DLOG("Skipping client message for unhandled type %d\n", event->type); } diff --git a/testcases/t/266-net-moveresize-window.t b/testcases/t/266-net-moveresize-window.t new file mode 100644 index 00000000..69542f9c --- /dev/null +++ b/testcases/t/266-net-moveresize-window.t @@ -0,0 +1,117 @@ +#!perl +# vim:ts=4:sw=4:expandtab +# +# Please read the following documents before working on tests: +# • http://build.i3wm.org/docs/testsuite.html +# (or docs/testsuite) +# +# • http://build.i3wm.org/docs/lib-i3test.html +# (alternatively: perldoc ./testcases/lib/i3test.pm) +# +# • http://build.i3wm.org/docs/ipc.html +# (or docs/ipc) +# +# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf +# (unless you are already familiar with Perl) +# +# Tests for _NET_MOVERESIZE_WINDOW. +# Ticket: #2603 +use i3test i3_autostart => 0; + +sub moveresize_window { + my ($win, $pos_x, $pos_y, $width, $height) = @_; + + my $flags = 0; + $flags |= (1 << 8) if $pos_x >= 0; + $flags |= (1 << 9) if $pos_y >= 0; + $flags |= (1 << 10) if $width >= 0; + $flags |= (1 << 11) if $height >= 0; + + my $msg = pack "CCSLLLLLLL", + X11::XCB::CLIENT_MESSAGE, # response_type + 32, # format + 0, # sequence + $win->id, # window + $x->atom(name => '_NET_MOVERESIZE_WINDOW')->id, # message type + $flags, # data32[0] (flags) + $pos_x, # data32[1] (x) + $pos_y, # data32[2] (y) + $width, # data32[3] (width) + $height; # data32[4] (height) + + $x->send_event(0, $x->get_root_window(), X11::XCB::EVENT_MASK_SUBSTRUCTURE_REDIRECT, $msg); + sync_with_i3; +} + +my $config = < [50, 50, 100, 100]); +moveresize_window($window, 0, 0, 555, 666); + +$content = get_ws($ws); +is($content->{floating_nodes}->[0]->{rect}->{x}, 0, 'the x coordinate is correct'); +is($content->{floating_nodes}->[0]->{rect}->{y}, 0, 'the y coordinate is correct'); +is($content->{floating_nodes}->[0]->{rect}->{width}, 555, 'the width is correct'); +is($content->{floating_nodes}->[0]->{rect}->{height}, 666, 'the height is correct'); + +exit_gracefully($pid); + +############################################################################### +# A _NET_MOVERESIZE_WINDOW client message can change only the position of a +# window. +############################################################################### + +$pid = launch_with_config($config); +$ws = fresh_workspace; + +$window = open_floating_window(rect => [50, 50, 100, 100]); +moveresize_window($window, 100, 100, -1, -1); + +$content = get_ws($ws); +is($content->{floating_nodes}->[0]->{rect}->{x}, 100, 'the x coordinate is correct'); +is($content->{floating_nodes}->[0]->{rect}->{y}, 100, 'the y coordinate is correct'); +is($content->{floating_nodes}->[0]->{rect}->{width}, 100, 'the width is unchanged'); +is($content->{floating_nodes}->[0]->{rect}->{height}, 100, 'the height is unchanged'); + +exit_gracefully($pid); + +############################################################################### +# A _NET_MOVERESIZE_WINDOW client message can change only the size of a +# window. +############################################################################### + +$pid = launch_with_config($config); +$ws = fresh_workspace; + +$window = open_floating_window(rect => [50, 50, 100, 100]); +moveresize_window($window, -1, -1, 200, 200); + +$content = get_ws($ws); +is($content->{floating_nodes}->[0]->{rect}->{x}, 50, 'the x coordinate is unchanged'); +is($content->{floating_nodes}->[0]->{rect}->{y}, 50, 'the y coordinate is unchanged'); +is($content->{floating_nodes}->[0]->{rect}->{width}, 200, 'the width is correct'); +is($content->{floating_nodes}->[0]->{rect}->{height}, 200, 'the height is correct'); + +exit_gracefully($pid); + +############################################################################### + +done_testing; -- 2.39.5