]> git.sur5r.net Git - i3/i3/commitdiff
Introduce I3_FLOATING_WINDOW 2231/head
authorIngo Bürk <ingo.buerk@tngtech.com>
Tue, 23 Feb 2016 19:12:45 +0000 (20:12 +0100)
committerIngo Bürk <ingo.buerk@tngtech.com>
Thu, 25 Feb 2016 17:36:22 +0000 (18:36 +0100)
This patch introduces a proprietary atom I3_FLOATING_WINDOW which will be
set and maintained for floating windows and removed on tiling containers.

This allows users to select on this atom, e.g., in their compositor
configuration or in utility scripts (without using the IPC).

fixes #2223

include/atoms_rest.xmacro
src/floating.c
testcases/t/263-i3-floating-window-atom.t [new file with mode: 0644]

index 12cb63fd2434ecdc4fe05c3016d10351a3f032d1..d461dc08a1d0e7dcda554e04184d6010f78438d5 100644 (file)
@@ -13,6 +13,7 @@ xmacro(I3_CONFIG_PATH)
 xmacro(I3_SYNC)
 xmacro(I3_SHMLOG_PATH)
 xmacro(I3_PID)
+xmacro(I3_FLOATING_WINDOW)
 xmacro(_NET_REQUEST_FRAME_EXTENTS)
 xmacro(_NET_FRAME_EXTENTS)
 xmacro(_MOTIF_WM_HINTS)
index 8ac818ac6a95ab6978c4af7cb6f775e0c609df3b..231577fd5edf4c5ac83888db12616e45cce95b4f 100644 (file)
@@ -29,6 +29,34 @@ static Rect total_outputs_dimensions(void) {
     return outputs_dimensions;
 }
 
+/*
+ * Updates I3_FLOATING_WINDOW by either setting or removing it on the con and
+ * all its children.
+ *
+ */
+static void floating_set_hint_atom(Con *con, bool floating) {
+    if (!con_is_leaf(con)) {
+        Con *child;
+        TAILQ_FOREACH(child, &(con->nodes_head), nodes) {
+            floating_set_hint_atom(child, floating);
+        }
+    }
+
+    if (con->window == NULL) {
+        return;
+    }
+
+    if (floating) {
+        uint32_t val = 1;
+        xcb_change_property(conn, XCB_PROP_MODE_REPLACE, con->window->id,
+                            A_I3_FLOATING_WINDOW, XCB_ATOM_CARDINAL, 32, 1, &val);
+    } else {
+        xcb_delete_property(conn, con->window->id, A_I3_FLOATING_WINDOW);
+    }
+
+    xcb_flush(conn);
+}
+
 /**
  * Called when a floating window is created or resized.
  * This function resizes the window if its size is higher or lower than the
@@ -260,19 +288,19 @@ void floating_enable(Con *con, bool automatic) {
     /* Check if we need to re-assign it to a different workspace because of its
      * coordinates and exit if that was done successfully. */
     if (floating_maybe_reassign_ws(nc)) {
-        ipc_send_window_event("floating", con);
-        return;
+        goto done;
     }
 
     /* Sanitize coordinates: Check if they are on any output */
     if (get_output_containing(nc->rect.x, nc->rect.y) != NULL) {
-        ipc_send_window_event("floating", con);
-        return;
+        goto done;
     }
 
     ELOG("No output found at destination coordinates, centering floating window on current ws\n");
     floating_center(nc, ws->rect);
 
+done:
+    floating_set_hint_atom(nc, true);
     ipc_send_window_event("floating", con);
 }
 
@@ -318,6 +346,7 @@ void floating_disable(Con *con, bool automatic) {
     if (set_focus)
         con_focus(con);
 
+    floating_set_hint_atom(con, false);
     ipc_send_window_event("floating", con);
 }
 
diff --git a/testcases/t/263-i3-floating-window-atom.t b/testcases/t/263-i3-floating-window-atom.t
new file mode 100644 (file)
index 0000000..43b69cc
--- /dev/null
@@ -0,0 +1,70 @@
+#!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 our proprietary atom I3_FLOATING_WINDOW to allow
+# identifying floating windows.
+# Ticket: #2223
+use i3test;
+use X11::XCB qw(:all);
+
+my ($con);
+
+sub has_i3_floating_window {
+    sync_with_i3;
+
+    my ($con) = @_;
+    my $cookie = $x->get_property(
+        0,
+        $con->{id},
+        $x->atom(name => 'I3_FLOATING_WINDOW')->id,
+        $x->atom(name => 'CARDINAL')->id,
+        0,
+        1
+    );
+
+    my $reply = $x->get_property_reply($cookie->{sequence});
+    return 0 if $reply->{length} != 1;
+
+    return unpack("L", $reply->{value});
+}
+
+###############################################################################
+# Toggling floating on a container adds / removes I3_FLOATING_WINDOW.
+###############################################################################
+
+fresh_workspace;
+
+$con = open_window;
+is(has_i3_floating_window($con), 0, 'I3_FLOATING_WINDOW is not set');
+
+cmd 'floating enable';
+is(has_i3_floating_window($con), 1, 'I3_FLOATING_WINDOW is set');
+
+cmd 'floating disable';
+is(has_i3_floating_window($con), 0, 'I3_FLOATING_WINDOW is not set');
+
+###############################################################################
+# A window that is floated when managed has I3_FLOATING_WINDOW set.
+###############################################################################
+#
+fresh_workspace;
+
+$con = open_floating_window;
+is(has_i3_floating_window($con), 1, 'I3_FLOATING_WINDOW is set');
+
+###############################################################################
+
+done_testing;