Bugfix: respect WM_HINTS.input for WM_TAKE_FOCUS clients. This fixes

problems with some Qt apps
(upstream git commit 2d14ced024416e2074b57290bf7dade7d08899e5)

Bugfix: either use SetInputFocus *or* send WM_TAKE_FOCUS, not both.
This fixes problems with Oracle/OpenJDK JRE 7.0
(upstream git commit 21a2971b2442ab0881cf79553cc6b65bbb44afa7)
This commit is contained in:
dcoppa 2012-01-20 15:53:18 +00:00
parent 2ae9c7eeb8
commit cff065fc5f
10 changed files with 261 additions and 10 deletions

View File

@ -1,9 +1,9 @@
# $OpenBSD: Makefile,v 1.23 2012/01/11 13:33:48 dcoppa Exp $
# $OpenBSD: Makefile,v 1.24 2012/01/20 15:53:18 dcoppa Exp $
COMMENT = improved dynamic tiling window manager
DISTNAME = i3-4.1.1
REVISION = 0
REVISION = 1
CATEGORIES = x11
EXTRACT_SUFX = .tar.bz2

View File

@ -1,6 +1,6 @@
$OpenBSD: patch-i3bar_src_child_c,v 1.1 2011/12/27 09:05:17 dcoppa Exp $
--- i3bar/src/child.c.orig Tue Dec 27 09:42:01 2011
+++ i3bar/src/child.c Tue Dec 27 09:42:12 2011
$OpenBSD: patch-i3bar_src_child_c,v 1.2 2012/01/20 15:53:18 dcoppa Exp $
--- i3bar/src/child.c.orig Sat Dec 24 16:25:08 2011
+++ i3bar/src/child.c Fri Jan 20 15:17:47 2012
@@ -80,7 +80,6 @@ void stdin_io_cb(struct ev_loop *loop, ev_io *watcher,
}
@ -9,3 +9,13 @@ $OpenBSD: patch-i3bar_src_child_c,v 1.1 2011/12/27 09:05:17 dcoppa Exp $
cleanup();
draw_bars();
return;
@@ -113,9 +112,6 @@ void stdin_io_cb(struct ev_loop *loop, ev_io *watcher,
*
*/
void child_sig_cb(struct ev_loop *loop, ev_child *watcher, int revents) {
- ELOG("Child (pid: %d) unexpectedly exited with status %d\n",
- child_pid,
- watcher->rstatus);
cleanup();
}

View File

@ -0,0 +1,19 @@
$OpenBSD: patch-include_data_h,v 1.3 2012/01/20 15:53:18 dcoppa Exp $
Bugfix: respect WM_HINTS.input for WM_TAKE_FOCUS clients. This fixes
problems with some Qt apps
(upstream git commit 2d14ced024416e2074b57290bf7dade7d08899e5)
--- include/data.h.orig Sat Dec 24 16:25:08 2011
+++ include/data.h Fri Jan 20 14:29:55 2012
@@ -293,6 +293,10 @@ struct Window {
/** 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;

View File

@ -0,0 +1,19 @@
$OpenBSD: patch-include_window_h,v 1.1 2012/01/20 15:53:18 dcoppa Exp $
Bugfix: respect WM_HINTS.input for WM_TAKE_FOCUS clients. This fixes
problems with some Qt apps
(upstream git commit 2d14ced024416e2074b57290bf7dade7d08899e5)
--- include/window.h.orig Sat Dec 24 16:25:08 2011
+++ include/window.h Fri Jan 20 14:29:55 2012
@@ -57,4 +57,10 @@ void window_update_strut_partial(i3Window *win, xcb_ge
*/
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

View File

@ -0,0 +1,16 @@
$OpenBSD: patch-include_xcb_compat_h,v 1.1 2012/01/20 15:53:18 dcoppa Exp $
Bugfix: respect WM_HINTS.input for WM_TAKE_FOCUS clients. This fixes
problems with some Qt apps
(upstream git commit 2d14ced024416e2074b57290bf7dade7d08899e5)
--- include/xcb_compat.h.orig Fri Jan 20 15:10:01 2012
+++ include/xcb_compat.h Fri Jan 20 15:10:52 2012
@@ -27,6 +27,7 @@
#define XCB_ICCCM_SIZE_HINT_BASE_SIZE XCB_SIZE_HINT_BASE_SIZE
#define XCB_ICCCM_SIZE_HINT_P_ASPECT XCB_SIZE_HINT_P_ASPECT
#define xcb_icccm_wm_hints_t xcb_wm_hints_t
+#define xcb_icccm_get_wm_hints xcb_get_wm_hints
#define xcb_icccm_get_wm_hints_from_reply xcb_get_wm_hints_from_reply
#define xcb_icccm_get_wm_hints_reply xcb_get_wm_hints_reply
#define xcb_icccm_get_wm_hints_unchecked xcb_get_wm_hints_unchecked

View File

@ -1,4 +1,4 @@
$OpenBSD: patch-src_con_c,v 1.4 2012/01/11 13:33:48 dcoppa Exp $
$OpenBSD: patch-src_con_c,v 1.5 2012/01/20 15:53:18 dcoppa Exp $
Bugfix: don't lose focus on fullscreen windows when another window
gets moved to that workspace
@ -7,8 +7,8 @@ gets moved to that workspace
Bugfix: open new windows in the correct place when assignments match
(upstream git commit d4238c778a199ad88ebe8540904d98f81f110621)
--- src/con.c.orig Wed Jan 11 14:13:26 2012
+++ src/con.c Wed Jan 11 14:17:15 2012
--- src/con.c.orig Sat Dec 24 16:25:08 2011
+++ src/con.c Fri Jan 20 16:32:59 2012
@@ -656,8 +656,10 @@ void con_move_to_workspace(Con *con, Con *workspace, b
con_fix_percent(next);
@ -18,7 +18,7 @@ Bugfix: open new windows in the correct place when assignments match
+ * calling tree_render(), so for the "real" focus this is a no-op).
+ * We don't focus when there is a fullscreen con on that workspace. */
+ if (con_get_fullscreen_con(workspace, CF_OUTPUT) == NULL)
+ con_focus(con_descend_focused(con));
+ con_focus(con_descend_focused(con));
/* 8: when moving to a visible workspace on a different output, we keep the
* con focused. Otherwise, we leave the focus on the current workspace as we
@ -36,7 +36,7 @@ Bugfix: open new windows in the correct place when assignments match
Con *before;
Con *child;
+ if (next == focused)
+ return next;
+ return next;
do {
before = next;
TAILQ_FOREACH(child, &(next->focus_head), focused) {

View File

@ -0,0 +1,55 @@
$OpenBSD: patch-src_handlers_c,v 1.6 2012/01/20 15:53:18 dcoppa Exp $
Bugfix: respect WM_HINTS.input for WM_TAKE_FOCUS clients. This fixes
problems with some Qt apps
(upstream git commit 2d14ced024416e2074b57290bf7dade7d08899e5)
--- src/handlers.c.orig Sat Dec 24 16:25:08 2011
+++ src/handlers.c Fri Jan 20 14:29:55 2012
@@ -855,18 +855,16 @@ static bool handle_hints(void *data, xcb_connection_t
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 */
@@ -882,17 +880,10 @@ static bool handle_hints(void *data, xcb_connection_t
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;
}

View File

@ -0,0 +1,33 @@
$OpenBSD: patch-src_manage_c,v 1.5 2012/01/20 15:53:18 dcoppa Exp $
Bugfix: respect WM_HINTS.input for WM_TAKE_FOCUS clients. This fixes
problems with some Qt apps
(upstream git commit 2d14ced024416e2074b57290bf7dade7d08899e5)
--- src/manage.c.orig Sat Dec 24 16:25:08 2011
+++ src/manage.c Fri Jan 20 14:29:55 2012
@@ -80,7 +80,7 @@ void manage_window(xcb_window_t window, xcb_get_window
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);
@@ -142,6 +142,7 @@ void manage_window(xcb_window_t window, xcb_get_window
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);
@@ -169,6 +170,7 @@ void manage_window(xcb_window_t window, xcb_get_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);

View File

@ -0,0 +1,37 @@
$OpenBSD: patch-src_window_c,v 1.1 2012/01/20 15:53:18 dcoppa Exp $
Bugfix: respect WM_HINTS.input for WM_TAKE_FOCUS clients. This fixes
problems with some Qt apps
(upstream git commit 2d14ced024416e2074b57290bf7dade7d08899e5)
--- src/window.c.orig Sat Dec 24 16:25:08 2011
+++ src/window.c Fri Jan 20 14:29:55 2012
@@ -251,3 +251,28 @@ void window_update_role(i3Window *win, xcb_get_propert
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);
+}

View File

@ -0,0 +1,62 @@
$OpenBSD: patch-src_x_c,v 1.3 2012/01/20 15:53:18 dcoppa Exp $
Bugfix: either use SetInputFocus *or* send WM_TAKE_FOCUS, not both.
This fixes problems with Oracle/OpenJDK JRE 7.0
(upstream git commit 21a2971b2442ab0881cf79553cc6b65bbb44afa7)
Bugfix: respect WM_HINTS.input for WM_TAKE_FOCUS clients. This fixes
problems with some Qt apps
(upstream git commit 2d14ced024416e2074b57290bf7dade7d08899e5)
--- src/x.c.orig Sat Dec 24 16:25:08 2011
+++ src/x.c Fri Jan 20 14:29:56 2012
@@ -849,26 +849,34 @@ void x_push_changes(Con *con) {
/* Invalidate focused_id to correctly focus new windows with the same ID */
focused_id = XCB_NONE;
} else {
- 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
- * these generated by the clients. */
- if (focused->window != NULL) {
- values[0] = CHILD_EVENT_MASK & ~(XCB_EVENT_MASK_FOCUS_CHANGE);
- xcb_change_window_attributes(conn, focused->window->id, XCB_CW_EVENT_MASK, values);
- }
- xcb_set_input_focus(conn, XCB_INPUT_FOCUS_POINTER_ROOT, to_focus, XCB_CURRENT_TIME);
- if (focused->window != NULL) {
- values[0] = CHILD_EVENT_MASK;
- xcb_change_window_attributes(conn, focused->window->id, XCB_CW_EVENT_MASK, values);
- }
-
+ 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 (focused: %p / %s)\n",
+ to_focus, focused, focused->name);
send_take_focus(to_focus);
+ set_focus = !focused->window->doesnt_accept_focus;
+ DLOG("set_focus = %d\n", set_focus);
}
- ewmh_update_active_window(to_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
+ * these generated by the clients. */
+ if (focused->window != NULL) {
+ values[0] = CHILD_EVENT_MASK & ~(XCB_EVENT_MASK_FOCUS_CHANGE);
+ xcb_change_window_attributes(conn, focused->window->id, XCB_CW_EVENT_MASK, values);
+ }
+ xcb_set_input_focus(conn, XCB_INPUT_FOCUS_POINTER_ROOT, to_focus, XCB_CURRENT_TIME);
+ if (focused->window != NULL) {
+ values[0] = CHILD_EVENT_MASK;
+ xcb_change_window_attributes(conn, focused->window->id, XCB_CW_EVENT_MASK, values);
+ }
+
+ ewmh_update_active_window(to_focus);
+ }
+
focused_id = to_focus;
}
}