]> git.sur5r.net Git - i3/i3/commitdiff
Merge pull request #3040 from jchook/next
authorIngo Bürk <admin@airblader.de>
Mon, 13 Nov 2017 21:01:06 +0000 (22:01 +0100)
committerGitHub <noreply@github.com>
Mon, 13 Nov 2017 21:01:06 +0000 (22:01 +0100)
$mod+r toggles resize mode

docs/userguide
etc/config
i3-sensible-terminal
include/commands.h
libi3/ipc_recv_message.c
man/i3-sensible-terminal.man
parser-specs/commands.spec
src/commands.c
src/tree.c
testcases/t/252-floating-size.t
testcases/t/510-focus-across-outputs.t

index 54ac9c8d63cb2cd7012feaad7284d1b8c5e35f33..4fec6cdaf1ad742a357946c329c951f048f96935 100644 (file)
@@ -2302,7 +2302,7 @@ If you want to resize containers/windows using your keyboard, you can use the
 *Syntax*:
 -------------------------------------------------------
 resize grow|shrink <direction> [<px> px [or <ppt> ppt]]
-resize set <width> [px] <height> [px]
+resize set <width> [px | ppt] <height> [px | ppt]
 -------------------------------------------------------
 
 Direction can either be one of +up+, +down+, +left+ or +right+. Or you can be
index f6fd5e7b5a4d71c3bf85c09cbca9c27cabf38482..5b751d00df55f7f6831e5845697d4ce98c9a8eff 100644 (file)
@@ -22,7 +22,7 @@ font pango:monospace 8
 # The font above is very space-efficient, that is, it looks good, sharp and
 # clear in small sizes. However, its unicode glyph coverage is limited, the old
 # X core fonts rendering does not support right-to-left and this being a bitmap
-# font, it doesnt scale on retina/hidpi displays.
+# font, it doesn't scale on retina/hidpi displays.
 
 # use these keys for focus, movement, and resize directions when reaching for
 # the arrows is not convenient
index f92ff224a8989d3fbef991257d0a9ccd8deb56b7..23cb5688f716de0ddb013c61c4ecea35d13cb18b 100755 (executable)
@@ -8,7 +8,7 @@
 # We welcome patches that add distribution-specific mechanisms to find the
 # preferred terminal emulator. On Debian, there is the x-terminal-emulator
 # symlink for example.
-for terminal in "$TERMINAL" x-terminal-emulator urxvt rxvt termit terminator Eterm aterm uxterm xterm gnome-terminal roxterm xfce4-terminal termite lxterminal mate-terminal terminology st qterminal lilyterm tilix terminix konsole; do
+for terminal in "$TERMINAL" x-terminal-emulator urxvt rxvt termit terminator Eterm aterm uxterm xterm gnome-terminal roxterm xfce4-terminal termite lxterminal mate-terminal terminology st qterminal lilyterm tilix terminix konsole kitty; do
     if command -v "$terminal" > /dev/null 2>&1; then
         exec "$terminal" "$@"
     fi
index 9780f788b5bb53b308609df0818017e420d77024..85d5fe78a9f27056e565c048d52e4edc806e9bbc 100644 (file)
@@ -66,7 +66,7 @@ void cmd_move_con_to_workspace_number(I3_CMD, const char *which, const char *no_
  * Implementation of 'resize set <px> [px] <px> [px]'.
  *
  */
-void cmd_resize_set(I3_CMD, long cwidth, long cheight);
+void cmd_resize_set(I3_CMD, long cwidth, const char *mode_width, long cheight, const char *mode_height);
 
 /**
  * Implementation of 'resize grow|shrink <direction> [<px> px] [or <ppt> ppt]'.
index 16dda90d89b8cbcd5ec540aff00b1c3aba86d46c..84da5aa36cb90d7b913ec7c0afc87568102a9d70 100644 (file)
@@ -13,6 +13,7 @@
 #include <stdint.h>
 #include <unistd.h>
 #include <errno.h>
+#include <inttypes.h>
 
 #include <i3/ipc.h>
 
@@ -41,14 +42,21 @@ int ipc_recv_message(int sockfd, uint32_t *message_type,
         if (n == -1)
             return -1;
         if (n == 0) {
-            return -2;
+            if (read_bytes == 0) {
+                return -2;
+            } else {
+                ELOG("IPC: unexpected EOF while reading header, got %" PRIu32 " bytes, want %" PRIu32 " bytes\n",
+                     read_bytes, to_read);
+                return -3;
+            }
         }
 
         read_bytes += n;
     }
 
     if (memcmp(walk, I3_IPC_MAGIC, strlen(I3_IPC_MAGIC)) != 0) {
-        ELOG("IPC: invalid magic in reply\n");
+        ELOG("IPC: invalid magic in header, got \"%.*s\", want \"%s\"\n",
+             (int)strlen(I3_IPC_MAGIC), walk, I3_IPC_MAGIC);
         return -3;
     }
 
@@ -61,13 +69,18 @@ int ipc_recv_message(int sockfd, uint32_t *message_type,
     *reply = smalloc(*reply_length);
 
     read_bytes = 0;
-    int n;
     while (read_bytes < *reply_length) {
-        if ((n = read(sockfd, *reply + read_bytes, *reply_length - read_bytes)) == -1) {
+        const int n = read(sockfd, *reply + read_bytes, *reply_length - read_bytes);
+        if (n == -1) {
             if (errno == EINTR || errno == EAGAIN)
                 continue;
             return -1;
         }
+        if (n == 0) {
+            ELOG("IPC: unexpected EOF while reading payload, got %" PRIu32 " bytes, want %" PRIu32 " bytes\n",
+                 read_bytes, *reply_length);
+            return -3;
+        }
 
         read_bytes += n;
     }
index 20a6810c59bb8ed9ec4a1ab717e85de16ad63b3e..bccc824a86959e3d16656f7e8eddd549f2888a45 100644 (file)
@@ -44,6 +44,7 @@ It tries to start one of the following (in that order):
 * tilix
 * terminix
 * konsole
+* kitty
 
 Please don’t complain about the order: If the user has any preference, they will
 have $TERMINAL set or modified their i3 configuration file.
index a587332817e8b23bde3d48cd8ef434c43924b275..0289fa1ab6018a404cb2445f5fa57b61eaf283eb 100644 (file)
@@ -258,14 +258,16 @@ state RESIZE_SET:
       -> RESIZE_WIDTH
 
 state RESIZE_WIDTH:
-  'px'
+  mode_width = 'px', 'ppt'
       ->
   height = number
       -> RESIZE_HEIGHT
 
 state RESIZE_HEIGHT:
-  'px', end
-      -> call cmd_resize_set(&width, &height)
+  mode_height = 'px', 'ppt'
+      ->
+  end
+      -> call cmd_resize_set(&width, $mode_width, &height, $mode_height)
 
 # rename workspace <name> to <name>
 # rename workspace to <name>
index d7cdf2198f7d6170f4d5038cba7dc396a2897361..e68fcd802b1c15e7a20300bd6a5ca2af5a6f27d9 100644 (file)
@@ -676,13 +676,13 @@ void cmd_resize(I3_CMD, const char *way, const char *direction, long resize_px,
 }
 
 /*
- * Implementation of 'resize set <px> [px] <px> [px]'.
+ * Implementation of 'resize set <width> [px | ppt] <height> [px | ppt]'.
  *
  */
-void cmd_resize_set(I3_CMD, long cwidth, long cheight) {
-    DLOG("resizing to %ldx%ld px\n", cwidth, cheight);
+void cmd_resize_set(I3_CMD, long cwidth, const char *mode_width, long cheight, const char *mode_height) {
+    DLOG("resizing to %ld %s x %ld %s\n", cwidth, mode_width, cheight, mode_height);
     if (cwidth <= 0 || cheight <= 0) {
-        ELOG("Resize failed: dimensions cannot be negative (was %ldx%ld)\n", cwidth, cheight);
+        ELOG("Resize failed: dimensions cannot be negative (was %ld %s x %ld %s)\n", cwidth, mode_width, cheight, mode_height);
         return;
     }
 
@@ -692,6 +692,13 @@ void cmd_resize_set(I3_CMD, long cwidth, long cheight) {
     TAILQ_FOREACH(current, &owindows, owindows) {
         Con *floating_con;
         if ((floating_con = con_inside_floating(current->con))) {
+            Con *output = con_get_output(floating_con);
+            if (mode_width && strcmp(mode_width, "ppt") == 0) {
+                cwidth = output->rect.width * ((double)cwidth / 100.0);
+            }
+            if (mode_height && strcmp(mode_height, "ppt") == 0) {
+                cheight = output->rect.height * ((double)cheight / 100.0);
+            }
             floating_resize(floating_con, cwidth, cheight);
         } else {
             ELOG("Resize failed: %p not a floating container\n", current->con);
index a6cc59fbb8faf8260e21719edba5bb85e164fc85..710bb655f6ab39254f0187884d69f565e718f9be 100644 (file)
@@ -560,21 +560,10 @@ static bool _tree_next(Con *con, char way, orientation_t orientation, bool wrap)
         if (!workspace)
             return false;
 
-        workspace_show(workspace);
-
-        /* If a workspace has an active fullscreen container, one of its
-         * children should always be focused. The above workspace_show()
-         * should be adequate for that, so return. */
-        if (con_get_fullscreen_con(workspace, CF_OUTPUT))
-            return true;
-
-        Con *focus = con_descend_direction(workspace, direction);
-
-        /* special case: if there was no tiling con to focus and the workspace
-         * has a floating con in the focus stack, focus the top of the focus
-         * stack (which may be floating) */
-        if (focus == workspace)
+        Con *focus = con_descend_tiling_focused(workspace);
+        if (focus == workspace) {
             focus = con_descend_focused(workspace);
+        }
 
         if (focus) {
             con_focus(focus);
index 8d8d412036105fd17a18ebb9aaf72bae8e176733..ac0c48d03d81a8ba31209197df47dd9c601426c0 100644 (file)
 # Test behavior of "resize <width> <height>" command.
 # Ticket: #1727
 # Bug still in: 4.10.2-1-gc0dbc5d
-use i3test;
+use i3test i3_config => <<EOT;
+# i3 config file (v4)
+font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
+
+fake-outputs 1333x999+0+0
+workspace ws output fake-0
+EOT
 
 ################################################################################
 # Check that setting floating windows size works
@@ -42,4 +48,54 @@ cmp_ok($content[0]->{rect}->{height}, '!=', $oldrect->{width}, 'height changed')
 cmp_ok($content[0]->{rect}->{width}, '==', 100, 'width changed to 100 px');
 cmp_ok($content[0]->{rect}->{height}, '==', 250, 'height changed to 250 px');
 
+################################################################################
+# Same but with ppt instead of px
+################################################################################
+
+kill_all_windows;
+$tmp = 'ws';
+cmd "workspace $tmp";
+open_floating_window;
+
+@content = @{get_ws($tmp)->{floating_nodes}};
+is(@content, 1, 'one floating node on this ws');
+
+$oldrect = $content[0]->{rect};
+
+cmd 'resize set 33 ppt 20 ppt';
+my $expected_width = int(0.33 * 1333);
+my $expected_height = int(0.2 * 999);
+
+@content = @{get_ws($tmp)->{floating_nodes}};
+cmp_ok($content[0]->{rect}->{x}, '==', $oldrect->{x}, 'x untouched');
+cmp_ok($content[0]->{rect}->{y}, '==', $oldrect->{y}, 'y untouched');
+cmp_ok($content[0]->{rect}->{width}, '!=', $oldrect->{width}, 'width changed');
+cmp_ok($content[0]->{rect}->{height}, '!=', $oldrect->{width}, 'height changed');
+cmp_ok($content[0]->{rect}->{width}, '==', $expected_width, "width changed to $expected_width px");
+cmp_ok($content[0]->{rect}->{height}, '==', $expected_height, "height changed to $expected_height px");
+
+################################################################################
+# Mix ppt and px in a single resize set command
+################################################################################
+
+cmd 'resize set 44 ppt 111 px';
+my $expected_width = int(0.44 * 1333);
+my $expected_height = 111;
+
+@content = @{get_ws($tmp)->{floating_nodes}};
+cmp_ok($content[0]->{rect}->{x}, '==', $oldrect->{x}, 'x untouched');
+cmp_ok($content[0]->{rect}->{y}, '==', $oldrect->{y}, 'y untouched');
+cmp_ok($content[0]->{rect}->{width}, '==', $expected_width, "width changed to $expected_width px");
+cmp_ok($content[0]->{rect}->{height}, '==', $expected_height, "height changed to $expected_height px");
+
+cmd 'resize set 222 px 100 ppt';
+my $expected_width = 222;
+my $expected_height = 999;
+
+@content = @{get_ws($tmp)->{floating_nodes}};
+cmp_ok($content[0]->{rect}->{x}, '==', $oldrect->{x}, 'x untouched');
+cmp_ok($content[0]->{rect}->{y}, '==', $oldrect->{y}, 'y untouched');
+cmp_ok($content[0]->{rect}->{width}, '==', $expected_width, "width changed to $expected_width px");
+cmp_ok($content[0]->{rect}->{height}, '==', $expected_height, "height changed to $expected_height px");
+
 done_testing;
index 21169adbc3b25ca155f6c9f5ad4e180702e79181..07a2115c06497d851f5eee9c2f1eef2121d0474b 100644 (file)
@@ -92,7 +92,7 @@ reset_focus $s3_ws;
 
 cmd "workspace $s2_ws";
 cmd 'focus right';
-is($x->input_focus, $sixth->id, 'sixth window focused');
+is($x->input_focus, $seventh->id, 'seventh window focused');
 reset_focus $s3_ws;
 
 cmd "workspace $s2_ws";
@@ -110,6 +110,8 @@ is($x->input_focus, $third->id, 'third window focused');
 cmd 'focus parent';
 cmd 'focus parent';
 cmd 'split v';
+# Focus second or else $first gets to the top of the focus stack.
+cmd '[id=' . $second->id . '] focus';
 reset_focus $s0_ws;
 
 cmd "workspace $s3_ws";
@@ -137,4 +139,96 @@ cmd "workspace $s2_ws";
 cmd 'focus up';
 is($x->input_focus, $second->id, 'second window focused');
 
+###################################################################
+# Test that focus (left|down|right|up), when focusing across
+# outputs, doesn't focus the next window in the given direction but
+# the most focused window of the container in the given direction.
+# In the following layout:
+# [ WS1*[ ] WS2[ H[ A B* ] ] ]
+# (where the asterisk denotes the focused container within its
+# parent) moving right from WS1 should focus B which is focused
+# inside WS2, not A which is the next window on the right of WS1.
+# See issue #1160.
+###################################################################
+
+kill_all_windows;
+
+sync_with_i3;
+$x->root->warp_pointer(1025, 0);  # Second screen.
+sync_with_i3;
+$s1_ws = fresh_workspace;
+$first = open_window;
+$second = open_window;
+
+sync_with_i3;
+$x->root->warp_pointer(0, 0);  # First screen.
+sync_with_i3;
+$s0_ws = fresh_workspace;
+open_window;
+$third = open_window;
+
+cmd 'focus right';
+is($x->input_focus, $second->id, 'second window (rightmost) focused');
+cmd 'focus left';
+is($x->input_focus, $first->id, 'first window focused');
+cmd 'focus left';
+is($x->input_focus, $third->id, 'third window focused');
+
+
+###################################################################
+# Similar but with a tabbed layout.
+###################################################################
+
+cmd 'layout tabbed';
+$fourth = open_window;
+cmd 'focus left';
+is($x->input_focus, $third->id, 'third window (tabbed) focused');
+cmd "workspace $s1_ws";
+cmd 'focus left';
+is($x->input_focus, $third->id, 'third window (tabbed) focused');
+
+
+###################################################################
+# Similar but with a stacked layout on the bottom screen.
+###################################################################
+
+sync_with_i3;
+$x->root->warp_pointer(0, 769);  # Third screen.
+sync_with_i3;
+$s2_ws = fresh_workspace;
+cmd 'layout stacked';
+$fifth = open_window;
+$sixth = open_window;
+
+cmd "workspace $s0_ws";
+cmd 'focus down';
+is($x->input_focus, $sixth->id, 'sixth window (stacked) focused');
+
+###################################################################
+# Similar but with a more complex layout.
+###################################################################
+
+sync_with_i3;
+$x->root->warp_pointer(1025, 769);  # Fourth screen.
+sync_with_i3;
+$s3_ws = fresh_workspace;
+open_window;
+open_window;
+cmd 'split v';
+open_window;
+open_window;
+cmd 'split h';
+my $nested = open_window;
+open_window;
+cmd 'focus left';
+is($x->input_focus, $nested->id, 'nested window focused');
+
+cmd "workspace $s1_ws";
+cmd 'focus down';
+is($x->input_focus, $nested->id, 'nested window focused from workspace above');
+
+cmd "workspace $s2_ws";
+cmd 'focus right';
+is($x->input_focus, $nested->id, 'nested window focused from workspace on the left');
+
 done_testing;