]> git.sur5r.net Git - i3/i3/commitdiff
Support "resize set W H" 1893/head
authorrr- <mkurczew@gmail.com>
Sat, 5 Sep 2015 06:31:45 +0000 (08:31 +0200)
committerrr- <mkurczew@gmail.com>
Fri, 11 Sep 2015 21:12:07 +0000 (23:12 +0200)
docs/userguide
include/commands.h
include/floating.h
parser-specs/commands.spec
src/commands.c
src/floating.c
testcases/t/189-floating-constraints.t
testcases/t/252-floating-size.t [new file with mode: 0644]

index b993f60c6d2a29b267a8d695e60337dd78b524a9..ab9d27d104d97657390bfc3093a33ade7520d7ce 100644 (file)
@@ -2007,6 +2007,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]
 -------------------------------------------------------
 
 Direction can either be one of +up+, +down+, +left+ or +right+. Or you can be
@@ -2015,7 +2016,8 @@ space from all the other containers. The optional pixel argument specifies by
 how many pixels a *floating container* should be grown or shrunk (the default
 is 10 pixels). The ppt argument means percentage points and specifies by how
 many percentage points a *tiling container* should be grown or shrunk (the
-default is 10 percentage points).
+default is 10 percentage points). Note that +resize set+ will only work for
+floating containers.
 
 I recommend using the resize command inside a so called +mode+:
 
@@ -2048,6 +2050,11 @@ mode "resize" {
 bindsym $mod+r mode "resize"
 ----------------------------------------------------------------------
 
+*Example 2 - setting urxvt size to 640x480:*
+------------------------------------------------
+for_window [class="urxvt"] resize set 640 480
+------------------------------------------------
+
 === Jumping to specific windows
 
 Often when in a multi-monitor environment, you want to quickly jump to a
index 6d1046d4b74cece97c59ee2ee36e475dbb13eeda..b243b9e0f0a8c8f5aeccead872614d64c80a89b4 100644 (file)
@@ -60,6 +60,12 @@ void cmd_move_con_to_workspace_name(I3_CMD, char *name);
  */
 void cmd_move_con_to_workspace_number(I3_CMD, char *which);
 
+/**
+ * Implementation of 'resize set <px> [px] <px> [px]'.
+ *
+ */
+void cmd_size(I3_CMD, char *cwidth, char *cheight);
+
 /**
  * Implementation of 'resize grow|shrink <direction> [<px> px] [or <ppt> ppt]'.
  *
index 78e75be8fd35d9589dea7ac873131a8fdaf4cac9..466c0e79a4d04c20c4999eaa400014c288a73452 100644 (file)
@@ -188,6 +188,15 @@ drag_result_t drag_pointer(Con *con, const xcb_button_press_event_t *event,
  */
 void floating_reposition(Con *con, Rect newrect);
 
+/**
+ * Sets size of the CT_FLOATING_CON to specified dimensions. Might limit the
+ * actual size with regard to size constraints taken from user settings.
+ * Additionally, the dimensions may be upscaled until they're divisible by the
+ * window's size hints.
+ *
+ */
+void floating_resize(Con *floating_con, int x, int y);
+
 /**
  * Fixes the coordinates of the floating window whenever the window gets
  * reassigned to a different output (or when the output’s rect changes).
index 94dc630a8c1e0ab6e7de6e54508dacfcdb4e1b2a..f5fb9884b2513706d4bdd2206976c3989ef19ffd 100644 (file)
@@ -211,6 +211,8 @@ state UNMARK:
 state RESIZE:
   way = 'grow', 'shrink'
       -> RESIZE_DIRECTION
+  set = 'set'
+      -> RESIZE_SET
 
 state RESIZE_DIRECTION:
   direction = 'up', 'down', 'left', 'right', 'width', 'height'
@@ -238,6 +240,20 @@ state RESIZE_TILING_FINAL:
   'ppt', end
       -> call cmd_resize($way, $direction, $resize_px, $resize_ppt)
 
+state RESIZE_SET:
+  width = word
+      -> RESIZE_WIDTH
+
+state RESIZE_WIDTH:
+  'px'
+      ->
+  height = word
+      -> RESIZE_HEIGHT
+
+state RESIZE_HEIGHT:
+  'px', end
+      -> call cmd_size($width, $height)
+
 # rename workspace <name> to <name>
 # rename workspace to <name>
 state RENAME:
index 6a80dcb2fadee573a5266758c676363d5a9882e0..1967e2227f22c81f3afe4295accc9c50eb33b081 100644 (file)
@@ -823,6 +823,37 @@ void cmd_resize(I3_CMD, char *way, char *direction, char *resize_px, char *resiz
     ysuccess(true);
 }
 
+/*
+ * Implementation of 'resize set <px> [px] <px> [px]'.
+ *
+ */
+void cmd_size(I3_CMD, char *cwidth, char *cheight) {
+    DLOG("resizing to %sx%s px\n", cwidth, cheight);
+    // TODO: We could either handle this in the parser itself as a separate token (and make the stack typed) or we need a better way to convert a string to a number with error checking
+    int x = atoi(cwidth);
+    int y = atoi(cheight);
+    if (x <= 0 || y <= 0) {
+        ELOG("Resize failed: dimensions cannot be negative (was %sx%s)\n", cwidth, cheight);
+        return;
+    }
+
+    HANDLE_EMPTY_MATCH;
+
+    owindow *current;
+    TAILQ_FOREACH(current, &owindows, owindows) {
+        Con *floating_con;
+        if ((floating_con = con_inside_floating(current->con))) {
+            floating_resize(floating_con, x, y);
+        } else {
+            ELOG("Resize failed: %p not a floating container\n", current->con);
+        }
+    }
+
+    cmd_output->needs_tree_render = true;
+    // XXX: default reply for now, make this a better reply
+    ysuccess(true);
+}
+
 /*
  * Implementation of 'border normal|pixel [<n>]', 'border none|1pixel|toggle'.
  *
index eef02ac674f359c57ab6d1b1332e2d27fb20a4ab..0a510f67fa3de0ba8dc6df8ed4e9cf77050552d2 100644 (file)
@@ -825,6 +825,37 @@ void floating_reposition(Con *con, Rect newrect) {
     tree_render();
 }
 
+/*
+ * Sets size of the CT_FLOATING_CON to specified dimensions. Might limit the
+ * actual size with regard to size constraints taken from user settings.
+ * Additionally, the dimensions may be upscaled until they're divisible by the
+ * window's size hints.
+ *
+ */
+void floating_resize(Con *floating_con, int x, int y) {
+    DLOG("floating resize to %dx%d px\n", x, y);
+    Rect *rect = &floating_con->rect;
+    Con *focused_con = con_descend_focused(floating_con);
+    if (focused_con->window == NULL) {
+        DLOG("No window is focused. Not resizing.\n");
+        return;
+    }
+    int wi = focused_con->window->width_increment;
+    int hi = focused_con->window->height_increment;
+    rect->width = x;
+    rect->height = y;
+    if (wi)
+        rect->width += (wi - 1 - rect->width) % wi;
+    if (hi)
+        rect->height += (hi - 1 - rect->height) % hi;
+
+    floating_check_size(floating_con);
+
+    /* If this is a scratchpad window, don't auto center it from now on. */
+    if (floating_con->scratchpad_state == SCRATCHPAD_FRESH)
+        floating_con->scratchpad_state = SCRATCHPAD_CHANGED;
+}
+
 /*
  * Fixes the coordinates of the floating window whenever the window gets
  * reassigned to a different output (or when the output’s rect changes).
index debbb0a21487742c4971f9e4e23f4dcee69929e1..ad356f4240fadae8a605014182a4b0d218fb6c47 100644 (file)
@@ -186,4 +186,36 @@ is($rect->{y}, $old_y, 'window did not move when trying to resize');
 
 exit_gracefully($pid);
 
+################################################################################
+# 7: check floating_maximum_size with cmd_size
+################################################################################
+
+my $config = <<EOT;
+# i3 config file (v4)
+font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
+
+# Test with different dimensions than the i3 default.
+floating_minimum_size 80 x 70
+floating_maximum_size 100 x 90
+EOT
+
+$pid = launch_with_config($config);
+
+my $window = open_floating_window(rect => [ 0, 0, 90, 80 ]);
+cmd 'border none';
+
+cmd 'resize set 101 91';
+sync_with_i3;
+my $rect = $window->rect;
+is($rect->{width}, 100, 'width did not exceed maximum width');
+is($rect->{height}, 90, 'height did not exceed maximum height');
+
+cmd 'resize set 79 69';
+sync_with_i3;
+$rect = $window->rect;
+is($rect->{width}, 80, 'width did not exceed minimum width');
+is($rect->{height}, 70, 'height did not exceed minimum height');
+
+exit_gracefully($pid);
+
 done_testing;
diff --git a/testcases/t/252-floating-size.t b/testcases/t/252-floating-size.t
new file mode 100644 (file)
index 0000000..ef4861a
--- /dev/null
@@ -0,0 +1,45 @@
+#!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)
+#
+# Test behavior of "resize <width> <height>" command.
+# Ticket: #1727
+# Bug still in: 4.10.2-1-gc0dbc5d
+use i3test;
+
+################################################################################
+# Check that setting floating windows size works
+################################################################################
+
+my $tmp = fresh_workspace;
+
+open_floating_window;
+
+my @content = @{get_ws($tmp)->{floating_nodes}};
+is(@content, 1, 'one floating node on this ws');
+
+my $oldrect = $content[0]->{rect};
+
+cmd 'resize set 100 px 250 px';
+
+@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}, '==', 100, 'width changed to 100 px');
+cmp_ok($content[0]->{rect}->{height}, '==', 250, 'height changed to 250 px');
+
+done_testing;