struct Window *window;
+ /* Should this container be marked urgent? This gets set when the window
+ * inside this container (if any) sets the urgency hint, for example. */
+ bool urgent;
+
/* ids/gc for the frame window */
xcb_window_t frame;
xcb_gcontext_t gc;
xcb_window_t window, xcb_atom_t name,
xcb_get_property_reply_t *reply);
+#endif
/**
* Handles the WM_HINTS property for extracting the urgency state of the window.
*
*/
int handle_hints(void *data, xcb_connection_t *conn, uint8_t state, xcb_window_t window,
xcb_atom_t name, xcb_get_property_reply_t *reply);
+#if 0
/**
* Handles the transient for hints set by a window, signalizing that this
*
*/
void workspace_map_clients(xcb_connection_t *conn, Workspace *ws);
+#endif
/**
* Goes through all clients on the given workspace and updates the workspace’s
* urgent flag accordingly.
*
*/
-void workspace_update_urgent_flag(Workspace *ws);
+void workspace_update_urgent_flag(Con *ws);
+#if 0
/*
* Returns the width of the workspace.
*
con_focus(con->parent);
focused = con;
+ if (con->urgent) {
+ con->urgent = false;
+ workspace_update_urgent_flag(con_get_workspace(con));
+ }
}
/*
return 1;
}
+#endif
/*
* Handles the WM_HINTS property for extracting the urgency state of the window.
*/
int handle_hints(void *data, xcb_connection_t *conn, uint8_t state, xcb_window_t window,
xcb_atom_t name, xcb_get_property_reply_t *reply) {
- Client *client = table_get(&by_child, window);
- if (client == NULL) {
- DLOG("Received WM_HINTS for unknown client\n");
- return 1;
- }
- xcb_wm_hints_t hints;
+ Con *con = con_by_window_id(window);
+ if (con == NULL) {
+ DLOG("Received WM_HINTS for unknown client\n");
+ return 1;
+ }
- if (reply != NULL) {
- if (!xcb_get_wm_hints_from_reply(&hints, reply))
- return 1;
- } else {
- if (!xcb_get_wm_hints_reply(conn, xcb_get_wm_hints_unchecked(conn, client->child), &hints, NULL))
- return 1;
- }
+ xcb_wm_hints_t hints;
- Client *last_focused = SLIST_FIRST(&(c_ws->focus_stack));
- if (!client->urgent && client == last_focused) {
- DLOG("Ignoring urgency flag for current client\n");
- return 1;
- }
+ if (reply != NULL) {
+ if (!xcb_get_wm_hints_from_reply(&hints, reply))
+ return 1;
+ } else {
+ if (!xcb_get_wm_hints_reply(conn, xcb_get_wm_hints_unchecked(conn, con->window->id), &hints, NULL))
+ return 1;
+ }
- /* Update the flag on the client directly */
- client->urgent = (xcb_wm_hints_get_urgency(&hints) != 0);
- CLIENT_LOG(client);
- LOG("Urgency flag changed to %d\n", client->urgent);
+ if (!con->urgent && focused == con) {
+ DLOG("Ignoring urgency flag for current client\n");
+ return 1;
+ }
- workspace_update_urgent_flag(client->workspace);
- redecorate_window(conn, client);
+ /* Update the flag on the client directly */
+ con->urgent = (xcb_wm_hints_get_urgency(&hints) != 0);
+ //CLIENT_LOG(con);
+ LOG("Urgency flag changed to %d\n", con->urgent);
- /* If the workspace this client is on is not visible, we need to redraw
- * the workspace bar */
- if (!workspace_is_visible(client->workspace)) {
- Output *output = client->workspace->output;
- render_workspace(conn, output, output->current_workspace);
- xcb_flush(conn);
- }
+ workspace_update_urgent_flag(con_get_workspace(con));
- return 1;
+#if 0
+ /* If the workspace this client is on is not visible, we need to redraw
+ * the workspace bar */
+ if (!workspace_is_visible(client->workspace)) {
+ Output *output = client->workspace->output;
+ render_workspace(conn, output, output->current_workspace);
+ xcb_flush(conn);
+ }
+#endif
+
+ return 1;
}
+#if 0
+
/*
* Handles the transient for hints set by a window, signalizing that this window is a popup window
* for some other window.
ystr("orientation");
y(integer, con->orientation);
+ ystr("urgent");
+ y(integer, con->urgent);
+
ystr("layout");
y(integer, con->layout);
* vim:ts=4:sw=4:expandtab
*/
#include <ev.h>
+#include <limits.h>
#include "all.h"
static int xkb_event_base;
/* Watch _NET_WM_NAME (title of the window encoded in UTF-8) */
xcb_property_set_handler(&prophs, atoms[_NET_WM_NAME], 128, handle_windowname_change, NULL);
+ /* Watch WM_HINTS (contains the urgent property) */
+ xcb_property_set_handler(&prophs, WM_HINTS, UINT_MAX, handle_hints, NULL);
+
/* Watch WM_NAME (title of the window encoded in COMPOUND_TEXT) */
xcb_watch_wm_name(&prophs, 128, handle_windowname_change_legacy, NULL);
ignore_enter_notify_forall(conn, u_ws, false);
}
+#endif
+
+static bool get_urgency_flag(Con *con) {
+ Con *child;
+ TAILQ_FOREACH(child, &(con->nodes_head), nodes)
+ if (child->urgent || get_urgency_flag(child))
+ return true;
+
+ TAILQ_FOREACH(child, &(con->floating_head), floating_windows)
+ if (child->urgent || get_urgency_flag(child))
+ return true;
+
+ return false;
+}
/*
* Goes through all clients on the given workspace and updates the workspace’s
* urgent flag accordingly.
*
*/
-void workspace_update_urgent_flag(Workspace *ws) {
- Client *current;
- bool old_flag = ws->urgent;
- bool urgent = false;
-
- SLIST_FOREACH(current, &(ws->focus_stack), focus_clients) {
- if (!current->urgent)
- continue;
+void workspace_update_urgent_flag(Con *ws) {
+ bool old_flag = ws->urgent;
+ ws->urgent = get_urgency_flag(ws);
+ DLOG("Workspace urgency flag changed from %d to %d\n", old_flag, ws->urgent);
- urgent = true;
- break;
- }
-
- ws->urgent = urgent;
-
- if (old_flag != urgent)
- ipc_send_event("workspace", I3_IPC_EVENT_WORKSPACE, "{\"change\":\"urgent\"}");
+ if (old_flag != ws->urgent)
+ ipc_send_event("workspace", I3_IPC_EVENT_WORKSPACE, "{\"change\":\"urgent\"}");
}
+#if 0
+
/*
* Returns the width of the workspace.
*
#!perl
# vim:ts=4:sw=4:expandtab
-# Beware that this test uses workspace 9 to perform some tests (it expects
-# the workspace to be empty).
-# TODO: skip it by default?
-use i3test tests => 7;
+use i3test tests => 10;
use X11::XCB qw(:all);
use Time::HiRes qw(sleep);
+use List::Util qw(first);
BEGIN {
use_ok('X11::XCB::Connection') or BAIL_OUT('Cannot load X11::XCB::Connection');
my $x = X11::XCB::Connection->new;
-my $i3 = i3;
-
-# Switch to the nineth workspace
-$i3->command('9')->recv;
+my $i3 = i3("/tmp/nestedcons");
+my $tmp = get_unused_workspace();
+$i3->command("workspace $tmp")->recv;
#####################################################################
# Create two windows and put them in stacking mode
#####################################################################
+$i3->command('split v')->recv;
+
my $top = i3test::open_standard_window($x);
-sleep 0.25;
my $bottom = i3test::open_standard_window($x);
-sleep 0.25;
-$i3->command('s')->recv;
+my @urgent = grep { $_->{urgent} == 1 } @{get_ws_content($tmp)};
+is(@urgent, 0, 'no window got the urgent flag');
+
+#$i3->command('layout stacking')->recv;
#####################################################################
# Add the urgency hint, switch to a different workspace and back again
#####################################################################
$top->add_hint('urgency');
-sleep 1;
+sleep 0.5;
+
+@content = @{get_ws_content($tmp)};
+@urgent = grep { $_->{urgent} == 1 } @content;
+$top_info = first { $_->{window} == $top->id } @content;
+$bottom_info = first { $_->{window} == $bottom->id } @content;
+
+is($top_info->{urgent}, 1, 'top window is marked urgent');
+is($bottom_info->{urgent}, 0, 'bottom window is not marked urgent');
+is(@urgent, 1, 'exactly one window got the urgent flag');
+
+$i3->command('[id="' . $top->id . '"] focus')->recv;
+
+@urgent = grep { $_->{urgent} == 1 } @{get_ws_content($tmp)};
+is(@urgent, 0, 'no window got the urgent flag after focusing');
+
+$top->add_hint('urgency');
+sleep 0.5;
+
+@urgent = grep { $_->{urgent} == 1 } @{get_ws_content($tmp)};
+is(@urgent, 0, 'no window got the urgent flag after re-setting urgency hint');
+
+#####################################################################
+# Check if the workspace urgency hint gets set/cleared correctly
+#####################################################################
+my $ws = get_ws($tmp);
+is($ws->{urgent}, 0, 'urgent flag not set on workspace');
+
+my $otmp = get_unused_workspace();
+$i3->command("workspace $otmp")->recv;
+
+$top->add_hint('urgency');
+sleep 0.5;
+
+$ws = get_ws($tmp);
+is($ws->{urgent}, 1, 'urgent flag set on workspace');
+
+$i3->command("workspace $tmp")->recv;
-$i3->command('1')->recv;
-$i3->command('9')->recv;
-$i3->command('1')->recv;
+$ws = get_ws($tmp);
+is($ws->{urgent}, 0, 'urgent flag not set on workspace after switching');
-my $std = i3test::open_standard_window($x);
-sleep 0.25;
-$std->add_hint('urgency');
-sleep 1;
+diag( "Testing i3, Perl $], $^X" );