diff options
-rw-r--r-- | Makefile.am | 13 | ||||
-rw-r--r-- | i3bar/src/child.c | 13 | ||||
-rw-r--r-- | src/click.c | 10 | ||||
-rw-r--r-- | src/match.c | 8 | ||||
-rw-r--r-- | src/resize.c | 4 | ||||
-rw-r--r-- | src/workspace.c | 2 | ||||
-rw-r--r-- | testcases/t/119-match.t | 18 | ||||
-rw-r--r-- | testcases/t/521-ewmh-desktop-viewport.t | 33 |
8 files changed, 85 insertions, 16 deletions
diff --git a/Makefile.am b/Makefile.am index 872fdff7..089c4a22 100644 --- a/Makefile.am +++ b/Makefile.am @@ -629,3 +629,16 @@ CLEANFILES = \ i3-command-parser.stamp \ i3-config-parser.stamp \ anyevent-i3.stamp + +################################################################################ +# Language Server support +################################################################################ + +# Recursively run make through https://github.com/rizsotto/Bear, +# which generates a compile_commands.json file in the source directory. +# This is useful for running e.g. the clangd or ccls language servers: +# https://clang.llvm.org/extra/clangd/ +# https://github.com/MaskRay/ccls/wiki +.PHONY: bear +bear: clean + bear -o $(top_srcdir)/compile_commands.json $(MAKE) $(MAKEFLAGS) diff --git a/i3bar/src/child.c b/i3bar/src/child.c index 56961fc8..e56145fa 100644 --- a/i3bar/src/child.c +++ b/i3bar/src/child.c @@ -32,6 +32,8 @@ /* Global variables for child_*() */ i3bar_child child; +#define DLOG_CHILD DLOG("%s: pid=%ld stopped=%d stop_signal=%d cont_signal=%d click_events=%d click_events_init=%d\n", \ + __func__, (long)child.pid, child.stopped, child.stop_signal, child.cont_signal, child.click_events, child.click_events_init) /* stdin- and SIGCHLD-watchers */ ev_io *stdin_io; @@ -619,9 +621,12 @@ void start_child(char *command) { ev_child_start(main_loop, child_sig); atexit(kill_child_at_exit); + DLOG_CHILD; } static void child_click_events_initialize(void) { + DLOG_CHILD; + if (!child.click_events_init) { yajl_gen_array_open(gen); child_write_output(); @@ -700,6 +705,8 @@ void send_block_clicked(int button, const char *name, const char *instance, int * */ void kill_child_at_exit(void) { + DLOG_CHILD; + if (child.pid > 0) { if (child.cont_signal > 0 && child.stopped) killpg(child.pid, child.cont_signal); @@ -713,6 +720,8 @@ void kill_child_at_exit(void) { * */ void kill_child(void) { + DLOG_CHILD; + if (child.pid > 0) { if (child.cont_signal > 0 && child.stopped) killpg(child.pid, child.cont_signal); @@ -728,6 +737,8 @@ void kill_child(void) { * */ void stop_child(void) { + DLOG_CHILD; + if (child.stop_signal > 0 && !child.stopped) { child.stopped = true; killpg(child.pid, child.stop_signal); @@ -739,6 +750,8 @@ void stop_child(void) { * */ void cont_child(void) { + DLOG_CHILD; + if (child.cont_signal > 0 && child.stopped) { child.stopped = false; killpg(child.pid, child.cont_signal); diff --git a/src/click.c b/src/click.c index 7a3fde36..811f74d5 100644 --- a/src/click.c +++ b/src/click.c @@ -242,18 +242,18 @@ static void route_click(Con *con, xcb_button_press_event_t *event, const bool mo /* 5: resize (floating) if this was a (left or right) click on the * left/right/bottom border, or a right click on the decoration. - * also try resizing (tiling) if it was a click on the top */ + * also try resizing (tiling) if possible */ if (mod_pressed && event->detail == XCB_BUTTON_CLICK_RIGHT) { DLOG("floating resize due to floatingmodifier\n"); floating_resize_window(floatingcon, proportional, event); return; } - if (!in_stacked && dest == CLICK_DECORATION && + if ((dest == CLICK_BORDER || dest == CLICK_DECORATION) && is_left_or_right_click) { /* try tiling resize, but continue if it doesn’t work */ DLOG("tiling resize with fallback\n"); - if (tiling_resize(con, event, dest, !was_focused)) + if (tiling_resize(con, event, dest, dest == CLICK_DECORATION && !was_focused)) goto done; } @@ -290,10 +290,6 @@ static void route_click(Con *con, xcb_button_press_event_t *event, const bool mo else if ((dest == CLICK_BORDER || dest == CLICK_DECORATION) && is_left_or_right_click) { DLOG("Trying to resize (tiling)\n"); - /* Since we updated the tree (con_activate() above), we need to - * re-render the tree before returning to the event loop (drag_pointer() - * inside tiling_resize() runs its own event-loop). */ - tree_render(); tiling_resize(con, event, dest, dest == CLICK_DECORATION && !was_focused); } diff --git a/src/match.c b/src/match.c index 7b7881b6..a8850af4 100644 --- a/src/match.c +++ b/src/match.c @@ -92,11 +92,9 @@ bool match_matches_window(Match *match, i3Window *window) { #define CHECK_WINDOW_FIELD(match_field, window_field, type) \ do { \ if (match->match_field != NULL) { \ - if (window->window_field == NULL) { \ - return false; \ - } \ - \ - const char *window_field_str = GET_FIELD_##type(window->window_field); \ + const char *window_field_str = window->window_field == NULL \ + ? "" \ + : GET_FIELD_##type(window->window_field); \ if (strcmp(match->match_field->pattern, "__focused__") == 0 && \ focused && focused->window && focused->window->window_field && \ strcmp(window_field_str, GET_FIELD_##type(focused->window->window_field)) == 0) { \ diff --git a/src/resize.c b/src/resize.c index 97a0f946..6ad92cc0 100644 --- a/src/resize.c +++ b/src/resize.c @@ -238,6 +238,10 @@ void resize_graphical_handler(Con *first, Con *second, orientation_t orientation const struct callback_params params = {orientation, output, helpwin, &new_position, &threshold_exceeded}; + /* Re-render the tree before returning to the event loop (drag_pointer() + * runs its own event-loop) in case if there are unrendered updates. */ + tree_render(); + /* `drag_pointer' blocks until the drag is completed. */ drag_result_t drag_result = drag_pointer(NULL, event, grabwin, 0, use_threshold, resize_callback, ¶ms); diff --git a/src/workspace.c b/src/workspace.c index b98750ff..f48599c7 100644 --- a/src/workspace.c +++ b/src/workspace.c @@ -1049,6 +1049,8 @@ void workspace_move_to_output(Con *ws, Output *output) { workspace_show(ws); } + ewmh_update_desktop_properties(); + if (!previously_visible_ws) { return; } diff --git a/testcases/t/119-match.t b/testcases/t/119-match.t index 64ffa4ed..65c41f1f 100644 --- a/testcases/t/119-match.t +++ b/testcases/t/119-match.t @@ -33,9 +33,7 @@ my $win = $content->[0]; # not match it ###################################################################### # TODO: specify more match types -# we can match on any (non-empty) class here since that window does not have -# WM_CLASS set -cmd q|[class=".*"] kill|; +# Try matching with an empty pattern since there isn't a WM_CLASS set. cmd q|[con_id="99999"] kill|; is_num_children($tmp, 1, 'window still there'); @@ -103,4 +101,18 @@ cmd '[title="^\w [3]$"] kill'; wait_for_unmap $left; is_num_children($tmp, 0, 'window killed'); +###################################################################### +# check that we can match empty properties +###################################################################### + +$tmp = fresh_workspace; + +$left = open_window(name => 'class is empty', wm_class => ''); +ok($left->mapped, 'left window mapped'); +is_num_children($tmp, 1, 'window opened'); + +cmd '[class="^$"] kill'; +wait_for_unmap $left; +is_num_children($tmp, 0, 'window killed'); + done_testing; diff --git a/testcases/t/521-ewmh-desktop-viewport.t b/testcases/t/521-ewmh-desktop-viewport.t index 5ede140d..a4119367 100644 --- a/testcases/t/521-ewmh-desktop-viewport.t +++ b/testcases/t/521-ewmh-desktop-viewport.t @@ -50,7 +50,10 @@ sub get_desktop_viewport { return unpack ("L$len", $reply->{value}); } -# initialize the workspaces +################################################################################ +# Initialize the workspaces +################################################################################ + cmd 'workspace 1'; cmd 'workspace 0'; @@ -60,6 +63,10 @@ my @desktop_viewport = get_desktop_viewport; is_deeply(\@desktop_viewport, \@expected_viewport, '_NET_DESKTOP_VIEWPORT should be an array of x/y coordinate pairs for the upper left corner of the respective outputs of the workspaces'); +################################################################################ +# Create workspace +################################################################################ + cmd 'workspace 0'; open_window; cmd 'workspace 3'; @@ -70,6 +77,10 @@ cmd 'workspace 3'; is_deeply(\@desktop_viewport, \@expected_viewport, 'it should be updated when a new workspace appears'); +################################################################################ +# Rename workspace +################################################################################ + cmd 'rename workspace 3 to 2'; @expected_viewport = (0, 0, 0, 0, 1024, 0); @@ -78,6 +89,10 @@ cmd 'rename workspace 3 to 2'; is_deeply(\@desktop_viewport, \@expected_viewport, 'it should stay up to date when a workspace is renamed'); +################################################################################ +# Empty workspace +################################################################################ + cmd 'workspace 0'; @expected_viewport = (0, 0, 1024, 0); @@ -86,4 +101,20 @@ cmd 'workspace 0'; is_deeply(\@desktop_viewport, \@expected_viewport, 'it should be updated when a workspace is emptied'); +################################################################################ +# Move workspace +# See #4001 +################################################################################ + +# Keep workspace 1 open to have 3 workspaces in total +cmd 'workspace 1'; +open_window; +cmd 'workspace 0, move workspace to output right'; +@expected_viewport = (0, 0, 1024, 0, 1024, 0); +@desktop_viewport = get_desktop_viewport; +is_deeply(\@desktop_viewport, \@expected_viewport, + 'it should be updated when a workspace is moved'); + +################################################################################ + done_testing; |