]> git.sur5r.net Git - i3/i3/commitdiff
Merge pull request #1816 from tcreech/tcreech-for-illumos
authorMichael Stapelberg <stapelberg@users.noreply.github.com>
Tue, 4 Aug 2015 07:10:06 +0000 (00:10 -0700)
committerMichael Stapelberg <stapelberg@users.noreply.github.com>
Tue, 4 Aug 2015 07:10:06 +0000 (00:10 -0700)
Changes for compiling i3 on Illumos

47 files changed:
.travis.yml
CONTRIBUTING.md
RELEASE-NOTES-4.10.2 [deleted file]
RELEASE-NOTES-4.10.3 [new file with mode: 0644]
debian/changelog
i3-config-wizard/main.c
i3-input/main.c
i3-msg/main.c
i3-nagbar/main.c
i3-sensible-terminal
i3bar/src/child.c
i3bar/src/config.c
i3bar/src/xcb.c
include/libi3.h
libi3/fake_configure_notify.c
libi3/get_exe_path.c
libi3/resolve_tilde.c
libi3/root_atom_contents.c
libi3/safewrappers.c
libi3/string.c
libi3/ucs2_conversion.c
man/asciidoc.conf
release.sh
src/bindings.c
src/commands_parser.c
src/con.c
src/config.c
src/config_directives.c
src/config_parser.c
src/fake_outputs.c
src/handlers.c
src/ipc.c
src/load_layout.c
src/main.c
src/manage.c
src/randr.c
src/regex.c
src/restore_layout.c
src/startup.c
src/tree.c
src/util.c
src/window.c
src/workspace.c
src/x.c
src/xcb.c
src/xinerama.c
testcases/t/248-regress-urgency-clear.t [new file with mode: 0644]

index e3e45656b0509d618bad2228209ff8923745a76d..f90e0ebda99bc75ae0207df25082753d53b49ab7 100644 (file)
@@ -45,3 +45,22 @@ script:
   - CFLAGS="-Wformat -Wformat-security -Wextra -Wno-unused-parameter -Werror" make -j
   - (cd testcases && xvfb-run ./complete-run.pl --parallel=1 || (cat latest/complete-run.log; false))
   - clang-format-3.5 -i $(find . -name "*.[ch]" | tr '\n' ' ') && git diff --exit-code || (echo 'Code was not formatted using clang-format!'; false)
+  - |
+    funcs='malloc|calloc|realloc|strdup|strndup|asprintf|write'
+    cstring='"([^"\\]|\\.)*"'
+    cchar="'[^\\\\]'|'\\\\.[^']*'"
+    regex="^([^'\"]|${cstring}|${cchar})*\<(${funcs})\>"
+    detected=0
+    while IFS= read -r file; do
+        if { cpp -w -fpreprocessed "$file" || exit "$?"; } | grep -E -- "$regex"; then
+            echo "^ $file calls a function that has a safe counterpart."
+            detected=1
+        fi
+    done << EOF
+    $(find -name '*.c' -not -name safewrappers.c -not -name strndup.c)
+    EOF
+    if [ "$detected" -ne 0 ]; then
+        echo
+        echo "Calls of functions that have safe counterparts were detected."
+        exit 1
+    fi
index 39835c14f56a9cf3b552673c6e36fee17be31c85..474355ad90f7a98c5325ce584f0ce871bf4c719b 100644 (file)
@@ -1,12 +1,12 @@
-# i3status/i3lock bugreports/feature requests
+# Contributing
 
-Note that i3status and i3lock related bugreports and feature requests should be
-filed in the corresponding repositories, i.e. https://github.com/i3/i3status
-and https://github.com/i3/i3lock
+## i3status/i3lock bug reports and feature requests
 
-# i3 bugreports/feature requests
+Note that bug reports and feature requests for related projects should be filed in the corresponding repositories for [i3status](https://github.com/i3/i3status) and [i3lock](https://github.com/i3/i3lock).
 
-1. Read http://i3wm.org/docs/debugging.html
+## i3 bug reports and feature requests
+
+1. Read the [debugging instructions](http://i3wm.org/docs/debugging.html).
 2. Make sure you include a link to your logfile in your report (section 3).
 3. Make sure you include the i3 version number in your report (section 1).
 4. Please be aware that we cannot support compatibility issues with
@@ -15,16 +15,16 @@ and https://github.com/i3/i3lock
    experience has shown that often, the software in question is responsible for
    the issue. Please raise an issue with the software in question, not i3.
 
-# Pull requests
+## Pull requests
 
 * Before sending a pull request for new features, please check with us that the
   feature is something we want to see in i3 by opening an issue which has
-  â\80\9cfeature requestâ\80\9d or â\80\9cenhancement” in its title.
+  â\80\9dfeature requestâ\80\9d or â\80\9denhancement” in its title.
 * Use the `next` branch for developing and sending your pull request.
 * Use `clang-format` to format your code.
-* Run the testsuite, see http://i3wm.org/docs/testsuite.html
+* Run the [testsuite](http://i3wm.org/docs/testsuite.html)
 
-# Finding something to do
+## Finding something to do
 
 * Find a [reproducible bug](https://github.com/i3/i3/issues?utf8=%E2%9C%93&q=is%3Aopen+label%3Areproducible+label%3Abug+) from the issue tracker. These issues have been reviewed and confirmed by a project contributor.
 * Find an [accepted enhancement](https://github.com/i3/i3/issues?utf8=%E2%9C%93&q=is%3Aopen+label%3Aaccepted+label%3Aenhancement) from the issue tracker. These have been approved and are ok to start working on.
diff --git a/RELEASE-NOTES-4.10.2 b/RELEASE-NOTES-4.10.2
deleted file mode 100644 (file)
index 49c06e5..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-
- ┌──────────────────────────────┐
- │ Release notes for i3 v4.10.2 │
- └──────────────────────────────┘
-
-This is i3 v4.10.2. This version is considered stable. All users of i3 are
-strongly encouraged to upgrade.
-
- ┌────────────────────────────┐
- │ Bugfixes                   │
- └────────────────────────────┘
-
-  • Cope with non-null-terminated x class properties.
-  • Get workspace name when renaming current workspace (fixes crash).
-  • Use a reasonable default sep_block_width if a separator_symbol is given.
-  • Remove windows from the save set when unmapping.
-
- ┌────────────────────────────┐
- │ Thanks!                    │
- └────────────────────────────┘
-
-Thanks for testing, bugfixes, discussions and everything I forgot go out to:
-
-  Ingo Bürk, Michael Hofmann,
-
--- Michael Stapelberg, 2015-04-16
diff --git a/RELEASE-NOTES-4.10.3 b/RELEASE-NOTES-4.10.3
new file mode 100644 (file)
index 0000000..524f552
--- /dev/null
@@ -0,0 +1,30 @@
+
+ ┌──────────────────────────────┐
+ │ Release notes for i3 v4.10.3 │
+ └──────────────────────────────┘
+
+This is i3 v4.10.3. This version is considered stable. All users of i3 are
+strongly encouraged to upgrade.
+
+ ┌────────────────────────────┐
+ │ Bugfixes                   │
+ └────────────────────────────┘
+
+  • serialize con_id with %p in run_binding() (For FreeBSD)
+  • ignore InputHint when not in WM_HINTS (fixes e.g. mupdf focus)
+  • disable physically disconnect RandR outputs
+  • initialize workspace rect to the output's upon creation
+  • userguide: quoted strings need to be used, escaping isn’t possible
+  • mkdirp: do not throw an error if directory exists (fixes layout loss for
+    in-place restarts)
+  • i3bar: fix freeing static strings
+
+ ┌────────────────────────────┐
+ │ Thanks!                    │
+ └────────────────────────────┘
+
+Thanks for testing, bugfixes, discussions and everything I forgot go out to:
+
+  Tony Crisci, Deiz, Theo Buehler, shdown
+
+-- Michael Stapelberg, 2015-07-30
index 023eeac10b6e000570cfc0c624f2ca04c1248cd9..96b7fd2379595a99934fb5210e934f59cb745a28 100644 (file)
@@ -1,8 +1,22 @@
-i3-wm (4.10.3-1) experimental; urgency=medium
+i3-wm (4.10.4-1) unstable; urgency=medium
 
   * NOT YET RELEASED.
 
- -- Michael Stapelberg <stapelberg@debian.org>  Thu, 16 Apr 2015 09:08:30 +0200
+ -- Michael Stapelberg <stapelberg@debian.org>  Thu, 30 Jul 2015 22:30:45 +0200
+
+i3-wm (4.10.3-1) unstable; urgency=medium
+
+  * New upstream release.
+
+ -- Michael Stapelberg <stapelberg@debian.org>  Thu, 30 Jul 2015 21:51:27 +0200
+
+i3-wm (4.10.2-2) unstable; urgency=medium
+
+  * New upstream release.
+  * experimental to unstable because i3-wm 4.10.2-1 was only in experimental
+    due to the freeze.
+
+ -- Michael Stapelberg <stapelberg@debian.org>  Fri, 01 May 2015 20:21:18 +0200
 
 i3-wm (4.10.2-1) experimental; urgency=medium
 
index 9b8a486d5183404cfe26d93e0d01ac63547af37c..bd12cd815af594191df3e2f7c60f958d2a4bfbfc 100644 (file)
@@ -392,7 +392,7 @@ static char *rewrite_binding(const char *input) {
                     }
                 }
                 if (walk != beginning) {
-                    char *str = scalloc(walk - beginning + 1);
+                    char *str = scalloc(walk - beginning + 1, 1);
                     /* We copy manually to handle escaping of characters. */
                     int inpos, outpos;
                     for (inpos = 0, outpos = 0;
@@ -768,7 +768,7 @@ int main(int argc, char *argv[]) {
         switch (o) {
             case 's':
                 FREE(socket_path);
-                socket_path = strdup(optarg);
+                socket_path = sstrdup(optarg);
                 break;
             case 'v':
                 printf("i3-config-wizard " I3_VERSION "\n");
index 6736aad3a97052e3d671029275b9510c28935860..cf3884e9b40e9874b697789bbd52d4568b99abd5 100644 (file)
@@ -103,7 +103,7 @@ static void restore_input_focus(void) {
  *
  */
 static uint8_t *concat_strings(char **glyphs, int max) {
-    uint8_t *output = calloc(max + 1, 4);
+    uint8_t *output = scalloc(max + 1, 4);
     uint8_t *walk = output;
     for (int c = 0; c < max; c++) {
         printf("at %c\n", glyphs[c][0]);
@@ -187,10 +187,10 @@ static void finish_input() {
 
     /* allocate space for the output */
     int inputlen = strlen(command);
-    char *full = calloc(1,
-                        strlen(format) - (2 * cnt) /* format without all %s */
-                            + (inputlen * cnt)     /* replaced %s */
-                            + 1);                  /* trailing NUL */
+    char *full = scalloc(strlen(format) - (2 * cnt) /* format without all %s */
+                             + (inputlen * cnt)     /* replaced %s */
+                             + 1,                   /* trailing NUL */
+                         1);
     char *dest = full;
     for (c = 0; c < len; c++) {
         /* if this is not % or it is % but without a following 's',
@@ -359,7 +359,7 @@ free_resources:
 }
 
 int main(int argc, char *argv[]) {
-    format = strdup("%s");
+    format = sstrdup("%s");
     socket_path = getenv("I3SOCK");
     char *pattern = sstrdup("pango:monospace 8");
     int o, option_index = 0;
@@ -381,7 +381,7 @@ int main(int argc, char *argv[]) {
         switch (o) {
             case 's':
                 FREE(socket_path);
-                socket_path = strdup(optarg);
+                socket_path = sstrdup(optarg);
                 break;
             case 'v':
                 printf("i3-input " I3_VERSION);
@@ -401,11 +401,11 @@ int main(int argc, char *argv[]) {
                 break;
             case 'f':
                 FREE(pattern);
-                pattern = strdup(optarg);
+                pattern = sstrdup(optarg);
                 break;
             case 'F':
                 FREE(format);
-                format = strdup(optarg);
+                format = sstrdup(optarg);
                 break;
             case 'h':
                 printf("i3-input " I3_VERSION "\n");
index 6a6186d8288d6e71679742f7ee90a2b92f34260e..47e7ae91e681e583f039d31b4e1ce83654fe44c4 100644 (file)
@@ -77,7 +77,7 @@ static int reply_boolean_cb(void *params, int val) {
 }
 
 static int reply_string_cb(void *params, const unsigned char *val, size_t len) {
-    char *str = scalloc(len + 1);
+    char *str = scalloc(len + 1, 1);
     strncpy(str, (const char *)val, len);
     if (strcmp(last_key, "error") == 0)
         last_reply.error = str;
@@ -105,7 +105,7 @@ static int reply_end_map_cb(void *params) {
 
 static int reply_map_key_cb(void *params, const unsigned char *keyVal, size_t keyLen) {
     free(last_key);
-    last_key = scalloc(keyLen + 1);
+    last_key = scalloc(keyLen + 1, 1);
     strncpy(last_key, (const char *)keyVal, keyLen);
     return 1;
 }
@@ -187,8 +187,7 @@ int main(int argc, char *argv[]) {
             payload = sstrdup(argv[optind]);
         } else {
             char *both;
-            if (asprintf(&both, "%s %s", payload, argv[optind]) == -1)
-                err(EXIT_FAILURE, "asprintf");
+            sasprintf(&both, "%s %s", payload, argv[optind]);
             free(payload);
             payload = both;
         }
index aca70ab115efd4c2021a81b37dff41068f3db26b..d86cd69a3f984f15f80012117b868d168f06ef3b 100644 (file)
@@ -371,7 +371,7 @@ int main(int argc, char *argv[]) {
     if (argv0_len > strlen(".nagbar_cmd") &&
         strcmp(argv[0] + argv0_len - strlen(".nagbar_cmd"), ".nagbar_cmd") == 0) {
         unlink(argv[0]);
-        cmd = strdup(argv[0]);
+        cmd = sstrdup(argv[0]);
         *(cmd + argv0_len - strlen(".nagbar_cmd")) = '\0';
         execl("/bin/sh", "/bin/sh", cmd, NULL);
         err(EXIT_FAILURE, "execv(/bin/sh, /bin/sh, %s)", cmd);
@@ -418,7 +418,7 @@ int main(int argc, char *argv[]) {
                 printf("i3-nagbar [-m <message>] [-b <button> <action>] [-t warning|error] [-f <font>] [-v]\n");
                 return 0;
             case 'b':
-                buttons = realloc(buttons, sizeof(button_t) * (buttoncnt + 1));
+                buttons = srealloc(buttons, sizeof(button_t) * (buttoncnt + 1));
                 buttons[buttoncnt].label = i3string_from_utf8(optarg);
                 buttons[buttoncnt].action = argv[optind];
                 printf("button with label *%s* and action *%s*\n",
index 6e05ce363e5d2bcd6b45c8aaaf3703225d3879b6..c80e5ee211b785e1f4dc59efc4501c73d5b44bcb 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 terminator Eterm aterm xterm gnome-terminal roxterm xfce4-terminal termite lxterminal mate-terminal; do
+for terminal in $TERMINAL x-terminal-emulator urxvt rxvt terminator Eterm aterm xterm gnome-terminal roxterm xfce4-terminal termite lxterminal mate-terminal terminology; do
     if command -v $terminal > /dev/null 2>&1; then
         exec $terminal "$@"
     fi
index e369c54deb190a0e3651c34e0fb3cab7e1d5525c..cfc96d5f1ad2d4841f39ceb39480e235fb93cb26 100644 (file)
@@ -105,13 +105,13 @@ __attribute__((format(printf, 1, 2))) static void set_statusline_error(const cha
     va_start(args, format);
     (void)vasprintf(&message, format, args);
 
-    struct status_block *err_block = scalloc(sizeof(struct status_block));
+    struct status_block *err_block = scalloc(1, sizeof(struct status_block));
     err_block->full_text = i3string_from_utf8("Error: ");
     err_block->name = sstrdup("error");
     err_block->color = sstrdup("red");
     err_block->no_separator = true;
 
-    struct status_block *message_block = scalloc(sizeof(struct status_block));
+    struct status_block *message_block = scalloc(1, sizeof(struct status_block));
     message_block->full_text = i3string_from_utf8(message);
     message_block->name = sstrdup("error_message");
     message_block->color = sstrdup("red");
@@ -220,21 +220,21 @@ static int stdin_string(void *context, const unsigned char *val, size_t len) {
         return 1;
     }
     if (strcasecmp(ctx->last_map_key, "min_width") == 0) {
-        char *copy = (char *)malloc(len + 1);
+        char *copy = (char *)smalloc(len + 1);
         strncpy(copy, (const char *)val, len);
         copy[len] = 0;
         ctx->block.min_width_str = copy;
         return 1;
     }
     if (strcasecmp(ctx->last_map_key, "name") == 0) {
-        char *copy = (char *)malloc(len + 1);
+        char *copy = (char *)smalloc(len + 1);
         strncpy(copy, (const char *)val, len);
         copy[len] = 0;
         ctx->block.name = copy;
         return 1;
     }
     if (strcasecmp(ctx->last_map_key, "instance") == 0) {
-        char *copy = (char *)malloc(len + 1);
+        char *copy = (char *)smalloc(len + 1);
         strncpy(copy, (const char *)val, len);
         copy[len] = 0;
         ctx->block.instance = copy;
@@ -433,7 +433,7 @@ void stdin_io_first_line_cb(struct ev_loop *loop, ev_io *watcher, int revents) {
     } else {
         /* In case of plaintext, we just add a single block and change its
          * full_text pointer later. */
-        struct status_block *new_block = scalloc(sizeof(struct status_block));
+        struct status_block *new_block = scalloc(1, sizeof(struct status_block));
         TAILQ_INSERT_TAIL(&statusline_head, new_block, blocks);
         read_flat_input((char *)buffer, rec);
     }
index 65447e7ecaa14bf0f11af8d634f262261c29c28f..0e2dd05a88d338400291f931558c7f875a47223c 100644 (file)
@@ -146,7 +146,7 @@ static int config_string_cb(void *params_, const unsigned char *val, size_t _len
      * users updating from that version and restarting i3bar before i3. */
     if (!strcmp(cur_key, "wheel_up_cmd")) {
         DLOG("wheel_up_cmd = %.*s\n", len, val);
-        binding_t *binding = scalloc(sizeof(binding_t));
+        binding_t *binding = scalloc(1, sizeof(binding_t));
         binding->input_code = 4;
         sasprintf(&(binding->command), "%.*s", len, val);
         TAILQ_INSERT_TAIL(&(config.bindings), binding, bindings);
@@ -157,7 +157,7 @@ static int config_string_cb(void *params_, const unsigned char *val, size_t _len
      * users updating from that version and restarting i3bar before i3. */
     if (!strcmp(cur_key, "wheel_down_cmd")) {
         DLOG("wheel_down_cmd = %.*s\n", len, val);
-        binding_t *binding = scalloc(sizeof(binding_t));
+        binding_t *binding = scalloc(1, sizeof(binding_t));
         binding->input_code = 5;
         sasprintf(&(binding->command), "%.*s", len, val);
         TAILQ_INSERT_TAIL(&(config.bindings), binding, bindings);
@@ -277,7 +277,7 @@ static int config_boolean_cb(void *params_, int val) {
 static int config_integer_cb(void *params_, long long val) {
     if (parsing_bindings) {
         if (strcmp(cur_key, "input_code") == 0) {
-            binding_t *binding = scalloc(sizeof(binding_t));
+            binding_t *binding = scalloc(1, sizeof(binding_t));
             binding->input_code = val;
             TAILQ_INSERT_TAIL(&(config.bindings), binding, bindings);
 
index f31d711a80a2b05a2d8d509cb0eb8ab308386395..f90bbceede5e51356204f85d1e9ceb38874606a7 100644 (file)
@@ -533,7 +533,7 @@ void handle_button(xcb_button_press_event_t *event) {
     }
 
     const size_t len = namelen + strlen("workspace \"\"") + 1;
-    char *buffer = scalloc(len + num_quotes);
+    char *buffer = scalloc(len + num_quotes, 1);
     strncpy(buffer, "workspace \"", strlen("workspace \""));
     size_t inpos, outpos;
     for (inpos = 0, outpos = strlen("workspace \"");
@@ -730,7 +730,7 @@ static void handle_client_message(xcb_client_message_event_t *event) {
                                  values);
 
             /* send the XEMBED_EMBEDDED_NOTIFY message */
-            void *event = scalloc(32);
+            void *event = scalloc(32, 1);
             xcb_client_message_event_t *ev = event;
             ev->response_type = XCB_CLIENT_MESSAGE;
             ev->window = client;
@@ -1654,8 +1654,7 @@ void reconfig_windows(bool redraw_bars) {
                                                "i3bar\0i3bar\0");
 
             char *name;
-            if (asprintf(&name, "i3bar for output %s", walk->name) == -1)
-                err(EXIT_FAILURE, "asprintf()");
+            sasprintf(&name, "i3bar for output %s", walk->name);
             xcb_void_cookie_t name_cookie;
             name_cookie = xcb_change_property(xcb_connection,
                                               XCB_PROP_MODE_REPLACE,
index 971e565e3f1209a3073a3cfc0092aed567298c5b..9e7ef133fb4ca3ce49d253fa2956adcec57186b7 100644 (file)
@@ -113,7 +113,7 @@ void *smalloc(size_t size);
  * there is no more memory available)
  *
  */
-void *scalloc(size_t size);
+void *scalloc(size_t num, size_t size);
 
 /**
  * Safe-wrapper around realloc which exits if realloc returns NULL (meaning
index 225577a44017157d001323b29d9fb77b0329f535..2c4d4559848ffd23d10632ebea4219459117ef69 100644 (file)
@@ -23,7 +23,7 @@ void fake_configure_notify(xcb_connection_t *conn, xcb_rectangle_t r, xcb_window
     /* Every X11 event is 32 bytes long. Therefore, XCB will copy 32 bytes.
      * In order to properly initialize these bytes, we allocate 32 bytes even
      * though we only need less for an xcb_configure_notify_event_t */
-    void *event = scalloc(32);
+    void *event = scalloc(32, 1);
     xcb_configure_notify_event_t *generated_event = event;
 
     generated_event->event = window;
index fc9b3014d0f1a98c6d57349f744287efa8c474e3..ef8f23bc25a1915385647f96656a9d4586cb6494 100644 (file)
@@ -73,7 +73,7 @@ char *get_exe_path(const char *argv0) {
         }
         sasprintf(&path, ":%s", tmp);
     } else {
-        path = strdup(path);
+        path = sstrdup(path);
     }
     const char *component;
     char *str = path;
index 26cbabe5f1679cd38ff4f7ac88f220cca2fb7c26..7a4fb79bf3c2ddca62b9b9bf07a532f96c867f58 100644 (file)
@@ -34,7 +34,7 @@ char *resolve_tilde(const char *path) {
         err(EXIT_FAILURE, "glob() failed");
     } else {
         head = globbuf.gl_pathv[0];
-        result = scalloc(strlen(head) + (tail ? strlen(tail) : 0) + 1);
+        result = scalloc(strlen(head) + (tail ? strlen(tail) : 0) + 1, 1);
         strncpy(result, head, strlen(head));
         if (tail)
             strncat(result, tail, strlen(tail));
index df54ef093c5cd2c34ce417ee0ed7cfbb6f577d4d..d91f1e15b4ba10f21cc122c3798746354bae9476 100644 (file)
@@ -80,18 +80,10 @@ char *root_atom_contents(const char *atomname, xcb_connection_t *provided_conn,
     if (prop_reply->type == XCB_ATOM_CARDINAL) {
         /* We treat a CARDINAL as a >= 32-bit unsigned int. The only CARDINAL
          * we query is I3_PID, which is 32-bit. */
-        if (asprintf(&content, "%u", *((unsigned int *)xcb_get_property_value(prop_reply))) == -1) {
-            free(atom_reply);
-            free(prop_reply);
-            return NULL;
-        }
+        sasprintf(&content, "%u", *((unsigned int *)xcb_get_property_value(prop_reply)));
     } else {
-        if (asprintf(&content, "%.*s", xcb_get_property_value_length(prop_reply),
-                     (char *)xcb_get_property_value(prop_reply)) == -1) {
-            free(atom_reply);
-            free(prop_reply);
-            return NULL;
-        }
+        sasprintf(&content, "%.*s", xcb_get_property_value_length(prop_reply),
+                  (char *)xcb_get_property_value(prop_reply));
     }
     if (provided_conn == NULL)
         xcb_disconnect(conn);
index f5973cab982185f869d0ed6b39eaf0ea80b67235..0a233a1271f996272a50751c964e5ecf94b17015 100644 (file)
@@ -27,10 +27,10 @@ void *smalloc(size_t size) {
     return result;
 }
 
-void *scalloc(size_t size) {
-    void *result = calloc(size, 1);
+void *scalloc(size_t num, size_t size) {
+    void *result = calloc(num, size);
     if (result == NULL)
-        err(EXIT_FAILURE, "calloc(%zd)", size);
+        err(EXIT_FAILURE, "calloc(%zd, %zd)", num, size);
     return result;
 }
 
index 70244743283f33e9f8034682e1f2a01b26ce42a8..a7b8c6fc4f1a6be6917106423cb58616500d8b66 100644 (file)
@@ -33,7 +33,7 @@ struct _i3String {
  *
  */
 i3String *i3string_from_utf8(const char *from_utf8) {
-    i3String *str = scalloc(sizeof(i3String));
+    i3String *str = scalloc(1, sizeof(i3String));
 
     /* Get the text */
     str->utf8 = sstrdup(from_utf8);
@@ -64,10 +64,10 @@ i3String *i3string_from_markup(const char *from_markup) {
  *
  */
 i3String *i3string_from_utf8_with_length(const char *from_utf8, size_t num_bytes) {
-    i3String *str = scalloc(sizeof(i3String));
+    i3String *str = scalloc(1, sizeof(i3String));
 
     /* Copy the actual text to our i3String */
-    str->utf8 = scalloc(sizeof(char) * (num_bytes + 1));
+    str->utf8 = scalloc(num_bytes + 1, 1);
     strncpy(str->utf8, from_utf8, num_bytes);
     str->utf8[num_bytes] = '\0';
 
@@ -97,12 +97,11 @@ i3String *i3string_from_markup_with_length(const char *from_markup, size_t num_b
  *
  */
 i3String *i3string_from_ucs2(const xcb_char2b_t *from_ucs2, size_t num_glyphs) {
-    i3String *str = scalloc(sizeof(i3String));
+    i3String *str = scalloc(1, sizeof(i3String));
 
     /* Copy the actual text to our i3String */
-    size_t num_bytes = num_glyphs * sizeof(xcb_char2b_t);
-    str->ucs2 = scalloc(num_bytes);
-    memcpy(str->ucs2, from_ucs2, num_bytes);
+    str->ucs2 = scalloc(num_glyphs, sizeof(xcb_char2b_t));
+    memcpy(str->ucs2, from_ucs2, num_glyphs * sizeof(xcb_char2b_t));
 
     /* Store the length */
     str->num_glyphs = num_glyphs;
index 3a7d0194d45f5430ea4d783a897126f8e5f6f0eb..b583e32cd6a4f9ba667748d5bd423d994bb595c9 100644 (file)
@@ -23,8 +23,8 @@ static iconv_t ucs2_conversion_descriptor = (iconv_t)-1;
  */
 char *convert_ucs2_to_utf8(xcb_char2b_t *text, size_t num_glyphs) {
     /* Allocate the output buffer (UTF-8 is at most 4 bytes per glyph) */
-    size_t buffer_size = num_glyphs * 4 * sizeof(char) + 1;
-    char *buffer = scalloc(buffer_size);
+    size_t buffer_size = num_glyphs * 4 + 1;
+    char *buffer = scalloc(buffer_size, 1);
 
     /* We need to use an additional pointer, because iconv() modifies it */
     char *output = buffer;
index 9fbce99157e3087c7aa87b3e08c25959b27b1846..eda71d6e2c1e1041c9019dc1f3d5033529416efe 100644 (file)
@@ -7,7 +7,7 @@ template::[header-declarations]
 <refentrytitle>{mantitle}</refentrytitle>
 <manvolnum>{manvolnum}</manvolnum>
 <refmiscinfo class="source">i3</refmiscinfo>
-<refmiscinfo class="version">4.10.2</refmiscinfo>
+<refmiscinfo class="version">4.10.3</refmiscinfo>
 <refmiscinfo class="manual">i3 Manual</refmiscinfo>
 </refmeta>
 <refnamediv>
index 4dd027779ed03541710a0e3e055f929d23b7d827..1ca70754d25ec5eaa8118c0867063cad2360a660 100755 (executable)
@@ -1,8 +1,8 @@
 #!/bin/zsh
 # This script is used to prepare a new release of i3.
 
-export RELEASE_VERSION="4.10.2"
-export PREVIOUS_VERSION="4.10.1"
+export RELEASE_VERSION="4.10.3"
+export PREVIOUS_VERSION="4.10.2"
 export RELEASE_BRANCH="master"
 
 if [ ! -e "../i3.github.io" ]
@@ -12,6 +12,12 @@ then
        exit 1
 fi
 
+if ! (cd ../i3.github.io && git pull)
+then
+       echo "Could not update ../i3.github.io repository"
+       exit 1
+fi
+
 if [ ! -e "RELEASE-NOTES-${RELEASE_VERSION}" ]
 then
        echo "RELEASE-NOTES-${RELEASE_VERSION} not found."
@@ -74,12 +80,12 @@ if [ "${RELEASE_BRANCH}" = "master" ]; then
        git checkout master
        git merge --no-ff release-${RELEASE_VERSION} -m "Merge branch 'release-${RELEASE_VERSION}'"
        git checkout next
-       git merge --no-ff master -m "Merge branch 'master' into next"
+       git merge --no-ff -X ours master -m "Merge branch 'master' into next"
 else
        git checkout next
        git merge --no-ff release-${RELEASE_VERSION} -m "Merge branch 'release-${RELEASE_VERSION}'"
        git checkout master
-       git merge --no-ff next -m "Merge branch 'next' into master"
+       git merge --no-ff -X theirs next -m "Merge branch 'next' into master"
 fi
 
 git remote remove origin
@@ -98,6 +104,7 @@ mkdir debian
 # Copy over the changelog because we expect it to be locally modified in the
 # start directory.
 cp "${STARTDIR}/debian/changelog" i3/debian/changelog
+(cd i3 && git add debian/changelog && git commit -m 'Update debian/changelog')
 
 cat > ${TMPDIR}/Dockerfile <<EOT
 FROM debian:sid
@@ -147,7 +154,6 @@ git add downloads/i3-${RELEASE_VERSION}.tar.bz2*
 cp ${TMPDIR}/i3/RELEASE-NOTES-${RELEASE_VERSION} downloads/RELEASE-NOTES-${RELEASE_VERSION}.txt
 git add downloads/RELEASE-NOTES-${RELEASE_VERSION}.txt
 sed -i "s,<h2>Documentation for i3 v[^<]*</h2>,<h2>Documentation for i3 v${RELEASE_VERSION}</h2>,g" docs/index.html
-sed -i "s,Verify you are using i3 ≥ .*,Verify you are using i3 ≥ ${RELEASE_VERSION},g" docs/debugging.html
 sed -i "s,<span style=\"margin-left: 2em; color: #c0c0c0\">[^<]*</span>,<span style=\"margin-left: 2em; color: #c0c0c0\">${RELEASE_VERSION}</span>,g" index.html
 sed -i "s,The current stable version is .*$,The current stable version is ${RELEASE_VERSION}.,g" downloads/index.html
 sed -i "s,<tbody>,<tbody>\n  <tr>\n    <td>${RELEASE_VERSION}</td>\n    <td><a href=\"/downloads/i3-${RELEASE_VERSION}.tar.bz2\">i3-${RELEASE_VERSION}.tar.bz2</a></td>\n    <td>$(ls -lh ../i3/i3-${RELEASE_VERSION}.tar.bz2 | awk -F " " {'print $5'} | sed 's/K$/ KiB/g')</td>\n    <td><a href=\"/downloads/i3-${RELEASE_VERSION}.tar.bz2.asc\">signature</a></td>\n    <td>$(date +'%Y-%m-%d')</td>\n    <td><a href=\"/downloads/RELEASE-NOTES-${RELEASE_VERSION}.txt\">release notes</a></td>\n  </tr>\n,g" downloads/index.html
@@ -162,15 +168,17 @@ git commit -a -m "save docs for ${PREVIOUS_VERSION}"
 for i in $(find _docs -maxdepth 1 -and -type f -and \! -regex ".*\.\(html\|man\)$" -and \! -name "Makefile")
 do
        base="$(basename $i)"
-       [ -e "${STARTDIR}/docs/${base}" ] && cp "${STARTDIR}/docs/${base}" "_docs/${base}"
+       [ -e "${TMPDIR}/i3/docs/${base}" ] && cp "${TMPDIR}/i3/docs/${base}" "_docs/${base}"
 done
 
+sed -i "s,Verify you are using i3 ≥ .*,Verify you are using i3 ≥ ${RELEASE_VERSION},g" _docs/debugging
+
 (cd _docs && make)
 
 for i in $(find _docs -maxdepth 1 -and -type f -and \! -regex ".*\.\(html\|man\)$" -and \! -name "Makefile")
 do
        base="$(basename $i)"
-       [ -e "${STARTDIR}/docs/${base}" ] && cp "_docs/${base}.html" docs/
+       [ -e "${TMPDIR}/i3/docs/${base}" ] && cp "_docs/${base}.html" docs/
 done
 
 git commit -a -m "update docs for ${RELEASE_VERSION}"
@@ -222,5 +230,4 @@ echo ""
 echo "Announce on:"
 echo "  twitter"
 echo "  google+"
-echo "  mailing list"
 echo "  #i3 topic"
index 63ca0836a352a784f1c3de7da12bb71d61a8a85d..8e8e9febe8bee0f97926ec690090f4cc6f3e2b36 100644 (file)
@@ -33,9 +33,9 @@ static struct Mode *mode_from_name(const char *name) {
     }
 
     /* If the mode was not found, create a new one */
-    mode = scalloc(sizeof(struct Mode));
+    mode = scalloc(1, sizeof(struct Mode));
     mode->name = sstrdup(name);
-    mode->bindings = scalloc(sizeof(struct bindings_head));
+    mode->bindings = scalloc(1, sizeof(struct bindings_head));
     TAILQ_INIT(mode->bindings);
     SLIST_INSERT_HEAD(&modes, mode, modes);
 
@@ -51,7 +51,7 @@ static struct Mode *mode_from_name(const char *name) {
 Binding *configure_binding(const char *bindtype, const char *modifiers, const char *input_code,
                            const char *release, const char *border, const char *whole_window,
                            const char *command, const char *modename) {
-    Binding *new_binding = scalloc(sizeof(Binding));
+    Binding *new_binding = scalloc(1, sizeof(Binding));
     DLOG("bindtype %s, modifiers %s, input code %s, release %s\n", bindtype, modifiers, input_code, release);
     new_binding->release = (release != NULL ? B_UPON_KEYRELEASE : B_UPON_KEYPRESS);
     new_binding->border = (border != NULL);
@@ -393,9 +393,9 @@ static Binding *binding_copy(Binding *bind) {
     Binding *ret = smalloc(sizeof(Binding));
     *ret = *bind;
     if (bind->symbol != NULL)
-        ret->symbol = strdup(bind->symbol);
+        ret->symbol = sstrdup(bind->symbol);
     if (bind->command != NULL)
-        ret->command = strdup(bind->command);
+        ret->command = sstrdup(bind->command);
     if (bind->translated_to != NULL) {
         ret->translated_to = smalloc(sizeof(xcb_keycode_t) * bind->number_keycodes);
         memcpy(ret->translated_to, bind->translated_to, sizeof(xcb_keycode_t) * bind->number_keycodes);
index 9ae75abea21ff28a1fb53501ece991a2037e46d8..ffe416f04dd1c3659ff0aae5687f02269ee63700 100644 (file)
@@ -148,9 +148,9 @@ static TAILQ_HEAD(criteria_head, criterion) criteria =
  */
 static void push_criterion(void *unused_criteria, const char *type,
                            const char *value) {
-    struct criterion *criterion = malloc(sizeof(struct criterion));
-    criterion->type = strdup(type);
-    criterion->value = strdup(value);
+    struct criterion *criterion = smalloc(sizeof(struct criterion));
+    criterion->type = sstrdup(type);
+    criterion->value = sstrdup(value);
     TAILQ_INSERT_TAIL(&criteria, criterion, criteria);
 }
 
@@ -243,7 +243,7 @@ char *parse_string(const char **walk, bool as_word) {
     if (*walk == beginning)
         return NULL;
 
-    char *str = scalloc(*walk - beginning + 1);
+    char *str = scalloc(*walk - beginning + 1, 1);
     /* We copy manually to handle escaping of characters. */
     int inpos, outpos;
     for (inpos = 0, outpos = 0;
@@ -270,7 +270,7 @@ char *parse_string(const char **walk, bool as_word) {
 CommandResult *parse_command(const char *input, yajl_gen gen) {
     DLOG("COMMAND: *%s*\n", input);
     state = INITIAL;
-    CommandResult *result = scalloc(sizeof(CommandResult));
+    CommandResult *result = scalloc(1, sizeof(CommandResult));
 
     /* A YAJL JSON generator used for formatting replies. */
     command_output.json_gen = gen;
index 08c720015bd40b3099dc55fb55148fb4e7089214..3427013d2419c8caf52730c7310897a82c734826 100644 (file)
--- a/src/con.c
+++ b/src/con.c
@@ -36,7 +36,7 @@ void con_force_split_parents_redraw(Con *con) {
  *
  */
 Con *con_new_skeleton(Con *parent, i3Window *window) {
-    Con *new = scalloc(sizeof(Con));
+    Con *new = scalloc(1, sizeof(Con));
     new->on_remove_child = con_on_remove_child;
     TAILQ_INSERT_TAIL(&all_cons, new, all_cons);
     new->aspect_ratio = 0.0;
@@ -211,7 +211,7 @@ void con_focus(Con *con) {
      * checks before resetting the urgency.
      */
     if (con->urgent && con_is_leaf(con)) {
-        con->urgent = false;
+        con_set_urgency(con, false);
         con_update_parents_urgency(con);
         workspace_update_urgent_flag(con_get_workspace(con));
         ipc_send_window_event("urgent", con);
@@ -1722,13 +1722,13 @@ void con_update_parents_urgency(Con *con) {
  *
  */
 void con_set_urgency(Con *con, bool urgent) {
-    if (focused == con) {
+    if (urgent && focused == con) {
         DLOG("Ignoring urgency flag for current client\n");
-        con->window->urgent.tv_sec = 0;
-        con->window->urgent.tv_usec = 0;
         return;
     }
 
+    const bool old_urgent = con->urgent;
+
     if (con->urgency_timer == NULL) {
         con->urgent = urgent;
     } else
@@ -1752,7 +1752,7 @@ void con_set_urgency(Con *con, bool urgent) {
     if ((ws = con_get_workspace(con)) != NULL)
         workspace_update_urgent_flag(ws);
 
-    if (con->urgent == urgent) {
+    if (con->urgent != old_urgent) {
         LOG("Urgency flag changed to %d\n", con->urgent);
         ipc_send_window_event("urgent", con);
     }
index a931ba1f2de513d3e9d44a6e313e883a149cbd3f..b0c6f1a4f544beb2bd874ed1ef4205cfd3d2df3f 100644 (file)
@@ -58,7 +58,7 @@ bool parse_configuration(const char *override_configpath, bool use_nagbar) {
 
     /* initialize default bindings if we're just validating the config file */
     if (!use_nagbar && bindings == NULL) {
-        bindings = scalloc(sizeof(struct bindings_head));
+        bindings = scalloc(1, sizeof(struct bindings_head));
         TAILQ_INIT(bindings);
     }
 
@@ -155,9 +155,9 @@ void load_configuration(xcb_connection_t *conn, const char *override_configpath,
 
     SLIST_INIT(&modes);
 
-    struct Mode *default_mode = scalloc(sizeof(struct Mode));
+    struct Mode *default_mode = scalloc(1, sizeof(struct Mode));
     default_mode->name = sstrdup("default");
-    default_mode->bindings = scalloc(sizeof(struct bindings_head));
+    default_mode->bindings = scalloc(1, sizeof(struct bindings_head));
     TAILQ_INIT(default_mode->bindings);
     SLIST_INSERT_HEAD(&modes, default_mode, modes);
 
index 5b85012cbe6b8e7f0f7cf2ee849162f5080b45f5..6032dc11392911f17864819b7ecc4441a46259df 100644 (file)
@@ -242,7 +242,7 @@ CFGFUN(for_window, const char *command) {
         return;
     }
     DLOG("\t should execute command %s for the criteria mentioned above\n", command);
-    Assignment *assignment = scalloc(sizeof(Assignment));
+    Assignment *assignment = scalloc(1, sizeof(Assignment));
     assignment->type = A_COMMAND;
     match_copy(&(assignment->match), current_match);
     assignment->dest.command = sstrdup(command);
@@ -400,7 +400,7 @@ CFGFUN(workspace, const char *workspace, const char *output) {
         }
     }
     if (!duplicate) {
-        assignment = scalloc(sizeof(struct Workspace_Assignment));
+        assignment = scalloc(1, sizeof(struct Workspace_Assignment));
         assignment->name = sstrdup(workspace);
         assignment->output = sstrdup(output);
         TAILQ_INSERT_TAIL(&ws_assignments, assignment, ws_assignments);
@@ -458,7 +458,7 @@ CFGFUN(assign, const char *workspace) {
         return;
     }
     DLOG("New assignment, using above criteria, to workspace \"%s\".\n", workspace);
-    Assignment *assignment = scalloc(sizeof(Assignment));
+    Assignment *assignment = scalloc(1, sizeof(Assignment));
     match_copy(&(assignment->match), current_match);
     assignment->type = A_TO_WORKSPACE;
     assignment->dest.workspace = sstrdup(workspace);
@@ -472,7 +472,7 @@ CFGFUN(no_focus) {
     }
 
     DLOG("New assignment, using above criteria, to ignore focus on manage.\n");
-    Assignment *assignment = scalloc(sizeof(Assignment));
+    Assignment *assignment = scalloc(1, sizeof(Assignment));
     match_copy(&(assignment->match), current_match);
     assignment->type = A_NO_FOCUS;
     TAILQ_INSERT_TAIL(&assignments, assignment, assignments);
@@ -555,7 +555,7 @@ static void bar_configure_binding(const char *button, const char *command) {
         }
     }
 
-    struct Barbinding *new_binding = scalloc(sizeof(struct Barbinding));
+    struct Barbinding *new_binding = scalloc(1, sizeof(struct Barbinding));
     new_binding->input_code = input_code;
     new_binding->command = sstrdup(command);
     TAILQ_INSERT_TAIL(&(current_bar.bar_bindings), new_binding, bindings);
@@ -669,7 +669,7 @@ CFGFUN(bar_finish) {
 
     /* Copy the current (static) structure into a dynamically allocated
      * one, then cleanup our static one. */
-    Barconfig *bar_config = scalloc(sizeof(Barconfig));
+    Barconfig *bar_config = scalloc(1, sizeof(Barconfig));
     memcpy(bar_config, &current_bar, sizeof(Barconfig));
     TAILQ_INSERT_TAIL(&barconfigs, bar_config, configs);
 
index 9a0d19254db4d2c7d349054bdf351c8a96d24b11..6393efe913aa209ba9332b059a24f5be765f1d11 100644 (file)
@@ -202,9 +202,9 @@ static TAILQ_HEAD(criteria_head, criterion) criteria =
  */
 static void push_criterion(void *unused_criteria, const char *type,
                            const char *value) {
-    struct criterion *criterion = malloc(sizeof(struct criterion));
-    criterion->type = strdup(type);
-    criterion->value = strdup(value);
+    struct criterion *criterion = smalloc(sizeof(struct criterion));
+    criterion->type = sstrdup(type);
+    criterion->value = sstrdup(value);
     TAILQ_INSERT_TAIL(&criteria, criterion, criteria);
 }
 
@@ -414,7 +414,7 @@ struct ConfigResultIR *parse_config(const char *input, struct context *context)
                     }
                 }
                 if (walk != beginning) {
-                    char *str = scalloc(walk - beginning + 1);
+                    char *str = scalloc(walk - beginning + 1, 1);
                     /* We copy manually to handle escaping of characters. */
                     int inpos, outpos;
                     for (inpos = 0, outpos = 0;
@@ -519,7 +519,7 @@ struct ConfigResultIR *parse_config(const char *input, struct context *context)
 
             /* Contains the same amount of characters as 'input' has, but with
              * the unparseable part highlighted using ^ characters. */
-            char *position = scalloc(strlen(error_line) + 1);
+            char *position = scalloc(strlen(error_line) + 1, 1);
             const char *copywalk;
             for (copywalk = error_line;
                  *copywalk != '\n' && *copywalk != '\r' && *copywalk != '\0';
@@ -789,12 +789,12 @@ static char *migrate_config(char *input, off_t size) {
 
     /* read the script’s output */
     int conv_size = 65535;
-    char *converted = malloc(conv_size);
+    char *converted = smalloc(conv_size);
     int read_bytes = 0, ret;
     do {
         if (read_bytes == conv_size) {
             conv_size += 65535;
-            converted = realloc(converted, conv_size);
+            converted = srealloc(converted, conv_size);
         }
         ret = read(readpipe[0], converted + read_bytes, conv_size - read_bytes);
         if (ret == -1) {
@@ -849,7 +849,7 @@ bool parse_file(const char *f, bool use_nagbar) {
     if (fstat(fd, &stbuf) == -1)
         die("Could not fstat file: %s\n", strerror(errno));
 
-    buf = scalloc((stbuf.st_size + 1) * sizeof(char));
+    buf = scalloc(stbuf.st_size + 1, 1);
 
     if ((fstr = fdopen(fd, "r")) == NULL)
         die("Could not fdopen: %s\n", strerror(errno));
@@ -897,7 +897,7 @@ bool parse_file(const char *f, bool use_nagbar) {
             while (*v_value == '\t' || *v_value == ' ')
                 v_value++;
 
-            struct Variable *new = scalloc(sizeof(struct Variable));
+            struct Variable *new = scalloc(1, sizeof(struct Variable));
             new->key = sstrdup(v_key);
             new->value = sstrdup(v_value);
             SLIST_INSERT_HEAD(&variables, new, variables);
@@ -931,7 +931,7 @@ bool parse_file(const char *f, bool use_nagbar) {
     /* Then, allocate a new buffer and copy the file over to the new one,
      * but replace occurences of our variables */
     char *walk = buf, *destwalk;
-    char *new = smalloc((stbuf.st_size + extra_bytes + 1) * sizeof(char));
+    char *new = smalloc(stbuf.st_size + extra_bytes + 1);
     destwalk = new;
     while (walk < (buf + stbuf.st_size)) {
         /* Find the next variable */
@@ -990,7 +990,7 @@ bool parse_file(const char *f, bool use_nagbar) {
         }
     }
 
-    context = scalloc(sizeof(struct context));
+    context = scalloc(1, sizeof(struct context));
     context->filename = f;
 
     struct ConfigResultIR *config_output = parse_config(new, context);
index b4f92cd404f78f4048ee0ad789e4100c84983f30..3df0e246a28661a0d0a0d29504928442bbeff3ef 100644 (file)
@@ -49,7 +49,7 @@ void fake_outputs_init(const char *output_spec) {
             new_output->rect.width = min(new_output->rect.width, width);
             new_output->rect.height = min(new_output->rect.height, height);
         } else {
-            new_output = scalloc(sizeof(Output));
+            new_output = scalloc(1, sizeof(Output));
             sasprintf(&(new_output->name), "fake-%d", num_screens);
             DLOG("Created new fake output %s (%p)\n", new_output->name, new_output);
             new_output->active = true;
index d7d48a1cfb5847c9cfcf5c1ce728717d495925d1..49636543e1e63359674320f9f2191e41e29ca5c4 100644 (file)
@@ -760,7 +760,7 @@ static void handle_client_message(xcb_client_message_event_t *event) {
         uint32_t rnd = event->data.data32[1];
         DLOG("[i3 sync protocol] Sending random value %d back to X11 window 0x%08x\n", rnd, window);
 
-        void *reply = scalloc(32);
+        void *reply = scalloc(32, 1);
         xcb_client_message_event_t *ev = reply;
 
         ev->response_type = XCB_CLIENT_MESSAGE;
@@ -1319,7 +1319,9 @@ static void property_notify(uint8_t state, xcb_window_t window, xcb_atom_t atom)
  *
  */
 void handle_event(int type, xcb_generic_event_t *event) {
-    DLOG("event type %d, xkb_base %d\n", type, xkb_base);
+    if (type != XCB_MOTION_NOTIFY)
+        DLOG("event type %d, xkb_base %d\n", type, xkb_base);
+
     if (randr_base > -1 &&
         type == randr_base + XCB_RANDR_SCREEN_CHANGE_NOTIFY) {
         handle_screen_change(event);
index 4af78ab2762a47cd22c75d58e919cf4eec16238e..021bdd7bf1b2f57e5c989a807866d43232c1d43c 100644 (file)
--- a/src/ipc.c
+++ b/src/ipc.c
@@ -84,7 +84,7 @@ void ipc_shutdown(void) {
 IPC_HANDLER(command) {
     /* To get a properly terminated buffer, we copy
      * message_size bytes out of the buffer */
-    char *command = scalloc(message_size + 1);
+    char *command = scalloc(message_size + 1, 1);
     strncpy(command, (const char *)message, message_size);
     LOG("IPC: received: *%s*\n", command);
     yajl_gen gen = yajl_gen_alloc(NULL);
@@ -855,7 +855,7 @@ IPC_HANDLER(get_bar_config) {
 
     /* To get a properly terminated buffer, we copy
      * message_size bytes out of the buffer */
-    char *bar_id = scalloc(message_size + 1);
+    char *bar_id = scalloc(message_size + 1, 1);
     strncpy(bar_id, (const char *)message, message_size);
     LOG("IPC: looking for config for bar ID \"%s\"\n", bar_id);
     Barconfig *current, *config = NULL;
@@ -900,10 +900,10 @@ static int add_subscription(void *extra, const unsigned char *s,
     int event = client->num_events;
 
     client->num_events++;
-    client->events = realloc(client->events, client->num_events * sizeof(char *));
+    client->events = srealloc(client->events, client->num_events * sizeof(char *));
     /* We copy the string because it is not null-terminated and strndup()
      * is missing on some BSD systems */
-    client->events[event] = scalloc(len + 1);
+    client->events[event] = scalloc(len + 1, 1);
     memcpy(client->events[event], s, len);
 
     DLOG("client is now subscribed to:\n");
@@ -1060,13 +1060,13 @@ void ipc_new_client(EV_P_ struct ev_io *w, int revents) {
 
     set_nonblock(client);
 
-    struct ev_io *package = scalloc(sizeof(struct ev_io));
+    struct ev_io *package = scalloc(1, sizeof(struct ev_io));
     ev_io_init(package, ipc_receive_message, client, EV_READ);
     ev_io_start(EV_A_ package);
 
     DLOG("IPC: new client connected on fd %d\n", w->fd);
 
-    ipc_client *new = scalloc(sizeof(ipc_client));
+    ipc_client *new = scalloc(1, sizeof(ipc_client));
     new->fd = client;
 
     TAILQ_INSERT_TAIL(&all_clients, new, clients);
index e4c4531d3c82f7e4cbb5726b3cbebccfb92ad349..fa0d2e5a5cf6bb1da825dec6a54f605d694404e1 100644 (file)
@@ -167,7 +167,7 @@ static int json_end_array(void *ctx) {
 static int json_key(void *ctx, const unsigned char *val, size_t len) {
     LOG("key: %.*s\n", (int)len, val);
     FREE(last_key);
-    last_key = scalloc((len + 1) * sizeof(char));
+    last_key = scalloc(len + 1, 1);
     memcpy(last_key, val, len);
     if (strcasecmp(last_key, "swallows") == 0)
         parsing_swallows = true;
@@ -209,10 +209,10 @@ static int json_string(void *ctx, const unsigned char *val, size_t len) {
         free(sval);
     } else {
         if (strcasecmp(last_key, "name") == 0) {
-            json_node->name = scalloc((len + 1) * sizeof(char));
+            json_node->name = scalloc(len + 1, 1);
             memcpy(json_node->name, val, len);
         } else if (strcasecmp(last_key, "sticky_group") == 0) {
-            json_node->sticky_group = scalloc((len + 1) * sizeof(char));
+            json_node->sticky_group = scalloc(len + 1, 1);
             memcpy(json_node->sticky_group, val, len);
             LOG("sticky_group of this container is %s\n", json_node->sticky_group);
         } else if (strcasecmp(last_key, "orientation") == 0) {
@@ -361,7 +361,7 @@ static int json_int(void *ctx, long long val) {
         json_node->old_id = val;
 
     if (parsing_focus) {
-        struct focus_mapping *focus_mapping = scalloc(sizeof(struct focus_mapping));
+        struct focus_mapping *focus_mapping = scalloc(1, sizeof(struct focus_mapping));
         focus_mapping->old_id = val;
         TAILQ_INSERT_TAIL(&focus_mappings, focus_mapping, focus_mappings);
     }
index 4c5b5f18ced0aff76ae7b2838c89039dfe49673d..5281d19c74a3bba7e48f3b14f9571005887d6c9f 100644 (file)
@@ -635,7 +635,7 @@ int main(int argc, char *argv[]) {
     if (ipc_socket == -1) {
         ELOG("Could not create the IPC socket, IPC disabled\n");
     } else {
-        struct ev_io *ipc_io = scalloc(sizeof(struct ev_io));
+        struct ev_io *ipc_io = scalloc(1, sizeof(struct ev_io));
         ev_io_init(ipc_io, ipc_new_client, ipc_socket, EV_READ);
         ev_io_start(main_loop, ipc_io);
     }
@@ -663,7 +663,7 @@ int main(int argc, char *argv[]) {
                 ELOG("Could not disable FD_CLOEXEC on fd %d\n", fd);
             }
 
-            struct ev_io *ipc_io = scalloc(sizeof(struct ev_io));
+            struct ev_io *ipc_io = scalloc(1, sizeof(struct ev_io));
             ev_io_init(ipc_io, ipc_new_client, fd, EV_READ);
             ev_io_start(main_loop, ipc_io);
         }
@@ -679,9 +679,9 @@ int main(int argc, char *argv[]) {
     ewmh_update_desktop_names();
     ewmh_update_desktop_viewport();
 
-    struct ev_io *xcb_watcher = scalloc(sizeof(struct ev_io));
-    xcb_check = scalloc(sizeof(struct ev_check));
-    struct ev_prepare *xcb_prepare = scalloc(sizeof(struct ev_prepare));
+    struct ev_io *xcb_watcher = scalloc(1, sizeof(struct ev_io));
+    xcb_check = scalloc(1, sizeof(struct ev_check));
+    struct ev_prepare *xcb_prepare = scalloc(1, sizeof(struct ev_prepare));
 
     ev_io_init(xcb_watcher, xcb_got_event, xcb_get_file_descriptor(conn), EV_READ);
     ev_io_start(main_loop, xcb_watcher);
index 8dcc17a27cec45defa4d49b149823afff4ab6a29..002a7c78f5ab332a5def9974c76391a14dd7cefd 100644 (file)
@@ -164,7 +164,7 @@ void manage_window(xcb_window_t window, xcb_get_window_attributes_cookie_t cooki
 
     DLOG("Managing window 0x%08x\n", window);
 
-    i3Window *cwindow = scalloc(sizeof(i3Window));
+    i3Window *cwindow = scalloc(1, sizeof(i3Window));
     cwindow->id = window;
     cwindow->depth = get_visual_depth(attr->visual);
 
@@ -419,6 +419,17 @@ void manage_window(xcb_window_t window, xcb_get_window_attributes_cookie_t cooki
     if (cwindow->dock)
         want_floating = false;
 
+    /* Plasma windows set their geometry in WM_SIZE_HINTS. */
+    if ((wm_size_hints.flags & XCB_ICCCM_SIZE_HINT_US_POSITION || wm_size_hints.flags & XCB_ICCCM_SIZE_HINT_P_POSITION) &&
+        (wm_size_hints.flags & XCB_ICCCM_SIZE_HINT_US_SIZE || wm_size_hints.flags & XCB_ICCCM_SIZE_HINT_P_SIZE)) {
+        DLOG("We are setting geometry according to wm_size_hints x=%d y=%d w=%d h=%d\n",
+             wm_size_hints.x, wm_size_hints.y, wm_size_hints.width, wm_size_hints.height);
+        geom->x = wm_size_hints.x;
+        geom->y = wm_size_hints.y;
+        geom->width = wm_size_hints.width;
+        geom->height = wm_size_hints.height;
+    }
+
     /* Store the requested geometry. The width/height gets raised to at least
      * 75x50 when entering floating mode, which is the minimum size for a
      * window to be useful (smaller windows are usually overlays/toolbars/…
index 1bd9993164d946b455db95ba3a5b0fd31f2ef503..96f2f23368d7423415ff0904bfaa52dd8d5607b9 100644 (file)
@@ -227,7 +227,7 @@ Output *get_output_next(direction_t direction, Output *current, output_close_far
 void disable_randr(xcb_connection_t *conn) {
     DLOG("RandR extension unusable, disabling.\n");
 
-    Output *s = scalloc(sizeof(Output));
+    Output *s = scalloc(1, sizeof(Output));
 
     s->active = true;
     s->rect.x = 0;
@@ -292,7 +292,7 @@ void output_init_con(Output *output) {
     topdock->type = CT_DOCKAREA;
     topdock->layout = L_DOCKAREA;
     /* this container swallows dock clients */
-    Match *match = scalloc(sizeof(Match));
+    Match *match = scalloc(1, sizeof(Match));
     match_init(match);
     match->dock = M_DOCK_TOP;
     match->insert_where = M_BELOW;
@@ -326,7 +326,7 @@ void output_init_con(Output *output) {
     bottomdock->type = CT_DOCKAREA;
     bottomdock->layout = L_DOCKAREA;
     /* this container swallows dock clients */
-    match = scalloc(sizeof(Match));
+    match = scalloc(1, sizeof(Match));
     match_init(match);
     match->dock = M_DOCK_BOTTOM;
     match->insert_where = M_BELOW;
@@ -522,7 +522,7 @@ static void handle_output(xcb_connection_t *conn, xcb_randr_output_t id,
     Output *new = get_output_by_id(id);
     bool existing = (new != NULL);
     if (!existing)
-        new = scalloc(sizeof(Output));
+        new = scalloc(1, sizeof(Output));
     new->id = id;
     new->primary = (primary && primary->output == id);
     FREE(new->name);
index 9549a98b54ba36980fe956b8957e63d4e21f1c6b..913519bede31d826144bdb7e5272e9c92598d876 100644 (file)
@@ -25,7 +25,7 @@ struct regex *regex_new(const char *pattern) {
     const char *error;
     int errorcode, offset;
 
-    struct regex *re = scalloc(sizeof(struct regex));
+    struct regex *re = scalloc(1, sizeof(struct regex));
     re->pattern = sstrdup(pattern);
     int options = PCRE_UTF8;
 #ifdef PCRE_HAS_UCP
index f56372a690ac5427e140a05e2747fccc813234d1..439d23ccf43abbb33c47220724fc53a801c626eb 100644 (file)
@@ -109,9 +109,9 @@ void restore_connect(void) {
     if (restore_conn == NULL || xcb_connection_has_error(restore_conn))
         errx(EXIT_FAILURE, "Cannot open display\n");
 
-    xcb_watcher = scalloc(sizeof(struct ev_io));
-    xcb_check = scalloc(sizeof(struct ev_check));
-    xcb_prepare = scalloc(sizeof(struct ev_prepare));
+    xcb_watcher = scalloc(1, sizeof(struct ev_io));
+    xcb_check = scalloc(1, sizeof(struct ev_check));
+    xcb_prepare = scalloc(1, sizeof(struct ev_prepare));
 
     ev_io_init(xcb_watcher, restore_xcb_got_event, xcb_get_file_descriptor(restore_conn), EV_READ);
     ev_io_start(main_loop, xcb_watcher);
@@ -210,7 +210,7 @@ static void open_placeholder_window(Con *con) {
         DLOG("Created placeholder window 0x%08x for leaf container %p / %s\n",
              placeholder, con, con->name);
 
-        placeholder_state *state = scalloc(sizeof(placeholder_state));
+        placeholder_state *state = scalloc(1, sizeof(placeholder_state));
         state->window = placeholder;
         state->con = con;
         state->rect = con->rect;
index b062ea8ba0cb3af34d32d5a047dc5d84cdfeeb8f..400d319239ec6149df3c4d8046cd544c22faf9de 100644 (file)
@@ -149,7 +149,7 @@ void start_application(const char *command, bool no_startup_id) {
         free(first_word);
 
         /* Trigger a timeout after 60 seconds */
-        struct ev_timer *timeout = scalloc(sizeof(struct ev_timer));
+        struct ev_timer *timeout = scalloc(1, sizeof(struct ev_timer));
         ev_timer_init(timeout, startup_timeout, 60.0, 0.);
         timeout->data = context;
         ev_timer_start(main_loop, timeout);
@@ -159,7 +159,7 @@ void start_application(const char *command, bool no_startup_id) {
         /* Save the ID and current workspace in our internal list of startup
          * sequences */
         Con *ws = con_get_workspace(focused);
-        struct Startup_Sequence *sequence = scalloc(sizeof(struct Startup_Sequence));
+        struct Startup_Sequence *sequence = scalloc(1, sizeof(struct Startup_Sequence));
         sequence->id = sstrdup(sn_launcher_context_get_startup_id(context));
         sequence->workspace = sstrdup(ws->name);
         sequence->context = context;
@@ -316,14 +316,8 @@ struct Startup_Sequence *startup_sequence_get(i3Window *cwindow,
     }
 
     char *startup_id;
-    if (asprintf(&startup_id, "%.*s", xcb_get_property_value_length(startup_id_reply),
-                 (char *)xcb_get_property_value(startup_id_reply)) == -1) {
-        perror("asprintf()");
-        DLOG("Could not get _NET_STARTUP_ID\n");
-        free(startup_id_reply);
-        return NULL;
-    }
-
+    sasprintf(&startup_id, "%.*s", xcb_get_property_value_length(startup_id_reply),
+              (char *)xcb_get_property_value(startup_id_reply));
     struct Startup_Sequence *current, *sequence = NULL;
     TAILQ_FOREACH(current, &startup_sequences, sequences) {
         if (strcmp(current->id, startup_id) != 0)
index 92b56e6c310909afe95ea828a796f1b7d9e36259..1d06d87481bc42b53cecb9748db111d6f0348369 100644 (file)
@@ -202,7 +202,7 @@ bool tree_close(Con *con, kill_window_t kill_window, bool dont_kill_parent, bool
 
     /* remove the urgency hint of the workspace (if set) */
     if (con->urgent) {
-        con->urgent = false;
+        con_set_urgency(con, false);
         con_update_parents_urgency(con);
         workspace_update_urgent_flag(con_get_workspace(con));
     }
index 5568fc714c619ba70663e29a377f8e3557b4e8fd..0edd471a2c247b7448ee54392dcecc86a08ae4c1 100644 (file)
@@ -122,7 +122,7 @@ void exec_i3_utility(char *name, char *argv[]) {
     /* if the script is not in path, maybe the user installed to a strange
      * location and runs the i3 binary with an absolute path. We use
      * argv[0]’s dirname */
-    char *pathbuf = strdup(start_argv[0]);
+    char *pathbuf = sstrdup(start_argv[0]);
     char *dir = dirname(pathbuf);
     sasprintf(&migratepath, "%s/%s", dir, name);
     argv[0] = migratepath;
@@ -276,7 +276,7 @@ void i3_restart(bool forget_layout) {
         int num_args;
         for (num_args = 0; start_argv[num_args] != NULL; num_args++)
             ;
-        char **new_argv = scalloc((num_args + 3) * sizeof(char *));
+        char **new_argv = scalloc(num_args + 3, sizeof(char *));
 
         /* copy the arguments, but skip the ones we'll replace */
         int write_index = 0;
index dd04b1b9e822c851e56948775ef6e45364773de9..764cfca5a98267a2f6ae8467aebd9a6d025b66d3 100644 (file)
@@ -208,13 +208,8 @@ void window_update_role(i3Window *win, xcb_get_property_reply_t *prop, bool befo
     }
 
     char *new_role;
-    if (asprintf(&new_role, "%.*s", xcb_get_property_value_length(prop),
-                 (char *)xcb_get_property_value(prop)) == -1) {
-        perror("asprintf()");
-        DLOG("Could not get WM_WINDOW_ROLE\n");
-        free(prop);
-        return;
-    }
+    sasprintf(&new_role, "%.*s", xcb_get_property_value_length(prop),
+              (char *)xcb_get_property_value(prop));
     FREE(win->role);
     win->role = new_role;
     LOG("WM_WINDOW_ROLE changed to \"%s\"\n", win->role);
index 59d6d77c86f7cff8cb2c41f744ddf8d6c16d362a..70022151117c7392f1de4bff97ee8e776322e79e 100644 (file)
@@ -322,17 +322,17 @@ static void workspace_reassign_sticky(Con *con) {
 static void workspace_defer_update_urgent_hint_cb(EV_P_ ev_timer *w, int revents) {
     Con *con = w->data;
 
+    ev_timer_stop(main_loop, con->urgency_timer);
+    FREE(con->urgency_timer);
+
     if (con->urgent) {
         DLOG("Resetting urgency flag of con %p by timer\n", con);
-        con->urgent = false;
+        con_set_urgency(con, false);
         con_update_parents_urgency(con);
         workspace_update_urgent_flag(con_get_workspace(con));
         ipc_send_window_event("urgent", con);
         tree_render();
     }
-
-    ev_timer_stop(main_loop, con->urgency_timer);
-    FREE(con->urgency_timer);
 }
 
 static void _workspace_show(Con *workspace) {
@@ -397,7 +397,7 @@ static void _workspace_show(Con *workspace) {
         if (focused->urgency_timer == NULL) {
             DLOG("Deferring reset of urgency flag of con %p on newly shown workspace %p\n",
                  focused, workspace);
-            focused->urgency_timer = scalloc(sizeof(struct ev_timer));
+            focused->urgency_timer = scalloc(1, sizeof(struct ev_timer));
             /* use a repeating timer to allow for easy resets */
             ev_timer_init(focused->urgency_timer, workspace_defer_update_urgent_hint_cb,
                           config.workspace_urgency_timer, config.workspace_urgency_timer);
diff --git a/src/x.c b/src/x.c
index ef6c734162c0431bc6dad0ee7bb56d17e9c78788..cdfc0f2f9964742055b43f8a6ca1c6df59fc0e35 100644 (file)
--- a/src/x.c
+++ b/src/x.c
@@ -147,7 +147,7 @@ void x_con_init(Con *con, uint16_t depth) {
     if (win_colormap != XCB_NONE)
         xcb_free_colormap(conn, win_colormap);
 
-    struct con_state *state = scalloc(sizeof(struct con_state));
+    struct con_state *state = scalloc(1, sizeof(struct con_state));
     state->id = con->frame;
     state->mapped = false;
     state->initial = true;
@@ -286,7 +286,7 @@ void x_window_kill(xcb_window_t window, kill_window_t kill_window) {
     /* Every X11 event is 32 bytes long. Therefore, XCB will copy 32 bytes.
      * In order to properly initialize these bytes, we allocate 32 bytes even
      * though we only need less for an xcb_configure_notify_event_t */
-    void *event = scalloc(32);
+    void *event = scalloc(32, 1);
     xcb_client_message_event_t *ev = event;
 
     ev->response_type = XCB_CLIENT_MESSAGE;
@@ -376,7 +376,7 @@ void x_draw_decoration(Con *con) {
         return;
 
     /* 1: build deco_params and compare with cache */
-    struct deco_render_params *p = scalloc(sizeof(struct deco_render_params));
+    struct deco_render_params *p = scalloc(1, sizeof(struct deco_render_params));
 
     /* find out which colors to use */
     if (con->urgent)
index 303d6af1cf2c9b583fff8653bd69fe230e00e457..001f6b51958cf46651304d3644134a3c40e46ba2 100644 (file)
--- a/src/xcb.c
+++ b/src/xcb.c
@@ -114,7 +114,7 @@ void send_take_focus(xcb_window_t window, xcb_timestamp_t timestamp) {
     /* Every X11 event is 32 bytes long. Therefore, XCB will copy 32 bytes.
      * In order to properly initialize these bytes, we allocate 32 bytes even
      * though we only need less for an xcb_configure_notify_event_t */
-    void *event = scalloc(32);
+    void *event = scalloc(32, 1);
     xcb_client_message_event_t *ev = event;
 
     ev->response_type = XCB_CLIENT_MESSAGE;
index ec030230760b39f927e7a7fd3048c26d7bce6f3f..cae71fc2b0da8d155617ed9397c3b61c7b3d9170 100644 (file)
@@ -56,7 +56,7 @@ static void query_screens(xcb_connection_t *conn) {
             s->rect.width = min(s->rect.width, screen_info[screen].width);
             s->rect.height = min(s->rect.height, screen_info[screen].height);
         } else {
-            s = scalloc(sizeof(Output));
+            s = scalloc(1, sizeof(Output));
             sasprintf(&(s->name), "xinerama-%d", num_screens);
             DLOG("Created new Xinerama screen %s (%p)\n", s->name, s);
             s->active = true;
diff --git a/testcases/t/248-regress-urgency-clear.t b/testcases/t/248-regress-urgency-clear.t
new file mode 100644 (file)
index 0000000..10ef377
--- /dev/null
@@ -0,0 +1,69 @@
+#!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)
+#
+# Ensures the urgency hint is cleared properly in the case where i3 set it (due
+# to focus_on_window_activation=urgent), hence the application not clearing it.
+# Ticket: #1825
+# Bug still in: 4.10.3-253-g03799dd
+use i3test i3_autostart => 0;
+
+sub send_net_active_window {
+    my ($id) = @_;
+
+    my $msg = pack "CCSLLLLLLL",
+        X11::XCB::CLIENT_MESSAGE, # response_type
+        32, # format
+        0, # sequence
+        $id, # destination window
+        $x->atom(name => '_NET_ACTIVE_WINDOW')->id,
+        0, # source
+        0, 0, 0, 0;
+
+    $x->send_event(0, $x->get_root_window(), X11::XCB::EVENT_MASK_SUBSTRUCTURE_REDIRECT, $msg);
+}
+
+my $config = <<'EOT';
+# i3 config file (v4)
+font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
+
+focus_on_window_activation urgent
+EOT
+
+my $pid = launch_with_config($config);
+my $i3 = i3(get_socket_path(0));
+my $ws = fresh_workspace;
+my $first = open_window;
+my $second = open_window;
+
+send_net_active_window($first->id);
+sync_with_i3;
+is($x->input_focus, $second->id, 'second window still focused');
+
+cmd '[urgent=latest] focus';
+sync_with_i3;
+is($x->input_focus, $first->id, 'first window focused');
+
+cmd 'focus right';
+sync_with_i3;
+is($x->input_focus, $second->id, 'second window focused again');
+
+cmd '[urgent=latest] focus';
+sync_with_i3;
+is($x->input_focus, $second->id, 'second window still focused');
+
+exit_gracefully($pid);
+
+done_testing;