aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am13
-rw-r--r--i3bar/src/child.c13
-rw-r--r--src/click.c10
-rw-r--r--src/match.c8
-rw-r--r--src/resize.c4
-rw-r--r--src/workspace.c2
-rw-r--r--testcases/t/119-match.t18
-rw-r--r--testcases/t/521-ewmh-desktop-viewport.t33
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, &params);
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;