broadway: use 'click-to-focus' approach instead of 'focus-follows-mouse'

The broadway backend would move the focus from one window to another based on
where the mouse was (i.e. 'focus-follows-mouse' approach). Handling the focus
this wait didn't play well with widgets which rely on focus-in-event and
focus-out-event, like the GtkEntry when using a completion popup window, see
e.g:
  https://bugzilla.gnome.org/show_bug.cgi?id=708984

So instead, setup broadway to require a click in a window to move the focus
(i.e. 'click-to-focus' approach):

 * The implicit GDK_FOCUS_CHANGE events that were generated upon reception of
   BROADWAY_EVENT_ENTER or BROADWAY_EVENT_LEAVE are removed.

 * The broadway daemon will now keep track of which is the focused window

 * Whenever the daemon detects an incoming BROADWAY_EVENT_BUTTON_PRESS, it will
   trigger the focused window switch, which sends a new BROADWAY_EVENT_FOCUS to
   the client, specifying which windows holds the focus.

 * Upon reception of a BROADWAY_EVENT_FOCUS, the client will generate a new
   GDK_FOCUS_CHANGE.

 * gdk_broadway_window_focus() was also implemented, which now requests the
   focus to the broadway server using a new BROADWAY_REQUEST_FOCUS_WINDOW.

This is based on an initial patch from Aleksander Morgado <aleksander@lanedo.com>.
This commit is contained in:
Alexander Larsson
2013-11-12 12:03:50 +01:00
parent f50a3af1b7
commit ddade66496
8 changed files with 83 additions and 19 deletions

View File

@ -117,14 +117,6 @@ _gdk_broadway_events_got_input (BroadwayInputMsg *message)
node = _gdk_event_queue_append (display, event);
_gdk_windowing_got_event (display, node, event, message->base.serial);
event = gdk_event_new (GDK_FOCUS_CHANGE);
event->focus_change.window = g_object_ref (window);
event->focus_change.in = TRUE;
gdk_event_set_device (event, display->core_pointer);
node = _gdk_event_queue_append (display, event);
_gdk_windowing_got_event (display, node, event, message->base.serial);
}
break;
case BROADWAY_EVENT_LEAVE:
@ -145,14 +137,6 @@ _gdk_broadway_events_got_input (BroadwayInputMsg *message)
node = _gdk_event_queue_append (display, event);
_gdk_windowing_got_event (display, node, event, message->base.serial);
event = gdk_event_new (GDK_FOCUS_CHANGE);
event->focus_change.window = g_object_ref (window);
event->focus_change.in = FALSE;
gdk_event_set_device (event, display->core_pointer);
node = _gdk_event_queue_append (display, event);
_gdk_windowing_got_event (display, node, event, message->base.serial);
}
break;
case BROADWAY_EVENT_POINTER_MOVE:
@ -295,6 +279,19 @@ _gdk_broadway_events_got_input (BroadwayInputMsg *message)
_gdk_broadway_screen_size_changed (screen, &message->screen_resize_notify);
break;
case BROADWAY_EVENT_FOCUS:
window = g_hash_table_lookup (display_broadway->id_ht, GINT_TO_POINTER (message->focus.id));
if (window)
{
event = gdk_event_new (GDK_FOCUS_CHANGE);
event->focus_change.window = g_object_ref (window);
event->focus_change.in = TRUE;
gdk_event_set_device (event, display->core_pointer);
node = _gdk_event_queue_append (display, event);
_gdk_windowing_got_event (display, node, event, message->base.serial);
}
break;
default:
g_printerr ("_gdk_broadway_events_got_input - Unknown input command %c\n", message->base.type);
break;