From 147d3c354abc7e322dbb10246824f4b6f52b97bd Mon Sep 17 00:00:00 2001 From: Alex Lu Date: Sun, 11 Feb 2018 19:05:43 +0800 Subject: [PATCH] Update EWMH atoms when closing a workspace container fix #3126 --- src/tree.c | 7 ++ testcases/t/294-update-ewmh-atoms.t | 111 ++++++++++++++++++++++++++++ 2 files changed, 118 insertions(+) create mode 100644 testcases/t/294-update-ewmh-atoms.t diff --git a/src/tree.c b/src/tree.c index b8bc732b..6c6a614e 100644 --- a/src/tree.c +++ b/src/tree.c @@ -330,6 +330,13 @@ bool tree_close_internal(Con *con, kill_window_t kill_window, bool dont_kill_par DLOG("parent container killed\n"); } + if (ws == con) { + DLOG("Closing a workspace container, updating EWMH atoms\n"); + ewmh_update_number_of_desktops(); + ewmh_update_desktop_names(); + ewmh_update_wm_desktop(); + } + con_free(con); /* in the case of floating windows, we already focused another container diff --git a/testcases/t/294-update-ewmh-atoms.t b/testcases/t/294-update-ewmh-atoms.t new file mode 100644 index 00000000..047cc119 --- /dev/null +++ b/testcases/t/294-update-ewmh-atoms.t @@ -0,0 +1,111 @@ +#!perl +# vim:ts=4:sw=4:expandtab +# +# Please read the following documents before working on tests: +# • https://build.i3wm.org/docs/testsuite.html +# (or docs/testsuite) +# +# • https://build.i3wm.org/docs/lib-i3test.html +# (alternatively: perldoc ./testcases/lib/i3test.pm) +# +# • https://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) +# +# Verifies _NET_DESKTOP_NAMES, _NET_CURRENT_DESKTOP and _NET_CURRENT_DESKTOP +# are updated properly when closing an inactive workspace container. +# See github issue #3126 + +use i3test; + +sub get_desktop_names { + sync_with_i3; + + my $cookie = $x->get_property( + 0, + $x->get_root_window(), + $x->atom(name => '_NET_DESKTOP_NAMES')->id, + $x->atom(name => 'UTF8_STRING')->id, + 0, + 4096, + ); + + my $reply = $x->get_property_reply($cookie->{sequence}); + + return 0 if $reply->{value_len} == 0; + + # the property is a null-delimited list of utf8 strings ;; + return split /\0/, $reply->{value}; +} + +sub get_num_of_desktops { + sync_with_i3; + + my $cookie = $x->get_property( + 0, + $x->get_root_window(), + $x->atom(name => '_NET_NUMBER_OF_DESKTOPS')->id, + $x->atom(name => 'CARDINAL')->id, + 0, + 4, + ); + + my $reply = $x->get_property_reply($cookie->{sequence}); + + return undef if $reply->{value_len} != 1; + return undef if $reply->{format} != 32; + return undef if $reply->{type} != $x->atom(name => 'CARDINAL')->id,; + + return unpack 'L', $reply->{value}; +} + +sub get_current_desktop { + sync_with_i3; + + my $cookie = $x->get_property( + 0, + $x->get_root_window(), + $x->atom(name => '_NET_CURRENT_DESKTOP')->id, + $x->atom(name => 'CARDINAL')->id, + 0, + 4, + ); + + my $reply = $x->get_property_reply($cookie->{sequence}); + + return undef if $reply->{value_len} != 1; + return undef if $reply->{format} != 32; + return undef if $reply->{type} != $x->atom(name => 'CARDINAL')->id,; + + return unpack 'L', $reply->{value}; +} + +cmd 'workspace 0'; +my $first = open_window; + +cmd 'workspace 1'; +my $second = open_window; + +cmd 'workspace 2'; +my $third = open_window; + +# Sanity check +is(get_current_desktop, 2); +is(get_num_of_desktops, 3); +my @actual_names = get_desktop_names; +my @expected_names = ('0', '1', '2'); +is_deeply(\@actual_names, \@expected_names); + +# Kill first window to close a workspace. +cmd '[id="' . $second->id . '"] kill'; + +is(get_current_desktop, 2, '_NET_CURRENT_DESKTOP should be updated'); +is(get_num_of_desktops, 2, '_NET_NUMBER_OF_DESKTOPS should be updated'); +my @actual_names = get_desktop_names; +my @expected_names = ('0', '2'); +is_deeply(\@actual_names, \@expected_names, '_NET_DESKTOP_NAMES should be updated'); + + +done_testing;