]> git.sur5r.net Git - i3/i3/commitdiff
Added support for _NET_MOVERESIZE_WINDOW. (#2634)
authorIngo Bürk <admin@airblader.de>
Fri, 13 Jan 2017 17:30:50 +0000 (18:30 +0100)
committerMichael Stapelberg <stapelberg@users.noreply.github.com>
Fri, 13 Jan 2017 17:30:50 +0000 (09:30 -0800)
fixes #2603

include/atoms_NET_SUPPORTED.xmacro
src/handlers.c
testcases/t/266-net-moveresize-window.t [new file with mode: 0644]

index 1358e0f11d7e3bef6231140f6a9a97adfbefe152..a7b9676d9817e21dcd142c6f62fc9606cada2773 100644 (file)
@@ -31,3 +31,4 @@ xmacro(_NET_DESKTOP_NAMES)
 xmacro(_NET_DESKTOP_VIEWPORT)
 xmacro(_NET_ACTIVE_WINDOW)
 xmacro(_NET_CLOSE_WINDOW)
+xmacro(_NET_MOVERESIZE_WINDOW)
index 9b248058e2e75140ce531b6e17f8d3643c5f9fe8..e02a1ee5457b166bf029533a4b99303b7b3dafec 100644 (file)
@@ -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 (file)
index 0000000..69542f9
--- /dev/null
@@ -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 = <<EOT;
+# i3 config file (v4)
+font font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
+
+new_window none
+new_float none
+EOT
+
+my ($pid, $ws, $window, $content);
+
+###############################################################################
+
+###############################################################################
+# A _NET_MOVERESIZE_WINDOW client message can change the position and size
+# of a floating window.
+###############################################################################
+
+$pid = launch_with_config($config);
+$ws = fresh_workspace;
+
+$window = open_floating_window(rect => [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;