shell: Remove intricate key event handling code

We no longer need to do contortions with key events, as Clutter
key events will be already handed to IMs through ClutterInputMethod.
This commit is contained in:
Carlos Garnacho 2017-12-14 17:21:16 +01:00
parent 83accce24e
commit d1bebba77a

View File

@ -58,7 +58,6 @@ struct _ShellGlobal {
ClutterStage *stage;
Window stage_xwindow;
GdkWindow *ibus_window;
MetaDisplay *meta_display;
GdkDisplay *gdk_display;
@ -854,95 +853,6 @@ ui_scaling_factor_changed (MetaSettings *settings,
update_scaling_factor (global, settings);
}
/* This is an IBus workaround. The flow of events with IBus is that every time
* it gets gets a key event, it:
*
* Sends it to the daemon via D-Bus asynchronously
* When it gets an reply, synthesizes a new GdkEvent and puts it into the
* GDK event queue with gdk_event_put(), including
* IBUS_FORWARD_MASK = 1 << 25 in the state to prevent a loop.
*
* (Normally, IBus uses the GTK+ key snooper mechanism to get the key
* events early, but since our key events aren't visible to GTK+ key snoopers,
* IBus will instead get the events via the standard
* GtkIMContext.filter_keypress() mechanism.)
*
* There are a number of potential problems here; probably the worst
* problem is that IBus doesn't forward the timestamp with the event
* so that every key event that gets delivered ends up with
* GDK_CURRENT_TIME. This creates some very subtle bugs; for example
* if you have IBus running and a keystroke is used to trigger
* launching an application, focus stealing prevention won't work
* right. http://code.google.com/p/ibus/issues/detail?id=1184
*
* In any case, our normal flow of key events is:
*
* GDK filter function => clutter_x11_handle_event => clutter actor
*
* So, if we see a key event that gets delivered via the GDK event handler
* function - then we know it must be one of these synthesized events, and
* we should push it back to clutter.
*
* To summarize, the full key event flow with IBus is:
*
* GDK filter function
* => Mutter
* => gnome_shell_plugin_xevent_filter()
* => clutter_x11_handle_event()
* => clutter event delivery to actor
* => gtk_im_context_filter_event()
* => sent to IBus daemon
* => response received from IBus daemon
* => gdk_event_put()
* => GDK event handler
* => <this function>
* => clutter_event_put()
* => clutter event delivery to actor
*
* Anything else we see here we just pass on to the normal GDK event handler
* gtk_main_do_event().
*/
static void
gnome_shell_gdk_event_handler (GdkEvent *event_gdk,
gpointer data)
{
if (event_gdk->type == GDK_KEY_PRESS || event_gdk->type == GDK_KEY_RELEASE)
{
ShellGlobal *global = data;
if (event_gdk->key.window == global->ibus_window)
{
ClutterDeviceManager *device_manager = clutter_device_manager_get_default ();
ClutterInputDevice *keyboard = clutter_device_manager_get_device (device_manager,
META_VIRTUAL_CORE_KEYBOARD_ID);
ClutterEvent *event_clutter = clutter_event_new ((event_gdk->type == GDK_KEY_PRESS) ?
CLUTTER_KEY_PRESS : CLUTTER_KEY_RELEASE);
event_clutter->key.time = event_gdk->key.time;
event_clutter->key.flags = CLUTTER_EVENT_NONE;
event_clutter->key.stage = CLUTTER_STAGE (global->stage);
event_clutter->key.source = NULL;
/* This depends on ClutterModifierType and GdkModifierType being
* identical, which they are currently. (They both match the X
* modifier state in the low 16-bits and have the same extensions.) */
event_clutter->key.modifier_state = event_gdk->key.state;
event_clutter->key.keyval = event_gdk->key.keyval;
event_clutter->key.hardware_keycode = event_gdk->key.hardware_keycode;
event_clutter->key.unicode_value = gdk_keyval_to_unicode (event_clutter->key.keyval);
event_clutter->key.device = keyboard;
clutter_event_put (event_clutter);
clutter_event_free (event_clutter);
return;
}
}
gtk_main_do_event (event_gdk);
}
static void
entry_cursor_func (StEntry *entry,
gboolean use_ibeam,
@ -978,32 +888,13 @@ _shell_global_set_plugin (ShellGlobal *global,
if (meta_is_wayland_compositor ())
{
/* When Mutter is acting as its own display server then the
stage does not have a window, so create a different window
which we use to communicate with IBus, and leave stage_xwindow
as None.
*/
GdkWindowAttr attributes;
attributes.wclass = GDK_INPUT_OUTPUT;
attributes.width = 100;
attributes.height = 100;
attributes.window_type = GDK_WINDOW_TOPLEVEL;
global->ibus_window = gdk_window_new (NULL,
&attributes,
0 /* attributes_mask */);
global->stage_xwindow = None;
}
else
{
global->stage_xwindow = clutter_x11_get_stage_window (global->stage);
global->ibus_window = gdk_x11_window_foreign_new_for_display (global->gdk_display,
global->stage_xwindow);
}
st_im_text_set_event_window (global->ibus_window);
st_entry_set_cursor_func (entry_cursor_func, global);
g_signal_connect (global->stage, "notify::width",
@ -1045,8 +936,6 @@ _shell_global_set_plugin (ShellGlobal *global,
g_signal_connect (settings, "ui-scaling-factor-changed",
G_CALLBACK (ui_scaling_factor_changed), global);
gdk_event_handler_set (gnome_shell_gdk_event_handler, global, NULL);
global->focus_manager = st_focus_manager_get_for_stage (global->stage);
update_scaling_factor (global, settings);