Commit 3fe86a48 authored by Owen Taylor's avatar Owen Taylor Committed by Owen Taylor

Protect against reentrancy problems by emitting ::preedit_changed at the

Fri May 17 14:40:24 2002  Owen Taylor  <otaylor@redhat.com>

        * gtk/gtkimmulticontext.c (gtk_im_multicontext_set_slave):
        Protect against reentrancy problems by emitting
        ::preedit_changed at the end, fixing input context
        leak. (Yao Zhang)

        * modules/input/gtkimcontextxim.c (status_window_free):
        Patch from Federico Mena Quintero to fix problem where
        references to IMContextXIM were kept around after
        module was unloaded.

        * gtk/gtkdnd.c (gtk_drag_dest_set): NULL initialize
        proxy window.
parent 0274195e
Fri May 17 14:40:24 2002 Owen Taylor <otaylor@redhat.com>
* gtk/gtkimmulticontext.c (gtk_im_multicontext_set_slave):
Protect against reentrancy problems by emitting
::preedit_changed at the end, fixing input context
leak. (Yao Zhang)
* modules/input/gtkimcontextxim.c (status_window_free):
Patch from Federico Mena Quintero to fix problem where
references to IMContextXIM were kept around after
module was unloaded.
* gtk/gtkdnd.c (gtk_drag_dest_set): NULL initialize
proxy window.
Fri May 17 13:56:23 2002 Owen Taylor <otaylor@redhat.com>
* gtk/gtkplug.c (gtk_plug_filter_func): Fix a missing
......
Fri May 17 14:40:24 2002 Owen Taylor <otaylor@redhat.com>
* gtk/gtkimmulticontext.c (gtk_im_multicontext_set_slave):
Protect against reentrancy problems by emitting
::preedit_changed at the end, fixing input context
leak. (Yao Zhang)
* modules/input/gtkimcontextxim.c (status_window_free):
Patch from Federico Mena Quintero to fix problem where
references to IMContextXIM were kept around after
module was unloaded.
* gtk/gtkdnd.c (gtk_drag_dest_set): NULL initialize
proxy window.
Fri May 17 13:56:23 2002 Owen Taylor <otaylor@redhat.com>
* gtk/gtkplug.c (gtk_plug_filter_func): Fix a missing
......
Fri May 17 14:40:24 2002 Owen Taylor <otaylor@redhat.com>
* gtk/gtkimmulticontext.c (gtk_im_multicontext_set_slave):
Protect against reentrancy problems by emitting
::preedit_changed at the end, fixing input context
leak. (Yao Zhang)
* modules/input/gtkimcontextxim.c (status_window_free):
Patch from Federico Mena Quintero to fix problem where
references to IMContextXIM were kept around after
module was unloaded.
* gtk/gtkdnd.c (gtk_drag_dest_set): NULL initialize
proxy window.
Fri May 17 13:56:23 2002 Owen Taylor <otaylor@redhat.com>
* gtk/gtkplug.c (gtk_plug_filter_func): Fix a missing
......
Fri May 17 14:40:24 2002 Owen Taylor <otaylor@redhat.com>
* gtk/gtkimmulticontext.c (gtk_im_multicontext_set_slave):
Protect against reentrancy problems by emitting
::preedit_changed at the end, fixing input context
leak. (Yao Zhang)
* modules/input/gtkimcontextxim.c (status_window_free):
Patch from Federico Mena Quintero to fix problem where
references to IMContextXIM were kept around after
module was unloaded.
* gtk/gtkdnd.c (gtk_drag_dest_set): NULL initialize
proxy window.
Fri May 17 13:56:23 2002 Owen Taylor <otaylor@redhat.com>
* gtk/gtkplug.c (gtk_plug_filter_func): Fix a missing
......
Fri May 17 14:40:24 2002 Owen Taylor <otaylor@redhat.com>
* gtk/gtkimmulticontext.c (gtk_im_multicontext_set_slave):
Protect against reentrancy problems by emitting
::preedit_changed at the end, fixing input context
leak. (Yao Zhang)
* modules/input/gtkimcontextxim.c (status_window_free):
Patch from Federico Mena Quintero to fix problem where
references to IMContextXIM were kept around after
module was unloaded.
* gtk/gtkdnd.c (gtk_drag_dest_set): NULL initialize
proxy window.
Fri May 17 13:56:23 2002 Owen Taylor <otaylor@redhat.com>
* gtk/gtkplug.c (gtk_plug_filter_func): Fix a missing
......
Fri May 17 14:40:24 2002 Owen Taylor <otaylor@redhat.com>
* gtk/gtkimmulticontext.c (gtk_im_multicontext_set_slave):
Protect against reentrancy problems by emitting
::preedit_changed at the end, fixing input context
leak. (Yao Zhang)
* modules/input/gtkimcontextxim.c (status_window_free):
Patch from Federico Mena Quintero to fix problem where
references to IMContextXIM were kept around after
module was unloaded.
* gtk/gtkdnd.c (gtk_drag_dest_set): NULL initialize
proxy window.
Fri May 17 13:56:23 2002 Owen Taylor <otaylor@redhat.com>
* gtk/gtkplug.c (gtk_plug_filter_func): Fix a missing
......
......@@ -867,9 +867,9 @@ gtk_drag_dest_set (GtkWidget *widget,
site->target_list = gtk_target_list_new (targets, n_targets);
else
site->target_list = NULL;
site->actions = actions;
site->do_proxy = FALSE;
site->proxy_window = NULL;
gtk_drag_dest_set_internal (widget, site);
}
......
......@@ -157,6 +157,8 @@ gtk_im_multicontext_set_slave (GtkIMMulticontext *multicontext,
GtkIMContext *slave,
gboolean finalizing)
{
gboolean need_preedit_changed = FALSE;
if (multicontext->slave)
{
if (!finalizing)
......@@ -179,7 +181,7 @@ gtk_im_multicontext_set_slave (GtkIMMulticontext *multicontext,
multicontext->slave = NULL;
if (!finalizing)
g_signal_emit_by_name (multicontext, "preedit_changed");
need_preedit_changed = TRUE;
}
multicontext->slave = slave;
......@@ -210,6 +212,9 @@ gtk_im_multicontext_set_slave (GtkIMMulticontext *multicontext,
if (multicontext->client_window)
gtk_im_context_set_client_window (slave, multicontext->client_window);
}
if (need_preedit_changed)
g_signal_emit_by_name (multicontext, "preedit_changed");
}
static GtkIMContext *
......
......@@ -25,6 +25,8 @@
#include "gtk/gtkwindow.h"
#include "gtkimcontextxim.h"
typedef struct _StatusWindow StatusWindow;
struct _GtkXIMInfo
{
GdkDisplay *display;
......@@ -33,6 +35,19 @@ struct _GtkXIMInfo
XIMStyle style;
};
/* A context status window; these are kept in the status_windows list. */
struct _StatusWindow
{
GtkWidget *window;
/* Toplevel window to which the status window corresponds */
GtkWidget *toplevel;
/* Signal connection ids; we connect to the toplevel */
guint destroy_handler_id;
guint configure_handler_id;
};
static void gtk_im_context_xim_class_init (GtkIMContextXIMClass *class);
static void gtk_im_context_xim_init (GtkIMContextXIM *im_context_xim);
static void gtk_im_context_xim_finalize (GObject *obj);
......@@ -64,6 +79,9 @@ GType gtk_type_im_context_xim = 0;
GSList *open_ims = NULL;
/* List of status windows for different toplevels */
static GSList *status_windows = NULL;
void
gtk_im_context_xim_register_type (GTypeModule *type_module)
{
......@@ -948,34 +966,39 @@ status_window_style_set (GtkWidget *toplevel,
gtk_widget_modify_fg (label, i, &toplevel->style->text[i]);
}
/* Frees a status window and removes its link from the status_windows list */
static void
status_window_destroy (GtkWidget *toplevel,
GtkWidget *status_window)
status_window_free (StatusWindow *status_window)
{
gtk_widget_destroy (status_window);
g_object_set_data (G_OBJECT (toplevel), "gtk-im-xim-status-window", NULL);
status_windows = g_slist_remove (status_windows, status_window);
g_signal_handler_disconnect (status_window->toplevel, status_window->destroy_handler_id);
g_signal_handler_disconnect (status_window->toplevel, status_window->configure_handler_id);
gtk_widget_destroy (status_window->window);
g_object_set_data (G_OBJECT (status_window->toplevel), "gtk-im-xim-status-window", NULL);
g_free (status_window);
}
static gboolean
status_window_configure (GtkWidget *toplevel,
GdkEventConfigure *event,
GtkWidget *status_window)
StatusWindow *status_window)
{
GdkRectangle rect;
GtkRequisition requisition;
gint y;
gint height = gdk_screen_get_height (gtk_widget_get_screen (toplevel));
gdk_window_get_frame_extents (toplevel->window, &rect);
gtk_widget_size_request (status_window, &requisition);
gtk_widget_size_request (status_window->window, &requisition);
if (rect.y + rect.height + requisition.height < height)
y = rect.y + rect.height;
else
y = height - requisition.height;
gtk_window_move (GTK_WINDOW (status_window), rect.x, y);
gtk_window_move (GTK_WINDOW (status_window->window), rect.x, y);
return FALSE;
}
......@@ -986,7 +1009,8 @@ status_window_get (GtkIMContextXIM *context_xim,
{
GdkWindow *toplevel_gdk;
GtkWidget *toplevel;
GtkWidget *status_window;
GtkWidget *window;
StatusWindow *status_window;
GtkWidget *status_label;
if (!context_xim->client_window)
......@@ -1007,35 +1031,45 @@ status_window_get (GtkIMContextXIM *context_xim,
return NULL;
status_window = g_object_get_data (G_OBJECT (toplevel), "gtk-im-xim-status-window");
if (status_window || !create)
return status_window;
if (status_window)
return status_window->window;
else if (!create)
return NULL;
status_window = g_new (StatusWindow, 1);
status_window->window = gtk_window_new (GTK_WINDOW_POPUP);
status_window->toplevel = toplevel;
status_windows = g_slist_prepend (status_windows, status_window);
status_window = gtk_window_new (GTK_WINDOW_POPUP);
window = status_window->window;
gtk_window_set_policy (GTK_WINDOW (status_window), FALSE, FALSE, FALSE);
gtk_widget_set_app_paintable (status_window, TRUE);
gtk_window_set_policy (GTK_WINDOW (window), FALSE, FALSE, FALSE);
gtk_widget_set_app_paintable (window, TRUE);
status_label = gtk_label_new ("");
gtk_misc_set_padding (GTK_MISC (status_label), 1, 1);
gtk_widget_show (status_label);
gtk_container_add (GTK_CONTAINER (status_window), status_label);
gtk_container_add (GTK_CONTAINER (window), status_label);
g_signal_connect (toplevel, "destroy",
G_CALLBACK (status_window_destroy), status_window);
g_signal_connect (toplevel, "configure_event",
G_CALLBACK (status_window_configure), status_window);
status_window->destroy_handler_id = g_signal_connect_swapped (toplevel, "destroy",
G_CALLBACK (status_window_free),
status_window);
status_window->configure_handler_id = g_signal_connect (toplevel, "configure_event",
G_CALLBACK (status_window_configure),
status_window);
status_window_configure (toplevel, NULL, status_window);
g_signal_connect (status_window, "style_set",
g_signal_connect (window, "style_set",
G_CALLBACK (status_window_style_set), status_label);
g_signal_connect (status_window, "expose_event",
g_signal_connect (window, "expose_event",
G_CALLBACK (status_window_expose_event), NULL);
g_object_set_data (G_OBJECT (toplevel), "gtk-im-xim-status-window", status_window);
return status_window;
return window;
}
static gboolean
......@@ -1086,3 +1120,16 @@ status_window_set_text (GtkIMContextXIM *context_xim,
gtk_widget_hide (status_window);
}
}
/**
* gtk_im_context_xim_shutdown:
*
* Destroys all the status windows that are kept by the XIM contexts. This
* function should only be called by the XIM module exit routine.
**/
void
gtk_im_context_xim_shutdown (void)
{
while (status_windows)
status_window_free (status_windows->data);
}
......@@ -84,6 +84,8 @@ struct _GtkIMContextXIMClass
void gtk_im_context_xim_register_type (GTypeModule *type_module);
GtkIMContext *gtk_im_context_xim_new (void);
void gtk_im_context_xim_shutdown (void);
#ifdef __cplusplus
}
#endif /* __cplusplus */
......
......@@ -43,6 +43,7 @@ im_module_init (GTypeModule *type_module)
void
im_module_exit (void)
{
gtk_im_context_xim_shutdown ();
}
void
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment