Merge branch 'matthiasc/for-master' into 'master'

Matthiasc/for master

Closes #2612

See merge request GNOME/gtk!1695
This commit is contained in:
Matthias Clasen 2020-04-15 19:28:32 +00:00
commit ec848dc83f
4 changed files with 60 additions and 106 deletions

View File

@ -2823,53 +2823,6 @@ check_autohide (GdkEvent *event)
return FALSE;
}
static gboolean
is_keyboard_event (GdkEvent *event)
{
switch ((guint) gdk_event_get_event_type (event))
{
case GDK_KEY_PRESS:
case GDK_KEY_RELEASE:
case GDK_FOCUS_CHANGE:
return TRUE;
default:;
}
return FALSE;
}
static GdkEvent *
rewrite_event_for_toplevel (GdkEvent *event)
{
GdkSurface *surface;
surface = gdk_event_get_surface (event);
if (!surface->parent)
return gdk_event_ref (event);
while (surface->parent)
surface = surface->parent;
if (gdk_event_get_event_type (event) == GDK_FOCUS_CHANGE)
return gdk_event_focus_new (surface,
gdk_event_get_device (event),
gdk_event_get_source_device (event),
gdk_focus_event_get_in (event));
else
{
return gdk_event_key_new (gdk_event_get_event_type (event),
surface,
gdk_event_get_device (event),
gdk_event_get_source_device (event),
gdk_event_get_time (event),
gdk_key_event_get_keycode (event),
gdk_event_get_modifier_state (event),
gdk_key_event_is_modifier (event),
&event->key.translated[0],
&event->key.translated[1]);
}
}
static void
add_event_mark (GdkEvent *event,
gint64 time,
@ -2985,15 +2938,7 @@ gdk_surface_handle_event (GdkEvent *event)
}
else
{
GdkEvent *emitted;
if (is_keyboard_event (event))
emitted = rewrite_event_for_toplevel (event);
else
emitted = gdk_event_ref (event);
g_signal_emit (gdk_event_get_surface (emitted), signals[EVENT], 0, emitted, &handled);
gdk_event_unref (emitted);
g_signal_emit (gdk_event_get_surface (event), signals[EVENT], 0, event, &handled);
}
if (GDK_PROFILER_IS_RUNNING)

View File

@ -92,12 +92,12 @@ gtk_event_controller_legacy_class_init (GtkEventControllerLegacyClass *klass)
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0, _gtk_boolean_handled_accumulator, NULL,
_gtk_marshal_BOOLEAN__OBJECT,
_gtk_marshal_BOOLEAN__BOXED,
G_TYPE_BOOLEAN, 1,
GDK_TYPE_EVENT);
g_signal_set_va_marshaller (signals[EVENT], G_TYPE_FROM_CLASS (klass),
_gtk_marshal_BOOLEAN__OBJECTv);
_gtk_marshal_BOOLEAN__BOXEDv);
}
static void

View File

@ -1226,6 +1226,30 @@ rewrite_event_for_grabs (GdkEvent *event)
return NULL;
}
static GdkEvent *
rewrite_event_for_toplevel (GdkEvent *event)
{
GdkSurface *surface;
surface = gdk_event_get_surface (event);
if (!surface->parent)
return NULL;
while (surface->parent)
surface = surface->parent;
return gdk_event_key_new (gdk_event_get_event_type (event),
surface,
gdk_event_get_device (event),
gdk_event_get_source_device (event),
gdk_event_get_time (event),
gdk_key_event_get_keycode (event),
gdk_event_get_modifier_state (event),
gdk_key_event_is_modifier (event),
&event->key.translated[0],
&event->key.translated[1]);
}
static gboolean
translate_event_coordinates (GdkEvent *event,
double *x,
@ -1430,19 +1454,6 @@ is_key_event (GdkEvent *event)
}
}
static gboolean
is_focus_event (GdkEvent *event)
{
switch ((guint) gdk_event_get_event_type (event))
{
case GDK_FOCUS_CHANGE:
return TRUE;
break;
default:
return FALSE;
}
}
static inline void
set_widget_active_state (GtkWidget *target,
const gboolean release)
@ -1620,10 +1631,16 @@ gtk_main_do_event (GdkEvent *event)
target_widget = event_widget;
/* If pointer or keyboard grabs are in effect, munge the events
/* We propagate key events from the root, even if they are
* delivered to a popup surface.
*
* If pointer or keyboard grabs are in effect, munge the events
* so that each window group looks like a separate app.
*/
rewritten_event = rewrite_event_for_grabs (event);
if (is_key_event (event))
rewritten_event = rewrite_event_for_toplevel (event);
else
rewritten_event = rewrite_event_for_grabs (event);
if (rewritten_event)
{
event = rewritten_event;
@ -1643,14 +1660,6 @@ gtk_main_do_event (GdkEvent *event)
{
target_widget = handle_key_event (event);
}
else if (is_focus_event (event))
{
if (!GTK_IS_WINDOW (target_widget))
{
g_message ("Ignoring an unexpected focus event from GDK on a non-toplevel surface.");
goto cleanup;
}
}
if (!target_widget)
goto cleanup;

View File

@ -40,7 +40,7 @@
#include "gtkcssshadowvalueprivate.h"
#include "gtkcssstylepropertyprivate.h"
#include "gtkdroptargetasync.h"
#include "gtkeventcontrollerfocus.h"
#include "gtkeventcontrollerlegacy.h"
#include "gtkeventcontrollerkey.h"
#include "gtkeventcontrollermotion.h"
#include "gtkgesturedrag.h"
@ -370,8 +370,10 @@ static void gtk_window_size_allocate (GtkWidget *widget,
int height,
int baseline);
static gboolean gtk_window_close_request (GtkWindow *window);
static void gtk_window_focus_in (GtkWidget *widget);
static void gtk_window_focus_out (GtkWidget *widget);
static gboolean gtk_window_handle_focus (GtkWidget *widget,
GdkEvent *event,
double x,
double y);
static gboolean gtk_window_key_pressed (GtkWidget *widget,
guint keyval,
guint keycode,
@ -1748,11 +1750,11 @@ gtk_window_init (GtkWindow *window)
g_signal_connect_swapped (priv->key_controller, "key-released",
G_CALLBACK (gtk_window_key_released), window);
gtk_widget_add_controller (widget, priv->key_controller);
controller = gtk_event_controller_focus_new ();
g_signal_connect_swapped (controller, "enter",
G_CALLBACK (gtk_window_focus_in), window);
g_signal_connect_swapped (controller, "leave",
G_CALLBACK (gtk_window_focus_out), window);
controller = gtk_event_controller_legacy_new ();
gtk_event_controller_set_name (controller, "gtk-window-toplevel-focus");
g_signal_connect_swapped (controller, "event",
G_CALLBACK (gtk_window_handle_focus), window);
gtk_widget_add_controller (widget, controller);
/* Shared constraint solver */
@ -5317,34 +5319,32 @@ gtk_window_has_mnemonic_modifier_pressed (GtkWindow *window)
return retval;
}
static void
gtk_window_focus_in (GtkWidget *widget)
static gboolean
gtk_window_handle_focus (GtkWidget *widget,
GdkEvent *event,
double x,
double y)
{
GtkWindow *window = GTK_WINDOW (widget);
/* It appears spurious focus in events can occur when
* the window is hidden. So we'll just check to see if
* the window is visible before actually handling the
* event
*/
if (gtk_widget_get_visible (widget))
if (gdk_event_get_event_type (event) != GDK_FOCUS_CHANGE)
return FALSE;
if (gdk_focus_event_get_in (event))
{
_gtk_window_set_is_active (window, TRUE);
if (gtk_window_has_mnemonic_modifier_pressed (window))
_gtk_window_schedule_mnemonics_visible (window);
}
}
else
{
_gtk_window_set_is_active (window, FALSE);
static void
gtk_window_focus_out (GtkWidget *widget)
{
GtkWindow *window = GTK_WINDOW (widget);
gtk_window_set_mnemonics_visible (window, FALSE);
}
_gtk_window_set_is_active (window, FALSE);
/* set the mnemonic-visible property to false */
gtk_window_set_mnemonics_visible (window, FALSE);
return TRUE;
}
static void