From ff4950a1bbba27182c875e869b98acaa4f404c57 Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Wed, 12 Dec 2012 00:23:35 +0100 Subject: [PATCH 01/98] debian/changelog: add dummy entry for the next version --- debian/changelog | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/debian/changelog b/debian/changelog index dcb966ae..ebdfbcef 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +i3-wm (4.4.1-0) unstable; urgency=low + + * NOT YET RELEASED + + -- Michael Stapelberg Wed, 12 Dec 2012 00:23:32 +0100 + i3-wm (4.4-1) experimental; urgency=low * New upstream release From 61a5b9ddd4806cd65820717dd3d0e3fda8a68cba Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Fri, 14 Dec 2012 21:44:20 +0100 Subject: [PATCH 02/98] Revert "don't use con_is_internal" This reverts commit c6948c59f592aa5ca0c2d81ff7ac1368a253c353. Given that master and next now both contain con_is_internal, we can use it again. --- src/workspace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/workspace.c b/src/workspace.c index 4ccf421c..5a0913bf 100644 --- a/src/workspace.c +++ b/src/workspace.c @@ -397,7 +397,7 @@ static void _workspace_show(Con *workspace) { * the corresponding workspace is cleaned up. * NOTE: Internal cons such as __i3_scratch (when a scratchpad window is * focused) are skipped, see bug #868. */ - if (current && !(current->name[0] == '_' && current->name[1] == '_')) { + if (current && !con_is_internal(current)) { FREE(previous_workspace_name); if (current) { previous_workspace_name = sstrdup(current->name); From 4273db04445046499f6e259678665b917498d29b Mon Sep 17 00:00:00 2001 From: Axel Wagner Date: Fri, 14 Dec 2012 01:27:34 +0100 Subject: [PATCH 03/98] i3-dump-log: Correct comment to reflect truth --- i3-dump-log/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/i3-dump-log/main.c b/i3-dump-log/main.c index 48465c75..4a11d218 100644 --- a/i3-dump-log/main.c +++ b/i3-dump-log/main.c @@ -121,7 +121,7 @@ int main(int argc, char *argv[]) { struct stat statbuf; - /* NB: While we must never read, we need O_RDWR for the pthread condvar. */ + /* NB: While we must never write, we need O_RDWR for the pthread condvar. */ int logbuffer_shm = shm_open(shmname, O_RDWR, 0); if (logbuffer_shm == -1) err(EXIT_FAILURE, "Could not shm_open SHM segment for the i3 log (%s)", shmname); @@ -129,7 +129,7 @@ int main(int argc, char *argv[]) { if (fstat(logbuffer_shm, &statbuf) != 0) err(EXIT_FAILURE, "stat(%s)", shmname); - /* NB: While we must never read, we need O_RDWR for the pthread condvar. */ + /* NB: While we must never write, we need PROT_WRITE for the pthread condvar. */ logbuffer = mmap(NULL, statbuf.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, logbuffer_shm, 0); if (logbuffer == MAP_FAILED) err(EXIT_FAILURE, "Could not mmap SHM segment for the i3 log"); From 3ca82996372cd9fddc00dd060b86f74f3936395f Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Thu, 20 Dec 2012 23:50:50 +0100 Subject: [PATCH 04/98] complete-run: clarify the message about missing ../i3 (Thanks Marcos) --- testcases/complete-run.pl | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/testcases/complete-run.pl b/testcases/complete-run.pl index b8121802..560dd4c3 100755 --- a/testcases/complete-run.pl +++ b/testcases/complete-run.pl @@ -1,10 +1,11 @@ #!/usr/bin/env perl # vim:ts=4:sw=4:expandtab -# © 2010-2011 Michael Stapelberg and contributors +# © 2010-2012 Michael Stapelberg and contributors package complete_run; use strict; use warnings; use v5.10; +use utf8; # the following are modules which ship with Perl (>= 5.10): use Pod::Usage; use Cwd qw(abs_path); @@ -29,6 +30,9 @@ use AnyEvent::I3 qw(:all); use X11::XCB::Connection; use JSON::XS; # AnyEvent::I3 depends on it, too. +binmode STDOUT, ':utf8'; +binmode STDERR, ':utf8'; + # Close superfluous file descriptors which were passed by running in a VIM # subshell or situations like that. AnyEvent::Util::close_all_fds_except(0, 1, 2); @@ -78,7 +82,7 @@ my @binaries = qw( ); foreach my $binary (@binaries) { - die "$binary executable not found" unless -e $binary; + die "$binary executable not found, did you run “make”?" unless -e $binary; die "$binary is not an executable" unless -x $binary; } From 5b8df2727058aa804e15da60da7520753216c1f0 Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Thu, 20 Dec 2012 23:54:48 +0100 Subject: [PATCH 05/98] userguide: s/mailclient/mail client/g (Thanks joepd) --- docs/userguide | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/userguide b/docs/userguide index 5880541c..58dcf9ac 100644 --- a/docs/userguide +++ b/docs/userguide @@ -1612,7 +1612,7 @@ bindsym $mod+r mode "resize" Often when in a multi-monitor environment, you want to quickly jump to a specific window. For example, while working on workspace 3 you may want to jump to your mail client to email your boss that you’ve achieved some -important goal. Instead of figuring out how to navigate to your mailclient, +important goal. Instead of figuring out how to navigate to your mail client, it would be more convenient to have a shortcut. You can use the +focus+ command with criteria for that. From b8939e6c9cb04e3903e78fe01aa7e3f2547ed815 Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Thu, 20 Dec 2012 23:56:17 +0100 Subject: [PATCH 06/98] hacking-howto: clarify where to send patches to (Thanks Vivien) --- docs/hacking-howto | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/hacking-howto b/docs/hacking-howto index 8a246efc..05fc9cbd 100644 --- a/docs/hacking-howto +++ b/docs/hacking-howto @@ -971,7 +971,8 @@ apply to the branch, preserving your commit message and name: git format-patch origin ----------------------- -Just send us the generated file via email. +Just send the generated file via email to the i3-discuss mailing list, see +http://i3wm.org/contact/ == Thought experiments From e0194f07653b7106aa5260e4d7b47ec0c6ab914f Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Fri, 21 Dec 2012 00:04:29 +0100 Subject: [PATCH 07/98] =?UTF-8?q?i3-dmenu-desktop:=20don=E2=80=99t=20add?= =?UTF-8?q?=20=E2=80=9Cgeany=E2=80=9D=20if=20=E2=80=9CGeany=E2=80=9D=20is?= =?UTF-8?q?=20already=20present=20(Thanks=20Tai-Lin=20Chu)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- i3-dmenu-desktop | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/i3-dmenu-desktop b/i3-dmenu-desktop index 20c7fbea..5bf77c2f 100755 --- a/i3-dmenu-desktop +++ b/i3-dmenu-desktop @@ -35,7 +35,7 @@ my $result = GetOptions( 'dmenu=s' => \$dmenu_cmd, 'entry-type=s' => \$entry_type, 'version' => sub { - say "dmenu-desktop 1.2 © 2012 Michael Stapelberg"; + say "dmenu-desktop 1.3 © 2012 Michael Stapelberg"; exit 0; }, 'help' => sub { @@ -250,6 +250,11 @@ for my $app (keys %apps) { if ($entry_type eq 'command' || $entry_type eq 'both') { my ($command) = split(' ', $apps{$app}->{Exec}); + + # Don’t add “geany” if “Geany” is already present. + my @keys = map { lc } keys %choices; + next if lc(basename($command)) ~~ @keys; + $choices{basename($command)} = $app; } } @@ -451,7 +456,7 @@ command) and both (type = both). =head1 VERSION -Version 1.2 +Version 1.3 =head1 AUTHOR From ff9c2f0c46a85b2bdf6a4c269ad37be82c9929d7 Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Sat, 22 Dec 2012 14:08:25 +0100 Subject: [PATCH 08/98] new-test: add launch_with_config to multi-monitor template --- testcases/new-test | 1 + 1 file changed, 1 insertion(+) diff --git a/testcases/new-test b/testcases/new-test index 2849301e..c2546158 100755 --- a/testcases/new-test +++ b/testcases/new-test @@ -79,6 +79,7 @@ font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1 fake-outputs 1024x768+0+0,1024x768+1024+0 EOT +my $pid = launch_with_config($config); exit_gracefully($pid); From 79bd2aede5aba10d7841db717e60736c90ffe130 Mon Sep 17 00:00:00 2001 From: Joep van Delft Date: Thu, 20 Dec 2012 18:32:11 +0100 Subject: [PATCH 09/98] Draw 1px tab separators left/right instead of 2px on the right only fixes #894 --- src/x.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/x.c b/src/x.c index 8f0ae37d..3a658a72 100644 --- a/src/x.c +++ b/src/x.c @@ -465,7 +465,7 @@ void x_draw_decoration(Con *con) { xcb_rectangle_t drect = { con->deco_rect.x, con->deco_rect.y, con->deco_rect.width, con->deco_rect.height }; xcb_poly_fill_rectangle(conn, parent->pixmap, parent->pm_gc, 1, &drect); - /* 5: draw two unconnected lines in border color */ + /* 5: draw two unconnected horizontal lines in border color */ xcb_change_gc(conn, parent->pm_gc, XCB_GC_FOREGROUND, (uint32_t[]){ p->color->border }); Rect *dr = &(con->deco_rect); int deco_diff_l = 2; @@ -539,19 +539,21 @@ after_title: * the right border again after rendering the text (and the unconnected * lines in border color). */ - /* Draw a separator line after every tab (except the last one), so that - * tabs can be easily distinguished. */ - if (parent->layout == L_TABBED && TAILQ_NEXT(con, nodes) != NULL) { + /* Draw a 1px separator line before and after every tab, so that tabs can + * be easily distinguished. */ + if (parent->layout == L_TABBED) { xcb_change_gc(conn, parent->pm_gc, XCB_GC_FOREGROUND, (uint32_t[]){ p->color->border }); } else { xcb_change_gc(conn, parent->pm_gc, XCB_GC_FOREGROUND, (uint32_t[]){ p->color->background }); } - xcb_poly_line(conn, XCB_COORD_MODE_ORIGIN, parent->pixmap, parent->pm_gc, 4, + xcb_poly_line(conn, XCB_COORD_MODE_ORIGIN, parent->pixmap, parent->pm_gc, 6, (xcb_point_t[]){ + { dr->x + dr->width, dr->y }, + { dr->x + dr->width, dr->y + dr->height }, { dr->x + dr->width - 1, dr->y }, { dr->x + dr->width - 1, dr->y + dr->height }, - { dr->x + dr->width - 2, dr->y }, - { dr->x + dr->width - 2, dr->y + dr->height } + { dr->x, dr->y + dr->height }, + { dr->x, dr->y }, }); xcb_change_gc(conn, parent->pm_gc, XCB_GC_FOREGROUND, (uint32_t[]){ p->color->border }); From 3a78d489e68305de08f3b86a5a470bd569deff85 Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Sun, 23 Dec 2012 15:54:49 +0100 Subject: [PATCH 10/98] Render tree before destroying X11 containers upon unmap (Thanks Merovius) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When an X11 window is closed (say, urxvt), i3 gets an UnmapNotify event and destroys (DestroyWindow) the window decorations. Before this commit, the DestroyWindow call was sent immediately. This lead to a situation where — due to the DestroyNotify — EnterNotify events were generated that would cause the focus to be set to the underlying window. With this commit, i3 first renders the tree and pushes changes to X11 before calling DestroyWindow. Therefore, the surrounding containers will take up any space that was freed by the window which was closed and no EnterNotify will be generated. fixes #660 --- src/tree.c | 45 +++++++++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/src/tree.c b/src/tree.c index 7a5fb9f0..c90f58f1 100644 --- a/src/tree.c +++ b/src/tree.c @@ -251,15 +251,29 @@ bool tree_close(Con *con, kill_window_t kill_window, bool dont_kill_parent, bool free(con->window); } - /* kill the X11 part of this container */ - x_con_kill(con); + Con *ws = con_get_workspace(con); + /* Figure out which container to focus next before detaching 'con'. */ + if (con_is_floating(con)) { + if (con == focused) { + DLOG("This is the focused container, i need to find another one to focus. I start looking at ws = %p\n", ws); + /* go down the focus stack as far as possible */ + next = con_next_focused(con); + + dont_kill_parent = true; + DLOG("Alright, focusing %p\n", next); + } else { + next = NULL; + } + } + + /* Detach the container so that it will not be rendered anymore. */ con_detach(con); /* disable urgency timer, if needed */ if (con->urgency_timer != NULL) { DLOG("Removing urgency timer of con %p\n", con); - workspace_update_urgent_flag(con_get_workspace(con)); + workspace_update_urgent_flag(ws); ev_timer_stop(main_loop, con->urgency_timer); FREE(con->urgency_timer); } @@ -270,21 +284,24 @@ bool tree_close(Con *con, kill_window_t kill_window, bool dont_kill_parent, bool con_fix_percent(parent); } + /* Render the tree so that the surrounding containers take up the space + * which 'con' does no longer occupy. If we don’t render here, there will + * be a gap in our containers and that could trigger an EnterNotify for an + * underlying container, see ticket #660. + * + * Rendering has to be avoided when dont_kill_parent is set (when + * tree_close calls itself recursively) because the tree is in a + * non-renderable state during that time. */ + if (!dont_kill_parent) + tree_render(); + + /* kill the X11 part of this container */ + x_con_kill(con); + if (con_is_floating(con)) { - Con *ws = con_get_workspace(con); DLOG("Container was floating, killing floating container\n"); tree_close(parent, DONT_KILL_WINDOW, false, (con == focused)); DLOG("parent container killed\n"); - if (con == focused) { - DLOG("This is the focused container, i need to find another one to focus. I start looking at ws = %p\n", ws); - /* go down the focus stack as far as possible */ - next = con_descend_focused(ws); - - dont_kill_parent = true; - DLOG("Alright, focusing %p\n", next); - } else { - next = NULL; - } } free(con->name); From 24aa857a89876474bac5209428abb389bc1a9a75 Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Sun, 23 Dec 2012 18:51:17 +0100 Subject: [PATCH 11/98] Bugfix: Correctly close floating windows (Thanks eeemsi) --- src/tree.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/tree.c b/src/tree.c index c90f58f1..c398ee1d 100644 --- a/src/tree.c +++ b/src/tree.c @@ -257,8 +257,7 @@ bool tree_close(Con *con, kill_window_t kill_window, bool dont_kill_parent, bool if (con_is_floating(con)) { if (con == focused) { DLOG("This is the focused container, i need to find another one to focus. I start looking at ws = %p\n", ws); - /* go down the focus stack as far as possible */ - next = con_next_focused(con); + next = con_next_focused(parent); dont_kill_parent = true; DLOG("Alright, focusing %p\n", next); From 5a567057abbd9b6acb8c440f9d81120e8bd6e5c6 Mon Sep 17 00:00:00 2001 From: Sascha Kruse Date: Mon, 10 Dec 2012 17:45:14 +0100 Subject: [PATCH 12/98] i3-dump-log/main.c: error handling for write(...) --- i3-dump-log/main.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/i3-dump-log/main.c b/i3-dump-log/main.c index 4a11d218..852a5cf7 100644 --- a/i3-dump-log/main.c +++ b/i3-dump-log/main.c @@ -42,14 +42,19 @@ static int check_for_wrap(void) { /* The log wrapped. Print the remaining content and reset walk to the top * of the log. */ wrap_count = header->wrap_count; - write(STDOUT_FILENO, walk, ((logbuffer + header->offset_last_wrap) - walk)); + const int len = (logbuffer + header->offset_last_wrap) - walk; + if (write(STDOUT_FILENO, walk, len) != len) + err(EXIT_FAILURE, "write()"); walk = logbuffer + sizeof(i3_shmlog_header); return 1; } static void print_till_end(void) { check_for_wrap(); - int n = write(STDOUT_FILENO, walk, ((logbuffer + header->offset_next_write) - walk)); + const int len = (logbuffer + header->offset_next_write) - walk; + const int n = write(STDOUT_FILENO, walk, len); + if (len != n) + err(EXIT_FAILURE, "write()"); if (n > 0) { walk += n; } From 9ae73b7a2adfb973cb72536e95d8311b0875b30c Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Mon, 24 Dec 2012 15:13:47 +0100 Subject: [PATCH 13/98] fix possibly uninitialized variable (Thanks knopwob) --- src/con.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/con.c b/src/con.c index ad5025a9..70c7d7f5 100644 --- a/src/con.c +++ b/src/con.c @@ -1573,6 +1573,10 @@ char *con_get_tree_representation(Con *con) { buf = sstrdup("T["); else if (con->layout == L_STACKED) buf = sstrdup("S["); + else { + ELOG("BUG: Code not updated to account for new layout type\n"); + assert(false); + } /* 2) append representation of children */ Con *child; From 56e0ceb44e0745b1670952be8f324783abdb28c5 Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Mon, 24 Dec 2012 15:19:20 +0100 Subject: [PATCH 14/98] initialize array to fix clang-analyze warning --- src/render.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/render.c b/src/render.c index 1216241b..c5cb76ba 100644 --- a/src/render.c +++ b/src/render.c @@ -201,7 +201,7 @@ void render_con(Con *con, bool render_fullscreen) { ++deco_height; /* precalculate the sizes to be able to correct rounding errors */ - int sizes[children]; + int sizes[children] = { 0 }; if ((con->layout == L_SPLITH || con->layout == L_SPLITV) && children > 0) { assert(!TAILQ_EMPTY(&con->nodes_head)); Con *child; From e11252a7afcbfef13856ad8724103812879e4dc6 Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Mon, 24 Dec 2012 15:27:09 +0100 Subject: [PATCH 15/98] =?UTF-8?q?pod2html:=20remove=20"(testsuite)"=20from?= =?UTF-8?q?=20title,=20it=E2=80=99s=20also=20for=20i3-dmenu-desktop?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/i3-pod2html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/i3-pod2html b/docs/i3-pod2html index 56a769f8..bda7e8d7 100755 --- a/docs/i3-pod2html +++ b/docs/i3-pod2html @@ -30,7 +30,7 @@ $parser->html_header_before_title( - +