libxklavier/xinput-fixes.patch
2009-11-02 05:33:13 +00:00

438 lines
14 KiB
Diff

? 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 @@
&current_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;