"min" means minimum required version
"lkgv" means last known good version
-┌──────────────┬────────┬────────┬───────────────────────────────────────────────────────────┐
-│ dependency │ min. │ lkgv │ URL │
-├──────────────┼────────┼────────┼───────────────────────────────────────────────────────────┤
-│ pkg-config │ 0.25 │ 0.29 │ https://pkgconfig.freedesktop.org/ │
-│ libxcb │ 1.1.93 │ 1.12 │ https://xcb.freedesktop.org/dist/ │
-│ xcb-util │ 0.3.3 │ 0.4.1 │ https://xcb.freedesktop.org/dist/ │
-│ xkbcommon │ 0.4.0 │ 0.6.1 │ https://xkbcommon.org/ │
-│ xkbcommon-x11│ 0.4.0 │ 0.6.1 │ https://xkbcommon.org/ │
-│ util-cursor³⁴│ 0.0.99 │ 0.1.3 │ https://xcb.freedesktop.org/dist/ │
-│ util-wm⁴ │ 0.3.8 │ 0.3.8 │ https://xcb.freedesktop.org/dist/ │
-│ util-keysyms⁴│ 0.3.8 │ 0.4.0 │ https://xcb.freedesktop.org/dist/ │
-│ util-xrm⁴ │ 1.0.0 │ 1.0.0 │ https://github.com/Airblader/xcb-util-xrm │
-│ libev │ 4.0 │ 4.19 │ http://libev.schmorp.de/ │
-│ yajl │ 2.0.1 │ 2.1.0 │ https://lloyd.github.com/yajl/ │
-│ asciidoc │ 8.3.0 │ 8.6.9 │ http://www.methods.co.nz/asciidoc/ │
-│ xmlto │ 0.0.23 │ 0.0.23 │ http://www.methods.co.nz/asciidoc/ │
-│ Pod::Simple² │ 3.22 │ 3.22 │ http://search.cpan.org/~dwheeler/Pod-Simple-3.23/ │
-│ docbook-xml │ 4.5 │ 4.5 │ http://www.methods.co.nz/asciidoc/ │
-│ PCRE │ 8.12 │ 8.38 │ https://www.pcre.org/ │
-│ libsn¹ │ 0.10 │ 0.12 │ https://freedesktop.org/wiki/Software/startup-notification │
-│ pango │ 1.30.0 | 1.40.1 │ http://www.pango.org/ │
-│ cairo │ 1.14.4 │ 1.14.6 │ https://cairographics.org/ │
-└──────────────┴────────┴────────┴───────────────────────────────────────────────────────────┘
+â\94\8câ\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94¬â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94¬â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94¬â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\90
+│ dependency │ min. │ lkgv │ URL │
+â\94\9câ\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94¼â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94¼â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94¼â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94¤
+│ pkg-config │ 0.25 │ 0.29 │ https://pkgconfig.freedesktop.org/ │
+│ libxcb │ 1.1.93 │ 1.12 │ https://xcb.freedesktop.org/dist/ │
+│ xcb-util │ 0.3.3 │ 0.4.1 │ https://xcb.freedesktop.org/dist/ │
+│ xkbcommon │ 0.4.0 │ 0.6.1 │ https://xkbcommon.org/ │
+│ xkbcommon-x11│ 0.4.0 │ 0.6.1 │ https://xkbcommon.org/ │
+│ util-cursor³⁴│ 0.0.99 │ 0.1.3 │ https://xcb.freedesktop.org/dist/ │
+│ util-wm⁴ │ 0.3.8 │ 0.3.8 │ https://xcb.freedesktop.org/dist/ │
+│ util-keysyms⁴│ 0.3.8 │ 0.4.0 │ https://xcb.freedesktop.org/dist/ │
+│ util-xrm⁴ │ 1.0.0 │ 1.0.0 │ https://github.com/Airblader/xcb-util-xrm/ │
+│ libev │ 4.0 │ 4.19 │ http://libev.schmorp.de/ │
+│ yajl │ 2.0.1 │ 2.1.0 │ https://lloyd.github.com/yajl/ │
+│ asciidoc │ 8.3.0 │ 8.6.9 │ http://www.methods.co.nz/asciidoc/ │
+│ xmlto │ 0.0.23 │ 0.0.23 │ http://www.methods.co.nz/asciidoc/ │
+│ Pod::Simple² │ 3.22 │ 3.22 │ http://search.cpan.org/dist/Pod-Simple/ │
+│ docbook-xml │ 4.5 │ 4.5 │ http://www.methods.co.nz/asciidoc/ │
+│ PCRE │ 8.12 │ 8.38 │ https://www.pcre.org/ │
+│ libsn¹ │ 0.10 │ 0.12 │ https://freedesktop.org/wiki/Software/startup-notification/ │
+│ pango │ 1.30.0 │ 1.40.1 │ http://www.pango.org/ │
+│ cairo │ 1.14.4 │ 1.14.6 │ https://cairographics.org/ │
+â\94\94â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94´â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94´â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94´â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\80â\94\98
¹ libsn = libstartup-notification
² Pod::Simple is a Perl module required for converting the testsuite
documentation to HTML. See https://michael.stapelberg.de/cpan/#Pod::Simple
*Syntax*:
-------------------------------------------------------
resize grow|shrink <direction> [<px> px [or <ppt> ppt]]
-resize set <width> [px | ppt] <height> [px | ppt]
+resize set [width] <width> [px | ppt]
+resize set height <height> [px | ppt]
+resize set [width] <width> [px | ppt] [height] <height> [px | ppt]
-------------------------------------------------------
Direction can either be one of +up+, +down+, +left+ or +right+. Or you can be
-> call cmd_resize($way, $direction, &resize_px, &resize_ppt)
state RESIZE_SET:
+ 'height'
+ -> RESIZE_HEIGHT_GET_NUMBER
+ 'width'
+ ->
width = number
-> RESIZE_WIDTH
state RESIZE_WIDTH:
mode_width = 'px', 'ppt'
->
+ end
+ -> call cmd_resize_set(&width, $mode_width, 0, 0)
+ 'height'
+ -> RESIZE_HEIGHT_GET_NUMBER
+ height = number
+ -> RESIZE_HEIGHT
+
+state RESIZE_HEIGHT_GET_NUMBER:
height = number
-> RESIZE_HEIGHT
struct xkb_state *xkb_state_numlock_no_shift;
};
+#define ADD_TRANSLATED_KEY(code, mods) \
+ do { \
+ struct Binding_Keycode *binding_keycode = smalloc(sizeof(struct Binding_Keycode)); \
+ binding_keycode->modifiers = (mods); \
+ binding_keycode->keycode = (code); \
+ TAILQ_INSERT_TAIL(&(bind->keycodes_head), binding_keycode, keycodes); \
+ } while (0)
+
/*
* add_keycode_if_matches is called for each keycode in the keymap and will add
* the keycode to |data->bind| if the keycode can result in the keysym
}
Binding *bind = resolving->bind;
-#define ADD_TRANSLATED_KEY(mods) \
- do { \
- struct Binding_Keycode *binding_keycode = smalloc(sizeof(struct Binding_Keycode)); \
- binding_keycode->modifiers = (mods); \
- binding_keycode->keycode = key; \
- TAILQ_INSERT_TAIL(&(bind->keycodes_head), binding_keycode, keycodes); \
- } while (0)
-
- ADD_TRANSLATED_KEY(bind->event_state_mask);
+ ADD_TRANSLATED_KEY(key, bind->event_state_mask);
/* Also bind the key with active CapsLock */
- ADD_TRANSLATED_KEY(bind->event_state_mask | XCB_MOD_MASK_LOCK);
+ ADD_TRANSLATED_KEY(key, bind->event_state_mask | XCB_MOD_MASK_LOCK);
/* If this binding is not explicitly for NumLock, check whether we need to
* add a fallback. */
xkb_keysym_t sym_numlock = xkb_state_key_get_one_sym(numlock_state, key);
if (sym_numlock == resolving->keysym) {
/* Also bind the key with active NumLock */
- ADD_TRANSLATED_KEY(bind->event_state_mask | xcb_numlock_mask);
+ ADD_TRANSLATED_KEY(key, bind->event_state_mask | xcb_numlock_mask);
/* Also bind the key with active NumLock+CapsLock */
- ADD_TRANSLATED_KEY(bind->event_state_mask | xcb_numlock_mask | XCB_MOD_MASK_LOCK);
+ ADD_TRANSLATED_KEY(key, bind->event_state_mask | xcb_numlock_mask | XCB_MOD_MASK_LOCK);
} else {
DLOG("Skipping automatic numlock fallback, key %d resolves to 0x%x with numlock\n",
key, sym_numlock);
}
}
-
-#undef ADD_TRANSLATED_KEY
}
/*
Binding *bind;
TAILQ_FOREACH(bind, bindings, bindings) {
-#define ADD_TRANSLATED_KEY(code, mods) \
- do { \
- struct Binding_Keycode *binding_keycode = smalloc(sizeof(struct Binding_Keycode)); \
- binding_keycode->modifiers = (mods); \
- binding_keycode->keycode = (code); \
- TAILQ_INSERT_TAIL(&(bind->keycodes_head), binding_keycode, keycodes); \
- } while (0)
-
if (bind->input_type == B_MOUSE) {
long button;
if (!parse_long(bind->symbol + (sizeof("button") - 1), &button, 10)) {
DLOG("state=0x%x, cfg=\"%s\", sym=0x%x → keycodes%s (%d)\n",
bind->event_state_mask, bind->symbol, keysym, keycodes, num_keycodes);
free(keycodes);
-
-#undef ADD_TRANSLATED_KEY
}
out:
}
}
+#undef ADD_TRANSLATED_KEY
+
/*
* Switches the key bindings to the given mode, if the mode exists
*
if ((floating_con = con_inside_floating(current->con))) {
Con *output = con_get_output(floating_con);
if (cwidth == 0) {
- cwidth = output->rect.width;
+ cwidth = floating_con->rect.width;
} else if (mode_width && strcmp(mode_width, "ppt") == 0) {
cwidth = output->rect.width * ((double)cwidth / 100.0);
}
if (cheight == 0) {
- cheight = output->rect.height;
+ cheight = floating_con->rect.height;
} else if (mode_height && strcmp(mode_height, "ppt") == 0) {
cheight = output->rect.height * ((double)cheight / 100.0);
}
}
}
- if (cheight > 0 && mode_width && strcmp(mode_width, "ppt") == 0) {
+ if (cheight > 0 && mode_height && strcmp(mode_height, "ppt") == 0) {
/* get the appropriate current container (skip stacked/tabbed cons) */
Con *target = current->con;
Con *dummy;
/* By re-attaching, the sort order will be correct afterwards. */
Con *previously_focused = focused;
+ Con *previously_focused_content = focused->type == CT_WORKSPACE ? focused->parent : NULL;
Con *parent = workspace->parent;
con_detach(workspace);
con_attach(workspace, parent, false);
}
workspace_move_to_output(workspace, target_output);
- if (previously_focused)
+ bool can_restore_focus = previously_focused != NULL;
+ /* NB: If previously_focused is a workspace we can't
+ * work directly with it since it might have been cleaned up by
+ * workspace_show() already, depending on the
+ * focus order/number of other workspaces on the output.
+ * Instead, we loop through the available workspaces and only focus
+ * previously_focused if we still find it. */
+ if (previously_focused_content) {
+ Con *workspace = NULL;
+ GREP_FIRST(workspace, previously_focused_content, child == previously_focused);
+ can_restore_focus &= (workspace != NULL);
+ }
+
+ if (can_restore_focus) {
+ /* Restore the previous focus since con_attach messes with the focus. */
workspace_show(con_get_workspace(previously_focused));
+ con_activate(previously_focused);
+ }
break;
}
- /* Restore the previous focus since con_attach messes with the focus. */
- con_activate(previously_focused);
-
cmd_output->needs_tree_render = true;
ysuccess(true);
EOT
################################################################################
-# Check that setting floating windows size works
+# Init variables used for all tests.
################################################################################
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';
+sub do_test {
+ my ($width, $height) = @_;
+
+ cmp_ok($content[0]->{rect}->{x}, '==', $oldrect->{x}, 'x unchanged');
+ cmp_ok($content[0]->{rect}->{y}, '==', $oldrect->{y}, 'y unchanged');
+
+ @content = @{get_ws($tmp)->{floating_nodes}};
+ if ($width) {
+ cmp_ok($content[0]->{rect}->{width}, '==', $width, "width changed to $width px");
+ } else {
+ cmp_ok($content[0]->{rect}->{width}, '==', $oldrect->{width}, 'width unchanged');
+ }
+ if ($height) {
+ cmp_ok($content[0]->{rect}->{height}, '==', $height, "height changed to $height px");
+ } else {
+ cmp_ok($content[0]->{rect}->{height}, '==', $oldrect->{height}, 'height unchanged');
+ }
+ $oldrect = $content[0]->{rect};
+}
-@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');
+################################################################################
+# Check that setting floating windows size works
+################################################################################
+
+cmd 'resize set 100 px 250 px';
+do_test(100, 250);
################################################################################
# Same but with ppt instead of px
################################################################################
-kill_all_windows;
-$tmp = 'ws';
-cmd "workspace $tmp";
-open_floating_window;
+cmd 'resize set 33 ppt 20 ppt';
+do_test(int(0.33 * 1333), int(0.2 * 999));
-@content = @{get_ws($tmp)->{floating_nodes}};
-is(@content, 1, 'one floating node on this ws');
+################################################################################
+# Mix ppt and px in a single resize set command
+################################################################################
-$oldrect = $content[0]->{rect};
+cmd 'resize set 44 ppt 111 px';
+do_test(int(0.44 * 1333), 111);
-cmd 'resize set 33 ppt 20 ppt';
-my $expected_width = int(0.33 * 1333);
-my $expected_height = int(0.2 * 999);
+cmd 'resize set 222 px 100 ppt';
+do_test(222, 999);
+
+################################################################################
+# Zero is interpreted as no change.
+# See issue: #3276.
+################################################################################
-@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");
+cmd 'resize set 0 px 333 px';
+do_test(0, 333);
+
+cmd 'resize set 333 px 0 ppt';
+do_test(333, 0);
+
+cmd 'resize set 0 px 0 ppt';
+do_test(0, 0);
+
+cmd 'resize set 100 ppt 0 px';
+do_test(1333, 0);
################################################################################
-# Mix ppt and px in a single resize set command
+# Use 'width' and 'height' keywords.
+# See issue: #3275.
################################################################################
-cmd 'resize set 44 ppt 111 px';
-$expected_width = int(0.44 * 1333);
-$expected_height = 111;
+cmd 'resize set width 200 px';
+do_test(200, 0);
-@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 height 200 px';
+do_test(0, 200);
-cmd 'resize set 222 px 100 ppt';
-$expected_width = 222;
-$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");
+cmd 'resize set width 300 px height 300 px';
+do_test(300, 300);
+
+# ppt + keyword used only for height
+cmd 'resize set 100 ppt height 100 px';
+do_test(1333, 100);
done_testing;
is(get_output_for_workspace('5'), 'fake-0',
'Renaming the workspace to a workspace assigned to a directional output should not move the workspace');
+##########################################################################
+# Renaming a workspace, so that it becomes assigned to the focused
+# output's workspace (and the focused output is empty) should
+# result in the original workspace replacing the originally
+# focused workspace.
+##########################################################################
+
+cmd 'workspace baz';
+cmd 'rename workspace 5 to 2';
+is(get_output_for_workspace('2'), 'fake-1',
+ 'Renaming a workspace so that it moves to the focused output which contains only an empty workspace should replace the empty workspace');
+
done_testing;
cmp_float($nodes->[0]->{percent}, 0.25, 'left window got only 25%');
cmp_float($nodes->[1]->{percent}, 0.75, 'right window got 75%');
+# Same but use the 'width' keyword.
+cmd 'resize set width 80 ppt';
+
+($nodes, $focus) = get_ws_content($tmp);
+
+cmp_float($nodes->[0]->{percent}, 0.20, 'left window got 20%');
+cmp_float($nodes->[1]->{percent}, 0.80, 'right window got 80%');
+
############################################################
# resize vertically
############################################################
cmp_float($nodes->[0]->{percent}, 0.25, 'top window got only 25%');
cmp_float($nodes->[1]->{percent}, 0.75, 'bottom window got 75%');
+# Same but use the 'height' keyword.
+cmd 'resize set height 80 ppt';
+
+($nodes, $focus) = get_ws_content($tmp);
+
+cmp_float($nodes->[0]->{percent}, 0.20, 'top window got 20%');
+cmp_float($nodes->[1]->{percent}, 0.80, 'bottom window got 80%');
############################################################
# resize horizontally and vertically