]> git.sur5r.net Git - i3/i3/commitdiff
Merge pull request #3230 from hwangcc23/fix-3227
authorIngo Bürk <admin@airblader.de>
Sat, 21 Apr 2018 15:57:54 +0000 (17:57 +0200)
committerGitHub <noreply@github.com>
Sat, 21 Apr 2018 15:57:54 +0000 (17:57 +0200)
Make "scratchpad show" return correct info

24 files changed:
Makefile.am
docs/debugging
docs/ipc
docs/userguide
i3bar/include/configuration.h
i3bar/src/config.c
i3bar/src/main.c
i3bar/src/xcb.c
include/config_directives.h
include/configuration.h
include/util.h
man/i3-input.man
man/i3-sensible-editor.man
man/i3-sensible-pager.man
parser-specs/commands.spec
parser-specs/config.spec
src/commands.c
src/con.c
src/config.c
src/config_directives.c
src/ipc.c
src/main.c
testcases/t/169-border-toggle.t
testcases/t/243-move-to-mark.t

index 557c65a58fe9e4506c8529c8d549f3a033a78f58..f8ae7a1b2b22416b41714c0a6844b4d96a507052 100644 (file)
@@ -521,6 +521,7 @@ i3_SOURCES = \
        include/shmlog.h \
        include/sighandler.h \
        include/startup.h \
+       include/sync.h \
        include/tree.h \
        include/util.h \
        include/window.h \
index dd26f98d924b3783a79a09fb9b0e64ce15a25d94..562a11f21e5f36993ac494f2405502a8345c387c 100644 (file)
@@ -160,7 +160,8 @@ flood kicks.
 
 == Debugging i3bar
 
-To debug i3bar problems, add +verbose yes+ to all +bar {}+ blocks in your i3
+To debug i3bar problems, use the +--verbose+ commandline parameter,
+or add +verbose yes+ to all +bar {}+ blocks in your i3
 config, reload your config and then restart all i3bar instances like this:
 
 ---------------------------------------------------------------------
index f011e773c42b9b4a1218061df1ee6c9b2e5311ca..e44ffd7ce20f2c38230bef3e137e02f73a22ea0e 100644 (file)
--- a/docs/ipc
+++ b/docs/ipc
@@ -328,6 +328,8 @@ window (integer)::
        This field is set to null for split containers or otherwise empty
        containers. This ID corresponds to what xwininfo(1) and other
        X11-related tools display (usually in hex).
+window_properties (map)::
+       X11 window properties title, instance, class, window_role and transient_for.
 urgent (bool)::
        Whether this container (window, split container, floating container or
        workspace) has the urgency hint set, directly or indirectly. All parent
@@ -423,6 +425,12 @@ JSON dump:
            "width": 1280,
            "height": 782
          },
+         "window_properties": {
+           "class": "Evince",
+           "instance": "evince",
+           "title": "Properties",
+           "transient_for": 52428808
+         },
          "floating_nodes": [],
          "nodes": [
 
index 5fc36585d02b3fb7a67bfe7adc43e6aca6bf2a62..e82403900374d50aadd57103c3c35b68e163c061 100644 (file)
@@ -2476,7 +2476,9 @@ To change the border of the current client, you can use +border normal+ to use t
 border (including window title), +border pixel 1+ to use a 1-pixel border (no window title)
 and +border none+ to make the client borderless.
 
-There is also +border toggle+ which will toggle the different border styles.
+There is also +border toggle+ which will toggle the different border styles. The
+optional pixel argument can be used to specify the border width when switching
+to the normal and pixel styles.
 
 Note that "pixel" refers to logical pixel. On HiDPI displays, a logical pixel
 may be represented by multiple physical pixels, so +pixel 1+ might not
@@ -2484,8 +2486,8 @@ necessarily translate into a single pixel row wide border.
 
 *Syntax*:
 -----------------------------------------------
-border normal|pixel [<n>]
-border none|toggle
+border normal|pixel|toggle [<n>]
+border none
 
 # legacy syntax, equivalent to "border pixel 1"
 border 1pixel
index e60d74836c34aa33104ceffd29b74ddff4545bc4..b86da2e040bad6c2191e7cbcd3df3ef1f9cdfad9 100644 (file)
@@ -41,13 +41,13 @@ typedef struct tray_output_t {
 } tray_output_t;
 
 typedef struct config_t {
-    int modifier;
+    uint32_t modifier;
 
     TAILQ_HEAD(bindings_head, binding_t)
     bindings;
 
     position_t position;
-    int verbose;
+    bool verbose;
     struct xcb_color_strings_t colors;
     bool disable_binding_mode_indicator;
     bool disable_ws;
index 59a44aee912b9a9b30ea99392cab662dda43dc03..c23256291c665545177c0323fca1cbfafbef0146 100644 (file)
@@ -119,6 +119,7 @@ static int config_string_cb(void *params_, const unsigned char *val, size_t _len
         return 1;
     }
 
+    /* Kept for backwards compatibility. */
     if (!strcmp(cur_key, "modifier")) {
         DLOG("modifier = %.*s\n", len, val);
         if (len == strlen("none") && !strncmp((const char *)val, "none", strlen("none"))) {
@@ -304,8 +305,10 @@ static int config_boolean_cb(void *params_, int val) {
     }
 
     if (!strcmp(cur_key, "verbose")) {
-        DLOG("verbose = %d\n", val);
-        config.verbose = val;
+        if (!config.verbose) {
+            DLOG("verbose = %d\n", val);
+            config.verbose = val;
+        }
         return 1;
     }
 
@@ -336,6 +339,12 @@ static int config_integer_cb(void *params_, long long val) {
         return 1;
     }
 
+    if (!strcmp(cur_key, "modifier")) {
+        DLOG("modifier = %lld\n", val);
+        config.modifier = (uint32_t)val;
+        return 1;
+    }
+
     return 0;
 }
 
index 069803d4f944289afac72323bf15acd8d24fae03..f90bb31297867decc9e4701aa7fcd9c2fe5b0108 100644 (file)
@@ -62,6 +62,7 @@ void print_usage(char *elf_name) {
     printf("-s, --socket  <sock_path>\tConnect to i3 via <sock_path>\n");
     printf("-h, --help    Display this help message and exit\n");
     printf("-v, --version Display version number and exit\n");
+    printf("-V, --verbose Enable verbose mode\n");
     printf("\n");
     printf(" PLEASE NOTE that i3bar will be automatically started by i3\n"
            " as soon as there is a 'bar' configuration block in your\n"
@@ -106,9 +107,10 @@ int main(int argc, char **argv) {
         {"bar_id", required_argument, 0, 'b'},
         {"help", no_argument, 0, 'h'},
         {"version", no_argument, 0, 'v'},
+        {"verbose", no_argument, 0, 'V'},
         {NULL, 0, 0, 0}};
 
-    while ((opt = getopt_long(argc, argv, "b:s:hv", long_opt, &option_index)) != -1) {
+    while ((opt = getopt_long(argc, argv, "b:s:hvV", long_opt, &option_index)) != -1) {
         switch (opt) {
             case 's':
                 socket_path = expand_path(optarg);
@@ -120,6 +122,9 @@ int main(int argc, char **argv) {
             case 'b':
                 config.bar_id = sstrdup(optarg);
                 break;
+            case 'V':
+                config.verbose = true;
+                break;
             default:
                 print_usage(argv[0]);
                 exit(EXIT_SUCCESS);
index 8843edbdc72e4532b8f6d1008be0018bfd9dd4a0..7bfeb12e90dd7d8cd20e31e0a8e6accfba0fb745 100644 (file)
@@ -79,7 +79,7 @@ int bar_height;
 
 /* These are only relevant for XKB, which we only need for grabbing modifiers */
 int xkb_base;
-int mod_pressed = 0;
+bool mod_pressed = 0;
 
 /* Event watchers, to interact with the user */
 ev_prepare *xcb_prep;
@@ -1108,49 +1108,15 @@ void xcb_prep_cb(struct ev_loop *loop, ev_prepare *watcher, int revents) {
             DLOG("received an xkb event\n");
 
             xcb_xkb_state_notify_event_t *state = (xcb_xkb_state_notify_event_t *)event;
+            const uint32_t mod = (config.modifier & 0xFFFF);
+            mod_pressed = (mod != 0 && (state->mods & mod) == mod);
             if (state->xkbType == XCB_XKB_STATE_NOTIFY && config.modifier != XCB_NONE) {
-                int modstate = state->mods & config.modifier;
-
-#define DLOGMOD(modmask, status)                        \
-    do {                                                \
-        switch (modmask) {                              \
-            case ShiftMask:                             \
-                DLOG("ShiftMask got " #status "!\n");   \
-                break;                                  \
-            case ControlMask:                           \
-                DLOG("ControlMask got " #status "!\n"); \
-                break;                                  \
-            case Mod1Mask:                              \
-                DLOG("Mod1Mask got " #status "!\n");    \
-                break;                                  \
-            case Mod2Mask:                              \
-                DLOG("Mod2Mask got " #status "!\n");    \
-                break;                                  \
-            case Mod3Mask:                              \
-                DLOG("Mod3Mask got " #status "!\n");    \
-                break;                                  \
-            case Mod4Mask:                              \
-                DLOG("Mod4Mask got " #status "!\n");    \
-                break;                                  \
-            case Mod5Mask:                              \
-                DLOG("Mod5Mask got " #status "!\n");    \
-                break;                                  \
-        }                                               \
-    } while (0)
-
-                if (modstate != mod_pressed) {
-                    if (modstate == 0) {
-                        DLOGMOD(config.modifier, released);
-                        if (!activated_mode)
-                            hide_bars();
-                    } else {
-                        DLOGMOD(config.modifier, pressed);
-                        activated_mode = false;
-                        unhide_bars();
-                    }
-                    mod_pressed = modstate;
+                if (mod_pressed) {
+                    activated_mode = false;
+                    unhide_bars();
+                } else if (!activated_mode) {
+                    hide_bars();
                 }
-#undef DLOGMOD
             }
 
             free(event);
index 852325ba0e2d6b3a7f71685c9ec663d79c291345..f21ad8e1985b2675fdcdbe0937e8a65d5a7e3d17 100644 (file)
@@ -81,7 +81,7 @@ CFGFUN(bar_hidden_state, const char *hidden_state);
 CFGFUN(bar_id, const char *bar_id);
 CFGFUN(bar_output, const char *output);
 CFGFUN(bar_verbose, const char *verbose);
-CFGFUN(bar_modifier, const char *modifier);
+CFGFUN(bar_modifier, const char *modifiers);
 CFGFUN(bar_wheel_up_cmd, const char *command);
 CFGFUN(bar_wheel_down_cmd, const char *command);
 CFGFUN(bar_bindsym, const char *button, const char *release, const char *command);
index 87897aafcd7137592e0d1e4725d29de2cdbeb9e1..3eccca4cef604d3ebbd89ab4650ffb682d075700 100644 (file)
@@ -289,16 +289,7 @@ struct Barconfig {
            S_SHOW = 1 } hidden_state;
 
     /** Bar modifier (to show bar when in hide mode). */
-    enum {
-        M_NONE = 0,
-        M_CONTROL = 1,
-        M_SHIFT = 2,
-        M_MOD1 = 3,
-        M_MOD2 = 4,
-        M_MOD3 = 5,
-        M_MOD4 = 6,
-        M_MOD5 = 7
-    } modifier;
+    uint32_t modifier;
 
     TAILQ_HEAD(bar_bindings_head, Barbinding)
     bar_bindings;
index 3547d8d7b50df6533fc566aec682efe0e63bc1a3..d58e21b7d675fd6946988a8c85fae5904c45d956 100644 (file)
@@ -25,9 +25,6 @@
 #define STARTS_WITH(string, needle) (strncasecmp((string), (needle), strlen((needle))) == 0)
 #define CIRCLEQ_NEXT_OR_NULL(head, elm, field) (CIRCLEQ_NEXT(elm, field) != CIRCLEQ_END(head) ? CIRCLEQ_NEXT(elm, field) : NULL)
 #define CIRCLEQ_PREV_OR_NULL(head, elm, field) (CIRCLEQ_PREV(elm, field) != CIRCLEQ_END(head) ? CIRCLEQ_PREV(elm, field) : NULL)
-#define FOR_TABLE(workspace)                             \
-    for (int cols = 0; cols < (workspace)->cols; cols++) \
-        for (int rows = 0; rows < (workspace)->rows; rows++)
 
 #define NODES_FOREACH(head)                                                    \
     for (Con *child = (Con *)-1; (child == (Con *)-1) && ((child = 0), true);) \
index 07a91783115e8394092207842dd341a332bea5be..dc145914749ab758962729649be6bf73a3355b14 100644 (file)
@@ -1,5 +1,5 @@
 i3-input(1)
-=========
+===========
 Michael Stapelberg <michael+i3@stapelberg.de>
 v4.1.2, April 2012
 
index 4f16d6c1e0e10098dee2645e098144142d25bc61..31e82ca3e71f5b882086d64c2bf1fdf7a2a5212c 100644 (file)
@@ -1,5 +1,5 @@
 i3-sensible-editor(1)
-===================
+=====================
 Michael Stapelberg <michael+i3@stapelberg.de>
 v4.1, November 2011
 
index 22754c0bd96686e74e5cb372384b9381db9b8ef4..2339bef053f73f96ed4eecf27b2d9e8b1136737d 100644 (file)
@@ -1,5 +1,5 @@
 i3-sensible-pager(1)
-===================
+====================
 Michael Stapelberg <michael+i3@stapelberg.de>
 v4.1, November 2011
 
index 4048768e5cee375b1ef31e55ca0ceef50e0c0fcd..106dac9909a448c2c8704f3fb91f55cd0a0f2d22 100644 (file)
@@ -86,16 +86,16 @@ state DEBUGLOG:
 # border normal|pixel [<n>]
 # border none|1pixel|toggle
 state BORDER:
-  border_style = 'normal', 'pixel'
+  border_style = 'normal', 'pixel', 'toggle'
     -> BORDER_WIDTH
-  border_style = 'none', 'toggle'
+  border_style = 'none'
     -> call cmd_border($border_style, 0)
-  border_style = '1pixel'
-    -> call cmd_border($border_style, 1)
+  '1pixel'
+    -> call cmd_border("pixel", 1)
 
 state BORDER_WIDTH:
   end
-    -> call cmd_border($border_style, 2)
+    -> call cmd_border($border_style, -1)
   border_width = number
     -> call cmd_border($border_style, &border_width)
 
index 9cbc782bfde7eaf42de3ab485a4eea1b63c0cfd9..c5c4651c0064516b1b6477742d5ee24c455d05c4 100644 (file)
@@ -491,8 +491,14 @@ state BAR_ID:
       -> call cfg_bar_id($bar_id); BAR
 
 state BAR_MODIFIER:
-  modifier = 'Mod1', 'Mod2', 'Mod3', 'Mod4', 'Mod5', 'Control', 'Ctrl', 'Shift', 'none', 'off'
-      -> call cfg_bar_modifier($modifier); BAR
+  'off', 'none'
+      -> call cfg_bar_modifier(NULL); BAR
+  modifiers = 'Mod1', 'Mod2', 'Mod3', 'Mod4', 'Mod5', 'Shift', 'Control', 'Ctrl'
+      ->
+  '+'
+      ->
+  end
+      -> call cfg_bar_modifier($modifiers); BAR
 
 state BAR_WHEEL_UP_CMD:
   command = string
index 4c03ba32a72d6005f76f773deab7ebe4b0216339..6083c6515268af4e3e34546bad7ef13d7a199dce 100644 (file)
@@ -718,6 +718,26 @@ void cmd_resize_set(I3_CMD, long cwidth, const char *mode_width, long cheight, c
     ysuccess(success);
 }
 
+static int border_width_from_style(border_style_t border_style, long border_width, Con *con) {
+    if (border_style == BS_NONE) {
+        return 0;
+    }
+    if (border_width >= 0) {
+        return logical_px(border_width);
+    }
+
+    const bool is_floating = con_inside_floating(con) != NULL;
+    /* Load the configured defaults. */
+    if (is_floating && border_style == config.default_floating_border) {
+        return config.default_floating_border_width;
+    } else if (!is_floating && border_style == config.default_border) {
+        return config.default_border_width;
+    } else {
+        /* Use some hardcoded values. */
+        return logical_px(border_style == BS_NORMAL ? 2 : 1);
+    }
+}
+
 /*
  * Implementation of 'border normal|pixel [<n>]', 'border none|1pixel|toggle'.
  *
@@ -730,36 +750,24 @@ void cmd_border(I3_CMD, const char *border_style_str, long border_width) {
 
     TAILQ_FOREACH(current, &owindows, owindows) {
         DLOG("matching: %p / %s\n", current->con, current->con->name);
-        int border_style = current->con->border_style;
-        int con_border_width = border_width;
 
+        border_style_t border_style;
         if (strcmp(border_style_str, "toggle") == 0) {
-            border_style++;
-            border_style %= 3;
-            if (border_style == BS_NORMAL)
-                con_border_width = 2;
-            else if (border_style == BS_NONE)
-                con_border_width = 0;
-            else if (border_style == BS_PIXEL)
-                con_border_width = 1;
+            border_style = (current->con->border_style + 1) % 3;
+        } else if (strcmp(border_style_str, "normal") == 0) {
+            border_style = BS_NORMAL;
+        } else if (strcmp(border_style_str, "pixel") == 0) {
+            border_style = BS_PIXEL;
+        } else if (strcmp(border_style_str, "none") == 0) {
+            border_style = BS_NONE;
         } else {
-            if (strcmp(border_style_str, "normal") == 0) {
-                border_style = BS_NORMAL;
-            } else if (strcmp(border_style_str, "pixel") == 0) {
-                border_style = BS_PIXEL;
-            } else if (strcmp(border_style_str, "1pixel") == 0) {
-                border_style = BS_PIXEL;
-                con_border_width = 1;
-            } else if (strcmp(border_style_str, "none") == 0) {
-                border_style = BS_NONE;
-            } else {
-                ELOG("BUG: called with border_style=%s\n", border_style_str);
-                ysuccess(false);
-                return;
-            }
+            ELOG("BUG: called with border_style=%s\n", border_style_str);
+            ysuccess(false);
+            return;
         }
 
-        con_set_border_style(current->con, border_style, logical_px(con_border_width));
+        const int con_border_width = border_width_from_style(border_style, border_width, current->con);
+        con_set_border_style(current->con, border_style, con_border_width);
     }
 
     cmd_output->needs_tree_render = true;
index 2180ad8816ab005af8fd3e1b5175e112a4de897d..deb6555846d05311acd05269a7e84fca53e45bad 100644 (file)
--- a/src/con.c
+++ b/src/con.c
@@ -1305,7 +1305,7 @@ bool con_move_to_mark(Con *con, const char *mark) {
         return true;
     }
 
-    if (con->type == CT_WORKSPACE) {
+    if (target->type == CT_WORKSPACE) {
         DLOG("target container is a workspace, simply moving the container there.\n");
         con_move_to_workspace(con, target, true, false, false);
         return true;
index 95b7ec9801f424e91402482589fc70e2d6efacbb..de149ce7d84adb828d2ec453410afb834afe1e53 100644 (file)
@@ -191,10 +191,6 @@ void load_configuration(xcb_connection_t *conn, const char *override_configpath,
 
     bindings = default_mode->bindings;
 
-#define REQUIRED_OPTION(name) \
-    if (config.name == NULL)  \
-        die("You did not specify required configuration option " #name "\n");
-
     /* Clear the old config or initialize the data structure */
     memset(&config, 0, sizeof(config));
 
index 491c840afbf71db3b52518f7a5b2eb1962e7c272..4a31f79e5ce8efed4bb501f32e8258ca6f53c078 100644 (file)
@@ -479,25 +479,8 @@ CFGFUN(bar_verbose, const char *verbose) {
     current_bar->verbose = eval_boolstr(verbose);
 }
 
-CFGFUN(bar_modifier, const char *modifier) {
-    if (strcmp(modifier, "Mod1") == 0)
-        current_bar->modifier = M_MOD1;
-    else if (strcmp(modifier, "Mod2") == 0)
-        current_bar->modifier = M_MOD2;
-    else if (strcmp(modifier, "Mod3") == 0)
-        current_bar->modifier = M_MOD3;
-    else if (strcmp(modifier, "Mod4") == 0)
-        current_bar->modifier = M_MOD4;
-    else if (strcmp(modifier, "Mod5") == 0)
-        current_bar->modifier = M_MOD5;
-    else if (strcmp(modifier, "Control") == 0 ||
-             strcmp(modifier, "Ctrl") == 0)
-        current_bar->modifier = M_CONTROL;
-    else if (strcmp(modifier, "Shift") == 0)
-        current_bar->modifier = M_SHIFT;
-    else if (strcmp(modifier, "none") == 0 ||
-             strcmp(modifier, "off") == 0)
-        current_bar->modifier = M_NONE;
+CFGFUN(bar_modifier, const char *modifiers) {
+    current_bar->modifier = modifiers ? event_state_from_str(modifiers) : XCB_NONE;
 }
 
 static void bar_configure_binding(const char *button, const char *release, const char *command) {
@@ -633,7 +616,7 @@ CFGFUN(bar_start) {
     TAILQ_INIT(&(current_bar->bar_bindings));
     TAILQ_INIT(&(current_bar->tray_outputs));
     current_bar->tray_padding = 2;
-    current_bar->modifier = M_MOD4;
+    current_bar->modifier = XCB_KEY_BUT_MASK_MOD_4;
 }
 
 CFGFUN(bar_finish) {
index 25da16170129594f75416ec2bb76cc0ccec4f253..eebb576ef4cefa8899d04a04f92b179475f95026 100644 (file)
--- a/src/ipc.c
+++ b/src/ipc.c
@@ -656,32 +656,7 @@ static void dump_bar_config(yajl_gen gen, Barconfig *config) {
     }
 
     ystr("modifier");
-    switch (config->modifier) {
-        case M_NONE:
-            ystr("none");
-            break;
-        case M_CONTROL:
-            ystr("ctrl");
-            break;
-        case M_SHIFT:
-            ystr("shift");
-            break;
-        case M_MOD1:
-            ystr("Mod1");
-            break;
-        case M_MOD2:
-            ystr("Mod2");
-            break;
-        case M_MOD3:
-            ystr("Mod3");
-            break;
-        case M_MOD5:
-            ystr("Mod5");
-            break;
-        default:
-            ystr("Mod4");
-            break;
-    }
+    y(integer, config->modifier);
 
     dump_bar_bindings(gen, config);
 
index 194ef05c337efc76898d780eee8148f5fc9c9ca0..d5d4dcef1349c682371f653621c9610803d8857c 100644 (file)
@@ -949,8 +949,9 @@ int main(int argc, char *argv[]) {
     Barconfig *barconfig;
     TAILQ_FOREACH(barconfig, &barconfigs, configs) {
         char *command = NULL;
-        sasprintf(&command, "%s --bar_id=%s --socket=\"%s\"",
+        sasprintf(&command, "%s %s --bar_id=%s --socket=\"%s\"",
                   barconfig->i3bar_command ? barconfig->i3bar_command : "i3bar",
+                  barconfig->verbose ? "-V" : "",
                   barconfig->id, current_socketpath);
         LOG("Starting bar process: %s\n", command);
         start_application(command, true);
index 51219ba6a63cecd217af61406bb85115b67d9cbb..4146fd7975c1a9e2d393dfd5e00024d4d4208bc2 100644 (file)
@@ -28,7 +28,7 @@ is($nodes[0]->{border}, 'normal', 'border style normal');
 
 cmd 'border 1pixel';
 @nodes = @{get_ws_content($tmp)};
-is($nodes[0]->{border}, 'pixel', 'border style 1pixel');
+is($nodes[0]->{border}, 'pixel', 'border style pixel');
 is($nodes[0]->{current_border_width}, 1, 'border width = 1px');
 
 cmd 'border none';
@@ -48,7 +48,7 @@ is($nodes[0]->{current_border_width}, 0, 'border width = 0px');
 
 cmd 'border toggle';
 @nodes = @{get_ws_content($tmp)};
-is($nodes[0]->{border}, 'pixel', 'border style 1pixel');
+is($nodes[0]->{border}, 'pixel', 'border style pixel');
 is($nodes[0]->{current_border_width}, 1, 'border width = 1px');
 
 cmd 'border toggle';
@@ -56,4 +56,19 @@ cmd 'border toggle';
 is($nodes[0]->{border}, 'normal', 'border style back to normal');
 is($nodes[0]->{current_border_width}, 2, 'border width = 2px');
 
+cmd 'border toggle 10';
+@nodes = @{get_ws_content($tmp)};
+is($nodes[0]->{border}, 'none', 'border style back to none even with width argument');
+is($nodes[0]->{current_border_width}, 0, 'border width = 0px');
+
+cmd 'border toggle 10';
+@nodes = @{get_ws_content($tmp)};
+is($nodes[0]->{border}, 'pixel', 'border style pixel');
+is($nodes[0]->{current_border_width}, 10, 'border width = 10px');
+
+cmd 'border toggle 10';
+@nodes = @{get_ws_content($tmp)};
+is($nodes[0]->{border}, 'normal', 'border style back to normal');
+is($nodes[0]->{current_border_width}, 10, 'border width = 10px');
+
 done_testing;
index 25d13333fd81e9fa9d81a9a1ae67585c6035eae7..c6b67f35ac7a38db7a64118607041b4c40d9e0fe 100644 (file)
@@ -336,6 +336,50 @@ sync_with_i3;
 
 does_i3_live;
 
+###############################################################################
+# Given 'S' and 'M' where 'M' is a workspace and 'S' is on a different
+# workspace, then 'S' ends up as a tiling container on 'M'.
+###############################################################################
+
+fresh_workspace;
+$S = open_window;
+$target_ws = fresh_workspace;
+$M = $target_ws;
+cmd 'mark target';
+
+cmd '[id="' . $S->{id} . '"] move container to mark target';
+sync_with_i3;
+
+does_i3_live;
+
+($nodes, $focus) = get_ws_content($target_ws);
+is(@{$nodes}, 1, 'tiling container moved to the target workspace');
+
+###############################################################################
+# Given 'S' and 'M' where 'S' is a workspace and 'M' is a container on a
+# different workspace, then all the contents of workspace 'S' end up in 'M's
+# workspace.
+###############################################################################
+
+$S = fresh_workspace;
+cmd 'mark S';
+open_window;
+open_window;
+cmd 'splitv';
+open_window;
+open_floating_window;
+$target_ws = fresh_workspace;
+$M = open_window;
+cmd 'mark target';
+
+cmd '[con_mark=S] move container to mark target';
+sync_with_i3;
+
+($nodes, $focus) = get_ws_content($target_ws);
+is(@{$nodes}, 2, 'there is a window and a container with the contents of the original workspace');
+is($nodes->[0]->{window}, $M->{id}, 'M remains the first window');
+is(@{get_ws($target_ws)->{floating_nodes}}, 1, 'target workspace has the floating container');
+
 ###############################################################################
 
 done_testing;