GDK W32: Adapt to event filter removal
Add a new W32 backend-specific message filtering mechanism. Works roughly the same way old event filtering did, but without events (events are GDK/X11 concept that never really made sense on W32), so there's no functionality for 'altering' events being emitted. If an event needs to be emitted in response to a message do it yourself. Implemented like this, it should give better performance than if we were to use GLib signals for this, since W32 sends a LOT of messages (unlike X11, which doesn't send events as often) all the time, and invoking the signal machinery on *each* message would probably be bad. https://bugzilla.gnome.org/show_bug.cgi?id=773299
This commit is contained in:
@@ -39,6 +39,127 @@
|
||||
|
||||
static int debug_indent = 0;
|
||||
|
||||
/**
|
||||
* gdk_win32_display_add_filter:
|
||||
* @display: a #GdkWin32Display
|
||||
* @function: filter callback
|
||||
* @data: data to pass to filter callback
|
||||
*
|
||||
* Adds an event filter to @window, allowing you to intercept messages
|
||||
* before they reach GDK. This is a low-level operation and makes it
|
||||
* easy to break GDK and/or GTK+, so you have to know what you're
|
||||
* doing.
|
||||
**/
|
||||
void
|
||||
gdk_win32_display_add_filter (GdkWin32Display *display,
|
||||
GdkWin32MessageFilterFunc function,
|
||||
gpointer data)
|
||||
{
|
||||
GList *tmp_list;
|
||||
GdkWin32MessageFilter *filter;
|
||||
|
||||
g_return_if_fail (GDK_IS_WIN32_DISPLAY (display));
|
||||
|
||||
tmp_list = display->filters;
|
||||
|
||||
for (tmp_list = display->filters; tmp_list; tmp_list = tmp_list->next)
|
||||
{
|
||||
filter = (GdkWin32MessageFilter *) tmp_list->data;
|
||||
|
||||
if ((filter->function == function) && (filter->data == data))
|
||||
{
|
||||
filter->ref_count++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
filter = g_new (GdkWin32MessageFilter, 1);
|
||||
filter->function = function;
|
||||
filter->data = data;
|
||||
filter->ref_count = 1;
|
||||
filter->removed = FALSE;
|
||||
|
||||
display->filters = g_list_append (display->filters, filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* _gdk_win32_message_filter_unref:
|
||||
* @display: A #GdkWin32Display
|
||||
* @filter: A message filter
|
||||
*
|
||||
* Release a reference to @filter. Note this function may
|
||||
* mutate the list storage, so you need to handle this
|
||||
* if iterating over a list of filters.
|
||||
*/
|
||||
void
|
||||
_gdk_win32_message_filter_unref (GdkWin32Display *display,
|
||||
GdkWin32MessageFilter *filter)
|
||||
{
|
||||
GList **filters;
|
||||
GList *tmp_list;
|
||||
|
||||
filters = &display->filters;
|
||||
|
||||
tmp_list = *filters;
|
||||
while (tmp_list)
|
||||
{
|
||||
GdkWin32MessageFilter *iter_filter = tmp_list->data;
|
||||
GList *node;
|
||||
|
||||
node = tmp_list;
|
||||
tmp_list = tmp_list->next;
|
||||
|
||||
if (iter_filter != filter)
|
||||
continue;
|
||||
|
||||
g_assert (iter_filter->ref_count > 0);
|
||||
|
||||
filter->ref_count--;
|
||||
if (filter->ref_count != 0)
|
||||
continue;
|
||||
|
||||
*filters = g_list_remove_link (*filters, node);
|
||||
g_free (filter);
|
||||
g_list_free_1 (node);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_win32_display_remove_filter:
|
||||
* @display: A #GdkWin32Display
|
||||
* @function: previously-added filter function
|
||||
* @data: user data for previously-added filter function
|
||||
*
|
||||
* Remove a filter previously added with gdk_win32_display_add_filter().
|
||||
*/
|
||||
void
|
||||
gdk_win32_display_remove_filter (GdkWin32Display *display,
|
||||
GdkWin32MessageFilterFunc function,
|
||||
gpointer data)
|
||||
{
|
||||
GList *tmp_list;
|
||||
GdkWin32MessageFilter *filter;
|
||||
|
||||
g_return_if_fail (GDK_IS_WIN32_DISPLAY (display));
|
||||
|
||||
tmp_list = display->filters;
|
||||
|
||||
while (tmp_list)
|
||||
{
|
||||
filter = (GdkWin32MessageFilter *) tmp_list->data;
|
||||
tmp_list = tmp_list->next;
|
||||
|
||||
if ((filter->function == function) && (filter->data == data))
|
||||
{
|
||||
filter->removed = TRUE;
|
||||
|
||||
_gdk_win32_message_filter_unref (display, filter);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static GdkMonitor *
|
||||
_gdk_win32_display_find_matching_monitor (GdkWin32Display *win32_display,
|
||||
GdkMonitor *needle)
|
||||
@@ -582,6 +703,9 @@ gdk_win32_display_finalize (GObject *object)
|
||||
|
||||
g_ptr_array_free (display_win32->monitors, TRUE);
|
||||
|
||||
while (display_win32->filters)
|
||||
_gdk_win32_message_filter_unref (display_win32, display_win32->filters->data);
|
||||
|
||||
G_OBJECT_CLASS (gdk_win32_display_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
|
||||
@@ -101,6 +101,9 @@ struct _GdkWin32Display
|
||||
/* Cursor Items (GdkCursor->HCURSOR) */
|
||||
GHashTable *cursors;
|
||||
GdkCursor *grab_cursor;
|
||||
|
||||
/* Message filters */
|
||||
GList *filters;
|
||||
};
|
||||
|
||||
struct _GdkWin32DisplayClass
|
||||
@@ -119,4 +122,14 @@ guint _gdk_win32_display_get_monitor_scale_factor (GdkWin32Display *win32_d
|
||||
HWND hwnd,
|
||||
gint *dpi);
|
||||
|
||||
typedef struct _GdkWin32MessageFilter GdkWin32MessageFilter;
|
||||
|
||||
struct _GdkWin32MessageFilter
|
||||
{
|
||||
GdkWin32MessageFilterFunc function;
|
||||
gpointer data;
|
||||
gboolean removed;
|
||||
guint ref_count;
|
||||
};
|
||||
|
||||
#endif /* __GDK_DISPLAY__WIN32_H__ */
|
||||
|
||||
@@ -697,27 +697,32 @@ close_it (gpointer data)
|
||||
|
||||
#endif
|
||||
|
||||
static GdkFilterReturn
|
||||
gdk_dropfiles_filter (GdkXEvent *xev,
|
||||
GdkEvent *event,
|
||||
gpointer data)
|
||||
static GdkWin32MessageFilterReturn
|
||||
gdk_dropfiles_filter (GdkWin32Display *display,
|
||||
MSG *msg,
|
||||
gint *ret_valp,
|
||||
gpointer data)
|
||||
{
|
||||
GdkSurface *window;
|
||||
GdkDragContext *context;
|
||||
GdkWin32DropContext *context_win32;
|
||||
GdkEvent *event;
|
||||
GString *result;
|
||||
MSG *msg = (MSG *) xev;
|
||||
HANDLE hdrop;
|
||||
POINT pt;
|
||||
gint nfiles, i;
|
||||
gchar *fileName, *linkedFile;
|
||||
|
||||
if (msg->message == WM_DROPFILES)
|
||||
{
|
||||
if (msg->message != WM_DROPFILES)
|
||||
return GDK_WIN32_MESSAGE_FILTER_CONTINUE;
|
||||
|
||||
GDK_NOTE (DND, g_print ("WM_DROPFILES: %p\n", msg->hwnd));
|
||||
|
||||
context = gdk_drop_context_new (gdk_surface_get_display (event->any.surface),
|
||||
window = gdk_win32_handle_table_lookup (msg->hwnd);
|
||||
|
||||
context = gdk_drop_context_new (display,
|
||||
NULL,
|
||||
event->any.surface,
|
||||
window,
|
||||
GDK_ACTION_COPY,
|
||||
GDK_DRAG_PROTO_WIN32_DROPFILES);
|
||||
context_win32 = GDK_WIN32_DROP_CONTEXT (context);
|
||||
@@ -730,14 +735,18 @@ gdk_dropfiles_filter (GdkXEvent *xev,
|
||||
|
||||
context->suggested_action = GDK_ACTION_COPY;
|
||||
current_dest_drag = context;
|
||||
event->any.type = GDK_DROP_START;
|
||||
event->dnd.context = current_dest_drag;
|
||||
gdk_event_set_device (event, gdk_drag_context_get_device (current_dest_drag));
|
||||
|
||||
hdrop = (HANDLE) msg->wParam;
|
||||
DragQueryPoint (hdrop, &pt);
|
||||
ClientToScreen (msg->hwnd, &pt);
|
||||
|
||||
event = gdk_event_new (GDK_DROP_START);
|
||||
|
||||
event->any.send_event = FALSE;
|
||||
g_set_object (&event->dnd.context, context);
|
||||
g_set_object (&event->any.surface, window);
|
||||
gdk_event_set_display (event, display);
|
||||
gdk_event_set_device (event, gdk_drag_context_get_device (context));
|
||||
event->dnd.x_root = pt.x / context_win32->scale + _gdk_offset_x;
|
||||
event->dnd.y_root = pt.y / context_win32->scale + _gdk_offset_y;
|
||||
event->dnd.time = _gdk_win32_get_next_tick (msg->time);
|
||||
@@ -813,14 +822,25 @@ gdk_dropfiles_filter (GdkXEvent *xev,
|
||||
g_string_append (result, "\015\012");
|
||||
}
|
||||
|
||||
/* FIXME: this call is currently a no-op, but it should
|
||||
* stash the string somewhere, and later produce it,
|
||||
* maybe in response to gdk_win32_drop_context_read_async()?
|
||||
*/
|
||||
_gdk_dropfiles_store (result->str);
|
||||
g_string_free (result, FALSE);
|
||||
|
||||
GDK_NOTE (EVENTS, _gdk_win32_print_event (event));
|
||||
_gdk_event_emit (event);
|
||||
gdk_event_free (event);
|
||||
|
||||
DragFinish (hdrop);
|
||||
return GDK_FILTER_TRANSLATE;
|
||||
}
|
||||
else
|
||||
return GDK_FILTER_CONTINUE;
|
||||
|
||||
gdk_display_put_event (display, event);
|
||||
gdk_event_free (event);
|
||||
|
||||
*ret_valp = 0;
|
||||
|
||||
return GDK_WIN32_MESSAGE_FILTER_REMOVE;
|
||||
}
|
||||
|
||||
/* Destination side */
|
||||
|
||||
@@ -1016,43 +1016,30 @@ fill_key_event_string (GdkEvent *event)
|
||||
}
|
||||
}
|
||||
|
||||
static GdkFilterReturn
|
||||
apply_event_filters (GdkSurface *window,
|
||||
MSG *msg,
|
||||
GList **filters)
|
||||
static GdkWin32MessageFilterReturn
|
||||
apply_message_filters (GdkDisplay *display,
|
||||
MSG *msg,
|
||||
gint *ret_valp,
|
||||
GList **filters)
|
||||
{
|
||||
GdkFilterReturn result = GDK_FILTER_CONTINUE;
|
||||
GdkEvent *event;
|
||||
GdkDisplay *display;
|
||||
GdkWin32MessageFilterReturn result = GDK_WIN32_MESSAGE_FILTER_CONTINUE;
|
||||
GList *node;
|
||||
GList *tmp_list;
|
||||
|
||||
event = gdk_event_new (GDK_NOTHING);
|
||||
event->any.surface = g_object_ref (window);
|
||||
event->any.flags |= GDK_EVENT_PENDING;
|
||||
|
||||
display = gdk_display_get_default ();
|
||||
|
||||
/* I think GdkFilterFunc semantics require the passed-in event
|
||||
* to already be in the queue. The filter func can generate
|
||||
* more events and append them after it if it likes.
|
||||
*/
|
||||
node = _gdk_event_queue_append (display, event);
|
||||
|
||||
tmp_list = *filters;
|
||||
while (tmp_list)
|
||||
{
|
||||
GdkEventFilter *filter = (GdkEventFilter *) tmp_list->data;
|
||||
GdkWin32MessageFilter *filter = (GdkWin32MessageFilter *) tmp_list->data;
|
||||
GList *node;
|
||||
|
||||
if ((filter->flags & GDK_EVENT_FILTER_REMOVED) != 0)
|
||||
if (filter->removed)
|
||||
{
|
||||
tmp_list = tmp_list->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
filter->ref_count++;
|
||||
result = filter->function (msg, event, filter->data);
|
||||
result = filter->function (display, msg, ret_valp, filter->data);
|
||||
|
||||
/* get the next node after running the function since the
|
||||
function may add or remove a next node */
|
||||
@@ -1067,23 +1054,10 @@ apply_event_filters (GdkSurface *window,
|
||||
g_free (filter);
|
||||
}
|
||||
|
||||
if (result != GDK_FILTER_CONTINUE)
|
||||
if (result != GDK_WIN32_MESSAGE_FILTER_CONTINUE)
|
||||
break;
|
||||
}
|
||||
|
||||
if (result == GDK_FILTER_CONTINUE || result == GDK_FILTER_REMOVE)
|
||||
{
|
||||
_gdk_event_queue_remove_link (display, node);
|
||||
g_list_free_1 (node);
|
||||
gdk_event_free (event);
|
||||
}
|
||||
else /* GDK_FILTER_TRANSLATE */
|
||||
{
|
||||
event->any.flags &= ~GDK_EVENT_PENDING;
|
||||
fixup_event (event);
|
||||
GDK_NOTE (EVENTS, _gdk_win32_print_event (event));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -2290,22 +2264,19 @@ gdk_event_translate (MSG *msg,
|
||||
STGMEDIUM *property_change_data;
|
||||
|
||||
display = gdk_display_get_default ();
|
||||
window = gdk_win32_handle_table_lookup (msg->hwnd);
|
||||
win32_display = GDK_WIN32_DISPLAY (display);
|
||||
|
||||
if (_gdk_default_filters)
|
||||
if (win32_display->filters)
|
||||
{
|
||||
/* Apply global filters */
|
||||
/* Apply display filters */
|
||||
GdkWin32MessageFilterReturn result = apply_message_filters (win32_display, msg, ret_valp, &win32_display->filters);
|
||||
|
||||
GdkFilterReturn result = apply_event_filters (window, msg, &_gdk_default_filters);
|
||||
|
||||
/* If result is GDK_FILTER_CONTINUE, we continue as if nothing
|
||||
* happened. If it is GDK_FILTER_REMOVE or GDK_FILTER_TRANSLATE,
|
||||
* we return TRUE, and DefWindowProcW() will not be called.
|
||||
*/
|
||||
if (result == GDK_FILTER_REMOVE || result == GDK_FILTER_TRANSLATE)
|
||||
if (result == GDK_WIN32_MESSAGE_FILTER_REMOVE)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
window = gdk_win32_handle_table_lookup (msg->hwnd);
|
||||
|
||||
if (window == NULL)
|
||||
{
|
||||
/* XXX Handle WM_QUIT here ? */
|
||||
@@ -2342,19 +2313,6 @@ gdk_event_translate (MSG *msg,
|
||||
*/
|
||||
#define return GOTO_DONE_INSTEAD
|
||||
|
||||
if (!GDK_SURFACE_DESTROYED (window) && window->filters)
|
||||
{
|
||||
/* Apply per-window filters */
|
||||
|
||||
GdkFilterReturn result = apply_event_filters (window, msg, &window->filters);
|
||||
|
||||
if (result == GDK_FILTER_REMOVE || result == GDK_FILTER_TRANSLATE)
|
||||
{
|
||||
return_val = TRUE;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
if (msg->message == aerosnap_message)
|
||||
_gdk_win32_surface_handle_aerosnap (gdk_surface_get_toplevel (window),
|
||||
(GdkWin32AeroSnapCombo) msg->wParam);
|
||||
|
||||
@@ -61,6 +61,50 @@ GDK_AVAILABLE_IN_ALL
|
||||
HCURSOR gdk_win32_display_get_hcursor (GdkDisplay *display,
|
||||
GdkCursor *cursor);
|
||||
|
||||
/**
|
||||
* GdkWin32MessageFilterReturn:
|
||||
* @GDK_WIN32_MESSAGE_FILTER_CONTINUE: event not handled, continue processing.
|
||||
* @GDK_WIN32_MESSAGE_FILTER_REMOVE: event handled, terminate processing.
|
||||
*
|
||||
* Specifies the result of applying a #GdkWin32MessageFilterFunc to a Windows message.
|
||||
*/
|
||||
typedef enum {
|
||||
GDK_WIN32_MESSAGE_FILTER_CONTINUE, /* Message not handled, continue processing */
|
||||
GDK_WIN32_MESSAGE_FILTER_REMOVE /* Terminate processing, removing message */
|
||||
} GdkWin32MessageFilterReturn;
|
||||
|
||||
/**
|
||||
* GdkWin32MessageFilterFunc:
|
||||
* @msg: the Windows message to filter.
|
||||
* @return_value: a location to store the return value for the message
|
||||
* @data: (closure): user data set when the filter was installed.
|
||||
*
|
||||
* Specifies the type of function used to filter Windows messages before they are
|
||||
* processed by GDK Win32 backend.
|
||||
*
|
||||
* The @return_value must be set, if this function returns
|
||||
* #GDK_WIN32_MESSAGE_FILTER_REMOVE, otherwise it is ignored.
|
||||
*
|
||||
* The event translation and message filtering are orthogonal -
|
||||
* if a filter wants a GDK event queued, it should do that itself.
|
||||
*
|
||||
* Returns: a #GdkWin32MessageFilterReturn value.
|
||||
*/
|
||||
typedef GdkWin32MessageFilterReturn (*GdkWin32MessageFilterFunc) (GdkWin32Display *display,
|
||||
MSG *message,
|
||||
gint *return_value,
|
||||
gpointer data);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_win32_display_add_filter (GdkWin32Display *display,
|
||||
GdkWin32MessageFilterFunc function,
|
||||
gpointer data);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_win32_display_remove_filter (GdkWin32Display *display,
|
||||
GdkWin32MessageFilterFunc function,
|
||||
gpointer data);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_WIN32_DISPLAY_H__ */
|
||||
|
||||
@@ -113,9 +113,10 @@ static void gtk_im_context_ime_set_use_preedit (GtkIMContext *context,
|
||||
/* GtkIMContextIME's private functions */
|
||||
static void gtk_im_context_ime_set_preedit_font (GtkIMContext *context);
|
||||
|
||||
static GdkFilterReturn
|
||||
gtk_im_context_ime_message_filter (GdkXEvent *xevent,
|
||||
GdkEvent *event,
|
||||
static GdkWin32MessageFilterReturn
|
||||
gtk_im_context_ime_message_filter (GdkWin32Display *display,
|
||||
MSG *msg,
|
||||
gint *ret_valp,
|
||||
gpointer data);
|
||||
static void get_window_position (GdkSurface *win,
|
||||
gint *x,
|
||||
@@ -661,8 +662,8 @@ gtk_im_context_ime_focus_in (GtkIMContext *context)
|
||||
toplevel = gdk_surface_get_toplevel (context_ime->client_surface);
|
||||
if (GDK_IS_SURFACE (toplevel))
|
||||
{
|
||||
gdk_surface_add_filter (toplevel,
|
||||
gtk_im_context_ime_message_filter, context_ime);
|
||||
gdk_win32_display_add_filter (gdk_surface_get_display (toplevel),
|
||||
gtk_im_context_ime_message_filter, context_ime);
|
||||
context_ime->toplevel = toplevel;
|
||||
}
|
||||
else
|
||||
@@ -783,9 +784,9 @@ gtk_im_context_ime_focus_out (GtkIMContext *context)
|
||||
toplevel = gdk_surface_get_toplevel (context_ime->client_surface);
|
||||
if (GDK_IS_SURFACE (toplevel))
|
||||
{
|
||||
gdk_surface_remove_filter (toplevel,
|
||||
gtk_im_context_ime_message_filter,
|
||||
context_ime);
|
||||
gdk_win32_display_remove_filter (gdk_surface_get_display (toplevel),
|
||||
gtk_im_context_ime_message_filter,
|
||||
context_ime);
|
||||
context_ime->toplevel = NULL;
|
||||
}
|
||||
else
|
||||
@@ -983,17 +984,17 @@ ERROR_OUT:
|
||||
}
|
||||
|
||||
|
||||
static GdkFilterReturn
|
||||
gtk_im_context_ime_message_filter (GdkXEvent *xevent,
|
||||
GdkEvent *event,
|
||||
gpointer data)
|
||||
static GdkWin32MessageFilterReturn
|
||||
gtk_im_context_ime_message_filter (GdkWin32Display *display,
|
||||
MSG *msg,
|
||||
gint *ret_valp,
|
||||
gpointer data)
|
||||
{
|
||||
GtkIMContext *context;
|
||||
GtkIMContextIME *context_ime;
|
||||
HWND hwnd;
|
||||
HIMC himc;
|
||||
MSG *msg = (MSG *) xevent;
|
||||
GdkFilterReturn retval = GDK_FILTER_CONTINUE;
|
||||
GdkWin32MessageFilterReturn retval = GDK_WIN32_MESSAGE_FILTER_CONTINUE;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_IM_CONTEXT_IME (data), retval);
|
||||
|
||||
@@ -1002,11 +1003,16 @@ gtk_im_context_ime_message_filter (GdkXEvent *xevent,
|
||||
if (!context_ime->focus)
|
||||
return retval;
|
||||
|
||||
if (gdk_win32_surface_get_impl_hwnd (context_ime->toplevel) != msg->hwnd)
|
||||
return retval;
|
||||
|
||||
hwnd = gdk_win32_surface_get_impl_hwnd (context_ime->client_surface);
|
||||
himc = ImmGetContext (hwnd);
|
||||
if (!himc)
|
||||
return retval;
|
||||
|
||||
*ret_valp = 0;
|
||||
|
||||
switch (msg->message)
|
||||
{
|
||||
case WM_IME_COMPOSITION:
|
||||
@@ -1063,11 +1069,11 @@ gtk_im_context_ime_message_filter (GdkXEvent *xevent,
|
||||
}
|
||||
|
||||
if (context_ime->commit_string)
|
||||
retval = TRUE;
|
||||
retval = GDK_WIN32_MESSAGE_FILTER_REMOVE;
|
||||
}
|
||||
|
||||
if (context_ime->use_preedit)
|
||||
retval = TRUE;
|
||||
retval = GDK_WIN32_MESSAGE_FILTER_REMOVE;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1076,7 +1082,7 @@ gtk_im_context_ime_message_filter (GdkXEvent *xevent,
|
||||
gtk_im_context_ime_set_cursor_location (context, NULL);
|
||||
g_signal_emit_by_name (context, "preedit-start");
|
||||
if (context_ime->use_preedit)
|
||||
retval = TRUE;
|
||||
retval = GDK_WIN32_MESSAGE_FILTER_REMOVE;
|
||||
break;
|
||||
|
||||
case WM_IME_ENDCOMPOSITION:
|
||||
@@ -1092,7 +1098,7 @@ gtk_im_context_ime_message_filter (GdkXEvent *xevent,
|
||||
}
|
||||
|
||||
if (context_ime->use_preedit)
|
||||
retval = TRUE;
|
||||
retval = GDK_WIN32_MESSAGE_FILTER_REMOVE;
|
||||
break;
|
||||
|
||||
case WM_IME_NOTIFY:
|
||||
@@ -1161,26 +1167,5 @@ cb_client_widget_hierarchy_changed (GtkWidget *widget,
|
||||
if (context_ime->toplevel == new_toplevel)
|
||||
return;
|
||||
|
||||
/* remove filter from old toplevel */
|
||||
if (GDK_IS_SURFACE (context_ime->toplevel))
|
||||
{
|
||||
gdk_surface_remove_filter (context_ime->toplevel,
|
||||
gtk_im_context_ime_message_filter,
|
||||
context_ime);
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
|
||||
/* add filter to new toplevel */
|
||||
if (GDK_IS_SURFACE (new_toplevel))
|
||||
{
|
||||
gdk_surface_add_filter (new_toplevel,
|
||||
gtk_im_context_ime_message_filter, context_ime);
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
|
||||
context_ime->toplevel = new_toplevel;
|
||||
}
|
||||
|
||||
@@ -147,22 +147,18 @@ gtk_win32_theme_equal (GtkWin32Theme *theme1,
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
|
||||
static GdkFilterReturn
|
||||
invalidate_win32_themes (GdkXEvent *xevent,
|
||||
GdkEvent *event,
|
||||
gpointer unused)
|
||||
static GdkWin32MessageFilterReturn
|
||||
invalidate_win32_themes (GdkWin32Display *display,
|
||||
MSG *msg,
|
||||
gint *ret_valp,
|
||||
gpointer data)
|
||||
{
|
||||
GHashTableIter iter;
|
||||
gboolean theme_was_open = FALSE;
|
||||
gpointer theme;
|
||||
MSG *msg;
|
||||
|
||||
if (!GDK_IS_WIN32_SURFACE (event->any.surface))
|
||||
return GDK_FILTER_CONTINUE;
|
||||
|
||||
msg = (MSG *) xevent;
|
||||
if (msg->message != WM_THEMECHANGED)
|
||||
return GDK_FILTER_CONTINUE;
|
||||
return GDK_WIN32_MESSAGE_FILTER_CONTINUE;
|
||||
|
||||
g_hash_table_iter_init (&iter, themes_by_class);
|
||||
while (g_hash_table_iter_next (&iter, NULL, &theme))
|
||||
@@ -170,9 +166,9 @@ invalidate_win32_themes (GdkXEvent *xevent,
|
||||
theme_was_open |= gtk_win32_theme_close (theme);
|
||||
}
|
||||
if (theme_was_open)
|
||||
gtk_style_context_reset_widgets (gdk_surface_get_display (event->any.surface));
|
||||
gtk_style_context_reset_widgets (display);
|
||||
|
||||
return GDK_FILTER_CONTINUE;
|
||||
return GDK_WIN32_MESSAGE_FILTER_CONTINUE;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -233,7 +229,7 @@ gtk_win32_theme_init (void)
|
||||
use_xp_theme = FALSE;
|
||||
}
|
||||
|
||||
gdk_surface_add_filter (NULL, invalidate_win32_themes, NULL);
|
||||
gdk_win32_display_add_filter (gdk_display_get_default (), invalidate_win32_themes, NULL);
|
||||
}
|
||||
|
||||
static HTHEME
|
||||
|
||||
Reference in New Issue
Block a user