* vim:ts=4:sw=4:expandtab
*
* i3 - an improved dynamic tiling window manager
- * © 2009-2011 Michael Stapelberg and contributors (see also: LICENSE)
+ * © 2009-2012 Michael Stapelberg and contributors (see also: LICENSE)
*
* include/data.h: This file defines all data structures used by i3
*
/** Whether the application needs to receive WM_TAKE_FOCUS */
bool needs_take_focus;
+ /** Whether this window accepts focus. We store this inverted so that the
+ * default will be 'accepts focus'. */
+ bool doesnt_accept_focus;
+
/** Whether the window says it is a dock window */
enum { W_NODOCK = 0, W_DOCK_TOP = 1, W_DOCK_BOTTOM = 2 } dock;
*/
void window_update_role(i3Window *win, xcb_get_property_reply_t *prop, bool before_mgmt);
+/**
+ * Updates the WM_HINTS (we only care about the input focus handling part).
+ *
+ */
+void window_update_hints(i3Window *win, xcb_get_property_reply_t *prop);
+
#endif
xcb_icccm_wm_hints_t hints;
- if (reply != NULL) {
- if (!xcb_icccm_get_wm_hints_from_reply(&hints, reply))
+ if (reply == NULL)
+ if (!(reply = xcb_get_property_reply(conn, xcb_icccm_get_wm_hints(conn, window), NULL)))
return false;
- } else {
- if (!xcb_icccm_get_wm_hints_reply(conn, xcb_icccm_get_wm_hints_unchecked(conn, con->window->id), &hints, NULL))
- return false;
- }
+
+ if (!xcb_icccm_get_wm_hints_from_reply(&hints, reply))
+ return false;
if (!con->urgent && focused == con) {
DLOG("Ignoring urgency flag for current client\n");
- FREE(reply);
- return true;
+ goto end;
}
/* Update the flag on the client directly */
tree_render();
-#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
-
- FREE(reply);
+end:
+ if (con->window)
+ window_update_hints(con->window, reply);
+ else free(reply);
return true;
}
xcb_get_property_cookie_t wm_type_cookie, strut_cookie, state_cookie,
utf8_title_cookie, title_cookie,
class_cookie, leader_cookie, transient_cookie,
- role_cookie, startup_id_cookie;
+ role_cookie, startup_id_cookie, wm_hints_cookie;
geomc = xcb_get_geometry(conn, d);
class_cookie = GET_PROPERTY(XCB_ATOM_WM_CLASS, 128);
role_cookie = GET_PROPERTY(A_WM_WINDOW_ROLE, 128);
startup_id_cookie = GET_PROPERTY(A__NET_STARTUP_ID, 512);
+ wm_hints_cookie = xcb_icccm_get_wm_hints(conn, window);
/* TODO: also get wm_normal_hints here. implement after we got rid of xcb-event */
DLOG("Managing window 0x%08x\n", window);
window_update_transient_for(cwindow, xcb_get_property_reply(conn, transient_cookie, NULL));
window_update_strut_partial(cwindow, xcb_get_property_reply(conn, strut_cookie, NULL));
window_update_role(cwindow, xcb_get_property_reply(conn, role_cookie, NULL), true);
+ window_update_hints(cwindow, xcb_get_property_reply(conn, wm_hints_cookie, NULL));
xcb_get_property_reply_t *startup_id_reply;
startup_id_reply = xcb_get_property_reply(conn, startup_id_cookie, NULL);
* vim:ts=4:sw=4:expandtab
*
* i3 - an improved dynamic tiling window manager
- * © 2009-2011 Michael Stapelberg and contributors (see also: LICENSE)
+ * © 2009-2012 Michael Stapelberg and contributors (see also: LICENSE)
*
* window.c: Updates window attributes (X11 hints/properties).
*
free(prop);
}
+
+/*
+ * Updates the WM_HINTS (we only care about the input focus handling part).
+ *
+ */
+void window_update_hints(i3Window *win, xcb_get_property_reply_t *prop) {
+ if (prop == NULL || xcb_get_property_value_length(prop) == 0) {
+ DLOG("WM_HINTS not set.\n");
+ FREE(prop);
+ return;
+ }
+
+ xcb_icccm_wm_hints_t hints;
+
+ if (!xcb_icccm_get_wm_hints_from_reply(&hints, prop)) {
+ DLOG("Could not get WM_HINTS\n");
+ free(prop);
+ return;
+ }
+
+ win->doesnt_accept_focus = !hints.input;
+ LOG("WM_HINTS.input changed to \"%d\"\n", hints.input);
+
+ free(prop);
+}
* vim:ts=4:sw=4:expandtab
*
* i3 - an improved dynamic tiling window manager
- * © 2009-2011 Michael Stapelberg and contributors (see also: LICENSE)
+ * © 2009-2012 Michael Stapelberg and contributors (see also: LICENSE)
*
* x.c: Interface to X11, transfers our in-memory state to X11 (see also
* render.c). Basically a big state machine.
/* Invalidate focused_id to correctly focus new windows with the same ID */
focused_id = XCB_NONE;
} else {
+ bool set_focus = true;
if (focused->window != NULL &&
focused->window->needs_take_focus) {
- DLOG("Updating focus by sending WM_TAKE_FOCUS to window 0x%08x only (focused: %p / %s)\n",
+ DLOG("Updating focus by sending WM_TAKE_FOCUS to window 0x%08x (focused: %p / %s)\n",
to_focus, focused, focused->name);
send_take_focus(to_focus);
- } else {
+ set_focus = !focused->window->doesnt_accept_focus;
+ DLOG("set_focus = %d\n", set_focus);
+ }
+
+ if (set_focus) {
DLOG("Updating focus (focused: %p / %s)\n", focused, focused->name);
/* We remove XCB_EVENT_MASK_FOCUS_CHANGE from the event mask to get
* no focus change events for our own focus changes. We only want