? xinput-fixes.patch Index: libxklavier/xklavier_evt.c =================================================================== RCS file: /cvs/xklavier/libxklavier/libxklavier/xklavier_evt.c,v retrieving revision 1.26 retrieving revision 1.29 diff -u -r1.26 -r1.29 --- libxklavier/xklavier_evt.c 24 Apr 2009 22:10:19 -0000 1.26 +++ libxklavier/xklavier_evt.c 30 Sep 2009 09:49:57 -0000 1.29 @@ -50,7 +50,8 @@ break; case CreateNotify: xkl_engine_process_create_window_evt(engine, - &xev->xcreatewindow); + &xev-> + xcreatewindow); break; case DestroyNotify: xkl_debug(150, @@ -100,6 +101,8 @@ XFocusChangeEvent * fev) { Window win; + Window prev_toplevel_win = + xkl_engine_priv(engine, curr_toplvl_win); Window toplevel_win; XklState selected_window_state; @@ -135,36 +138,51 @@ if (xkl_engine_get_toplevel_window_state (engine, toplevel_win, &selected_window_state)) { - if (xkl_engine_priv(engine, curr_toplvl_win) != - toplevel_win) { - gboolean old_win_transparent, new_win_transparent; - XklState tmp_state; - - old_win_transparent = - xkl_engine_is_toplevel_window_transparent - (engine, - xkl_engine_priv(engine, curr_toplvl_win)); - if (old_win_transparent) - xkl_debug(150, - "Leaving transparent window\n"); + if (prev_toplevel_win != toplevel_win) { + gboolean new_win_transparent; + Window parent = (Window) NULL, root = + (Window) NULL, *children = NULL; + guint nchildren = 0; /* - * Reload the current state from the current window. - * Do not do it for transparent window - we keep the state from - * the _previous_ window. + * If previous focused window exists - handle transparency and state + * (optional) */ - if (!old_win_transparent && - xkl_engine_get_toplevel_window_state(engine, - xkl_engine_priv - (engine, - curr_toplvl_win), - &tmp_state)) - { - xkl_engine_update_current_state(engine, - tmp_state.group, - tmp_state.indicators, - "Loading current (previous) state from the current (previous) window"); - } + if (xkl_engine_query_tree + (engine, prev_toplevel_win, &root, &parent, + &children, &nchildren) == Success) { + XklState tmp_state; + gboolean old_win_transparent = + xkl_engine_is_toplevel_window_transparent + (engine, prev_toplevel_win); + + if (children != NULL) + XFree(children); + + if (old_win_transparent) + xkl_debug(150, + "Leaving transparent window\n"); + /* + * Reload the current state from the current window. + * Do not do it for transparent window - we keep the state from + * the _previous_ window. + */ + if (!old_win_transparent + && + xkl_engine_get_toplevel_window_state + (engine, prev_toplevel_win, + &tmp_state)) { + xkl_engine_update_current_state + (engine, tmp_state.group, + tmp_state.indicators, + "Loading current (previous) state from the current (previous) window"); + } + } else + xkl_debug(150, + "Current (previous) window " + WINID_FORMAT + " does not exist any more, so transparency/state are not analyzed\n", + prev_toplevel_win); xkl_engine_priv(engine, curr_toplvl_win) = toplevel_win; @@ -216,8 +234,10 @@ "Restoring the group from %d to %d after gaining focus\n", xkl_engine_priv (engine, - curr_state).group, - selected_window_state.group); + curr_state). + group, + selected_window_state. + group); /* * For fast mouse movements - the state is probably not updated yet * (because of the group change notification being late). @@ -225,17 +245,21 @@ */ xkl_engine_update_current_state (engine, - selected_window_state.group, - selected_window_state.indicators, + selected_window_state. + group, + selected_window_state. + indicators, "Enforcing fast update of the current state"); xkl_engine_lock_group (engine, - selected_window_state.group); + selected_window_state. + group); } else { xkl_debug(150, "Both old and new focused window " "have group %d so no point restoring it\n", - selected_window_state.group); + selected_window_state. + group); xkl_engine_one_switch_to_secondary_group_performed (engine); } @@ -249,8 +273,10 @@ xkl_debug(150, "Restoring the indicators from %X to %X after gaining focus\n", xkl_engine_priv(engine, - curr_state).indicators, - selected_window_state.indicators); + curr_state). + indicators, + selected_window_state. + indicators); xkl_engine_ensure_vtable_inited (engine); xkl_engine_vcall(engine, @@ -261,12 +287,14 @@ xkl_debug(150, "Not restoring the indicators %X after gaining focus: indicator handling is not enabled\n", xkl_engine_priv(engine, - curr_state).indicators); + curr_state). + indicators); } else xkl_debug(150, "Not restoring the group %d after gaining focus: global layout (xor transparent window)\n", xkl_engine_priv(engine, - curr_state).group); + curr_state). + group); } else xkl_debug(150, "Same app window - just do nothing\n"); @@ -392,11 +420,13 @@ "Something (%d) happened to WM_STATE of window 0x%x\n", pev->state, pev->window); xkl_engine_select_input_merging(engine, - pev->window, + pev-> + window, PropertyChangeMask); if (has_xkl_state) { xkl_engine_delete_state(engine, - pev->window); + pev-> + window); } } } /* XKLL_MANAGE_WINDOW_STATES */ @@ -475,8 +505,9 @@ xkl_engine_priv(engine, last_error_code) = evt->error_code; switch (evt->error_code) { - case BadWindow: case BadAccess: + case BadDrawable: + case BadWindow: { XGetErrorText(evt->display, evt->error_code, buf, sizeof(buf)); @@ -491,6 +522,22 @@ break; } default: + if (engine != NULL + && xkl_engine_priv(engine, process_x_error)) { + if (xkl_engine_priv(engine, process_x_error) + (engine, evt)) { + xkl_debug(200, + "X ERROR processed by the engine: %p, " + WINID_FORMAT ", %d [%s], " + "X11 request: %d, minor code: %d\n", + dpy, + (unsigned long) evt->resourceid, + (int) evt->error_code, buf, + (int) evt->request_code, + (int) evt->minor_code); + break; + } + } xkl_debug(200, "Unexpected by libxklavier X ERROR: %p, " WINID_FORMAT ", %d [%s], " Index: libxklavier/xklavier_evt_xkb.c =================================================================== RCS file: /cvs/xklavier/libxklavier/libxklavier/xklavier_evt_xkb.c,v retrieving revision 1.11 retrieving revision 1.12 diff -u -r1.11 -r1.12 --- libxklavier/xklavier_evt_xkb.c 17 Nov 2008 00:19:27 -0000 1.11 +++ libxklavier/xklavier_evt_xkb.c 30 Sep 2009 09:49:57 -0000 1.12 @@ -162,6 +162,21 @@ #endif } +/* + * XKB error handler + */ +gint +xkl_xkb_process_x_error(XklEngine * engine, XErrorEvent * xerev) +{ +#ifdef HAVE_XINPUT + /* Ignore XInput errors */ + if (xerev->error_code == xkl_engine_backend(engine, XklXkb, xi_error_code)) + return 1; +#endif + + return 0; +} + void xkl_xkb_set_indicators(XklEngine * engine, const XklState * window_state) { Index: libxklavier/xklavier_private.h =================================================================== RCS file: /cvs/xklavier/libxklavier/libxklavier/xklavier_private.h,v retrieving revision 1.38 retrieving revision 1.39 diff -u -r1.38 -r1.39 --- libxklavier/xklavier_private.h 23 Jun 2009 23:18:38 -0000 1.38 +++ libxklavier/xklavier_private.h 30 Sep 2009 09:49:57 -0000 1.39 @@ -157,6 +157,13 @@ gint(*process_x_event) (XklEngine * engine, XEvent * xev); /* + * Handles X errors. + * return 0 if further processing is needed + * 1 if error was handled + */ + gint(*process_x_error) (XklEngine * engine, XErrorEvent * xerev); + + /* * Flushes the cached server config info. * xkb: frees XkbDesc * xmodmap: frees internal XklConfigRec Index: libxklavier/xklavier_private_xkb.h =================================================================== RCS file: /cvs/xklavier/libxklavier/libxklavier/xklavier_private_xkb.h,v retrieving revision 1.18 retrieving revision 1.20 diff -u -r1.18 -r1.20 --- libxklavier/xklavier_private_xkb.h 23 Jun 2009 21:33:00 -0000 1.18 +++ libxklavier/xklavier_private_xkb.h 30 Sep 2009 09:49:57 -0000 1.20 @@ -48,6 +48,8 @@ #ifdef HAVE_XINPUT gint xi_event_type; + + gint xi_error_code; #endif } XklXkb; @@ -86,7 +88,9 @@ const XklConfigRec * data, const gboolean binary); -extern gint xkl_xkb_process_x_event(XklEngine * engine, XEvent * kev); +extern gint xkl_xkb_process_x_event(XklEngine * engine, XEvent * xev); + +extern gint xkl_xkb_process_x_error(XklEngine * engine, XErrorEvent * xerev); extern void xkl_xkb_free_all_info(XklEngine * engine); Index: libxklavier/xklavier_toplevel.c =================================================================== RCS file: /cvs/xklavier/libxklavier/libxklavier/xklavier_toplevel.c,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- libxklavier/xklavier_toplevel.c 1 Mar 2008 21:43:19 -0000 1.6 +++ libxklavier/xklavier_toplevel.c 12 Oct 2009 20:28:55 -0000 1.7 @@ -114,6 +114,22 @@ g_signal_lookup("new-toplevel-window", xkl_engine_get_type()); g_signal_emitv(params, signal_id, 0, &rv); default_group_to_use = g_value_get_int(&rv); + + if (default_group_to_use == -1) { + Window transient_for = 0; + if (XGetTransientForHint(xkl_engine_get_display(engine), toplevel_win, &transient_for)) { + if (transient_for) { + XklState trans_state; + gboolean have_state = + xkl_engine_get_toplevel_window_state(engine, + transient_for, + &trans_state); + if (have_state) { + default_group_to_use = trans_state.group; + } + } + } + } if (default_group_to_use == -1) default_group_to_use = Index: libxklavier/xklavier_xkb.c =================================================================== RCS file: /cvs/xklavier/libxklavier/libxklavier/xklavier_xkb.c,v retrieving revision 1.33 retrieving revision 1.37 diff -u -r1.33 -r1.37 --- libxklavier/xklavier_xkb.c 24 Apr 2009 22:10:19 -0000 1.33 +++ libxklavier/xklavier_xkb.c 30 Sep 2009 09:49:57 -0000 1.37 @@ -96,7 +96,7 @@ XkbNamesNotify, XKB_NAMES_EVT_DTL_MASK, XKB_NAMES_EVT_DTL_MASK); #ifdef HAVE_XINPUT - if (xkl_engine_priv(engine, features) | XKLF_DEVICE_DISCOVERY) { + if (xkl_engine_priv(engine, features) & XKLF_DEVICE_DISCOVERY) { DevicePresence(display, xitype, xiclass); XSelectExtensionEvent(display, xkl_engine_priv(engine, root_window), @@ -353,8 +353,8 @@ ¤t_state_out->indicators)) current_state_out->indicators &= xkl_engine_backend(engine, XklXkb, - cached_desc)-> - indicators->phys_indicators; + cached_desc)->indicators-> + phys_indicators; else current_state_out->indicators = 0; } @@ -402,8 +402,8 @@ xkl_engine_backend (engine, XklXkb, device_id), - cached-> - names->indicators + cached->names-> + indicators [indicator_num], set, False, NULL); else { @@ -541,7 +541,7 @@ #ifdef LIBXKBFILE_PRESENT gint opcode; gboolean xkl_xkb_ext_present; - int xi_opc, xi_event_type, xi_error_code; + int xi_opc; xkl_engine_priv(engine, backend_id) = "XKB"; xkl_engine_priv(engine, features) = XKLF_CAN_TOGGLE_INDICATORS | @@ -564,6 +564,7 @@ xkl_engine_priv(engine, get_num_groups) = xkl_xkb_get_num_groups; xkl_engine_priv(engine, lock_group) = xkl_xkb_lock_group; xkl_engine_priv(engine, process_x_event) = xkl_xkb_process_x_event; + xkl_engine_priv(engine, process_x_error) = xkl_xkb_process_x_error; xkl_engine_priv(engine, free_all_info) = xkl_xkb_free_all_info; xkl_engine_priv(engine, if_cached_info_equals_actual) = xkl_xkb_if_cached_info_equals_actual; @@ -615,14 +616,24 @@ xkl_engine_priv(engine, features) |= XKLF_MULTIPLE_LAYOUTS_SUPPORTED; +#if HAVE_XINPUT if (XQueryExtension (display, "XInputExtension", &xi_opc, - &xi_event_type, &xi_error_code)) { + &xkl_engine_backend(engine, XklXkb, xi_event_type), + &xkl_engine_backend(engine, XklXkb, xi_error_code))) { xkl_debug(150, "XInputExtension found (%d, %d, %d)\n", - xi_opc, xi_event_type, xi_error_code); + xi_opc, + xkl_engine_backend(engine, XklXkb, + xi_event_type), + xkl_engine_backend(engine, XklXkb, + xi_error_code)); xkl_engine_priv(engine, features) |= XKLF_DEVICE_DISCOVERY; - } else + } else { xkl_debug(0, "XInputExtension not found\n"); + xkl_engine_backend(engine, XklXkb, xi_event_type) = -1; + xkl_engine_backend(engine, XklXkb, xi_error_code) = -1; + } +#endif return 0; #else xkl_debug(160, Index: libxklavier/xklavier_xmm.c =================================================================== RCS file: /cvs/xklavier/libxklavier/libxklavier/xklavier_xmm.c,v retrieving revision 1.14 retrieving revision 1.15 diff -u -r1.14 -r1.15 --- libxklavier/xklavier_xmm.c 27 Apr 2008 14:59:55 -0000 1.14 +++ libxklavier/xklavier_xmm.c 30 Sep 2009 09:49:57 -0000 1.15 @@ -327,6 +327,7 @@ xkl_engine_priv(engine, lock_group) = xkl_xmm_lock_group; xkl_engine_priv(engine, process_x_event) = xkl_xmm_process_x_event; + xkl_engine_priv(engine, process_x_error) = NULL; xkl_engine_priv(engine, free_all_info) = xkl_xmm_free_all_info; xkl_engine_priv(engine, if_cached_info_equals_actual) = xkl_xmm_if_cached_info_equals_actual;