diff options
-rw-r--r-- | ChangeLog | 31 | ||||
-rw-r--r-- | ChangeLog.pre-2-10 | 31 | ||||
-rw-r--r-- | ChangeLog.pre-2-6 | 31 | ||||
-rw-r--r-- | ChangeLog.pre-2-8 | 31 | ||||
-rw-r--r-- | docs/reference/ChangeLog | 5 | ||||
-rw-r--r-- | docs/reference/gdk-pixbuf/tmpl/module_interface.sgml | 10 | ||||
-rw-r--r-- | docs/reference/gdk/gdk-sections.txt | 2 | ||||
-rw-r--r-- | docs/reference/gdk/tmpl/events.sgml | 1 | ||||
-rw-r--r-- | docs/reference/gdk/tmpl/gdkdisplay.sgml | 19 | ||||
-rw-r--r-- | docs/reference/gtk/tmpl/gtkenums.sgml | 4 | ||||
-rw-r--r-- | gdk/gdkdisplay.h | 6 | ||||
-rw-r--r-- | gdk/gdkevents.h | 24 | ||||
-rw-r--r-- | gdk/x11/gdkdisplay-x11.c | 80 | ||||
-rw-r--r-- | gdk/x11/gdkdisplay-x11.h | 4 | ||||
-rw-r--r-- | gdk/x11/gdkevents-x11.c | 22 | ||||
-rw-r--r-- | gtk/gtkclipboard.c | 135 | ||||
-rw-r--r-- | gtk/gtkclipboard.h | 3 | ||||
-rw-r--r-- | gtk/gtkmain.c | 6 |
18 files changed, 402 insertions, 43 deletions
@@ -1,5 +1,36 @@ 2004-05-18 Matthias Clasen <mclasen@redhat.com> + * configure.in: Check for XFIXES extension. + + * gdk/x11/gdkdisplay-x11.h (struct _GdkDisplayX11): Add + a gboolean have_xfixes member. + + * gdk/x11/gdkdisplay-x11.c (gdk_display_open): Register + XFIXES events and set have_xfixes. + + * gdk/gdkevents.h (GdkEventType): Add GDK_OWNER_CHANGE. + (GdkEventOwnerChange): New event struct for owner change events. + (GdkOwnerChange): New enum for the reason field of GdkEventOwnerChange. + + * gdk/x11/gdkevents-x11.c (gdk_event_translate): Translate + XFixesSelectionNotify events into GdkEventOwnerChange events. + + * gdk/gdkdisplay.h: + * gdk/x11/gdkdisplay-x11.c (gdk_display_supports_selection_notification): + (gdk_display_request_selection_notification): New api + to support selection ownership notification. + + * gtk/gtkclipboard.h: + * gtk/gtkclipboard.c (_gtk_clipboard_handle_event): New private + api to handle owner change events. + (clipboard_peek): Refactored out the body of + gtk_clipboard_get_for_display() for use in _gtk_clipboard_handle_event(). + + * gtk/gtkmain.c (gtk_main_do_event): Handle GDK_OWNER_CHANGE events + by calling _gtk_clipboard_handle_event(). + +2004-05-18 Matthias Clasen <mclasen@redhat.com> + * gtk/gtkintl.h: Include glib/gi18n-lib.h and only define the P_() macros ourselves. diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index f50fab73b..fd8cdd184 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,5 +1,36 @@ 2004-05-18 Matthias Clasen <mclasen@redhat.com> + * configure.in: Check for XFIXES extension. + + * gdk/x11/gdkdisplay-x11.h (struct _GdkDisplayX11): Add + a gboolean have_xfixes member. + + * gdk/x11/gdkdisplay-x11.c (gdk_display_open): Register + XFIXES events and set have_xfixes. + + * gdk/gdkevents.h (GdkEventType): Add GDK_OWNER_CHANGE. + (GdkEventOwnerChange): New event struct for owner change events. + (GdkOwnerChange): New enum for the reason field of GdkEventOwnerChange. + + * gdk/x11/gdkevents-x11.c (gdk_event_translate): Translate + XFixesSelectionNotify events into GdkEventOwnerChange events. + + * gdk/gdkdisplay.h: + * gdk/x11/gdkdisplay-x11.c (gdk_display_supports_selection_notification): + (gdk_display_request_selection_notification): New api + to support selection ownership notification. + + * gtk/gtkclipboard.h: + * gtk/gtkclipboard.c (_gtk_clipboard_handle_event): New private + api to handle owner change events. + (clipboard_peek): Refactored out the body of + gtk_clipboard_get_for_display() for use in _gtk_clipboard_handle_event(). + + * gtk/gtkmain.c (gtk_main_do_event): Handle GDK_OWNER_CHANGE events + by calling _gtk_clipboard_handle_event(). + +2004-05-18 Matthias Clasen <mclasen@redhat.com> + * gtk/gtkintl.h: Include glib/gi18n-lib.h and only define the P_() macros ourselves. diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index f50fab73b..fd8cdd184 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,5 +1,36 @@ 2004-05-18 Matthias Clasen <mclasen@redhat.com> + * configure.in: Check for XFIXES extension. + + * gdk/x11/gdkdisplay-x11.h (struct _GdkDisplayX11): Add + a gboolean have_xfixes member. + + * gdk/x11/gdkdisplay-x11.c (gdk_display_open): Register + XFIXES events and set have_xfixes. + + * gdk/gdkevents.h (GdkEventType): Add GDK_OWNER_CHANGE. + (GdkEventOwnerChange): New event struct for owner change events. + (GdkOwnerChange): New enum for the reason field of GdkEventOwnerChange. + + * gdk/x11/gdkevents-x11.c (gdk_event_translate): Translate + XFixesSelectionNotify events into GdkEventOwnerChange events. + + * gdk/gdkdisplay.h: + * gdk/x11/gdkdisplay-x11.c (gdk_display_supports_selection_notification): + (gdk_display_request_selection_notification): New api + to support selection ownership notification. + + * gtk/gtkclipboard.h: + * gtk/gtkclipboard.c (_gtk_clipboard_handle_event): New private + api to handle owner change events. + (clipboard_peek): Refactored out the body of + gtk_clipboard_get_for_display() for use in _gtk_clipboard_handle_event(). + + * gtk/gtkmain.c (gtk_main_do_event): Handle GDK_OWNER_CHANGE events + by calling _gtk_clipboard_handle_event(). + +2004-05-18 Matthias Clasen <mclasen@redhat.com> + * gtk/gtkintl.h: Include glib/gi18n-lib.h and only define the P_() macros ourselves. diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index f50fab73b..fd8cdd184 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,5 +1,36 @@ 2004-05-18 Matthias Clasen <mclasen@redhat.com> + * configure.in: Check for XFIXES extension. + + * gdk/x11/gdkdisplay-x11.h (struct _GdkDisplayX11): Add + a gboolean have_xfixes member. + + * gdk/x11/gdkdisplay-x11.c (gdk_display_open): Register + XFIXES events and set have_xfixes. + + * gdk/gdkevents.h (GdkEventType): Add GDK_OWNER_CHANGE. + (GdkEventOwnerChange): New event struct for owner change events. + (GdkOwnerChange): New enum for the reason field of GdkEventOwnerChange. + + * gdk/x11/gdkevents-x11.c (gdk_event_translate): Translate + XFixesSelectionNotify events into GdkEventOwnerChange events. + + * gdk/gdkdisplay.h: + * gdk/x11/gdkdisplay-x11.c (gdk_display_supports_selection_notification): + (gdk_display_request_selection_notification): New api + to support selection ownership notification. + + * gtk/gtkclipboard.h: + * gtk/gtkclipboard.c (_gtk_clipboard_handle_event): New private + api to handle owner change events. + (clipboard_peek): Refactored out the body of + gtk_clipboard_get_for_display() for use in _gtk_clipboard_handle_event(). + + * gtk/gtkmain.c (gtk_main_do_event): Handle GDK_OWNER_CHANGE events + by calling _gtk_clipboard_handle_event(). + +2004-05-18 Matthias Clasen <mclasen@redhat.com> + * gtk/gtkintl.h: Include glib/gi18n-lib.h and only define the P_() macros ourselves. diff --git a/docs/reference/ChangeLog b/docs/reference/ChangeLog index c49ca30bd..e2cb1dea2 100644 --- a/docs/reference/ChangeLog +++ b/docs/reference/ChangeLog @@ -1,3 +1,8 @@ +2004-05-18 Matthias Clasen <mclasen@redhat.com> + + * gdk/gdk-sections.txt: Add gdk_display_supports_selection_notification + and gdk_display_request_selection_notification. + 2004-05-14 Matthias Clasen <mclasen@redhat.com> * gtk/tree_widget.sgml: Minor update. diff --git a/docs/reference/gdk-pixbuf/tmpl/module_interface.sgml b/docs/reference/gdk-pixbuf/tmpl/module_interface.sgml index 794384d6e..94e928bd9 100644 --- a/docs/reference/gdk-pixbuf/tmpl/module_interface.sgml +++ b/docs/reference/gdk-pixbuf/tmpl/module_interface.sgml @@ -129,6 +129,15 @@ They are not covered by the same stability guarantees as the regular @Returns: +<!-- ##### FUNCTION gdk_pixbuf_format_is_scalable ##### --> +<para> + +</para> + +@format: +@Returns: + + <!-- ##### STRUCT GdkPixbufFormat ##### --> <para> A #GdkPixbufFormat contains information about the image format accepted by a @@ -153,6 +162,7 @@ operations. </para> @GDK_PIXBUF_FORMAT_WRITABLE: the module can write out images in the format. +@GDK_PIXBUF_FORMAT_SCALABLE: @Since: 2.2 <!-- ##### STRUCT GdkPixbufModulePattern ##### --> diff --git a/docs/reference/gdk/gdk-sections.txt b/docs/reference/gdk/gdk-sections.txt index 92a508d60..a9c6fe44d 100644 --- a/docs/reference/gdk/gdk-sections.txt +++ b/docs/reference/gdk/gdk-sections.txt @@ -145,6 +145,8 @@ gdk_display_supports_cursor_alpha gdk_display_get_default_cursor_size gdk_display_get_maximal_cursor_size gdk_display_get_default_group +gdk_display_supports_selection_notification +gdk_display_request_selection_notification <SUBSECTION Standard> GDK_DISPLAY_OBJECT diff --git a/docs/reference/gdk/tmpl/events.sgml b/docs/reference/gdk/tmpl/events.sgml index caabb4411..4baccc895 100644 --- a/docs/reference/gdk/tmpl/events.sgml +++ b/docs/reference/gdk/tmpl/events.sgml @@ -84,6 +84,7 @@ when parts of a drawable were copied. This is not very useful. @GDK_SCROLL: @GDK_WINDOW_STATE: @GDK_SETTING: +@GDK_OWNER_CHANGE: <!-- ##### ENUM GdkEventMask ##### --> <para> diff --git a/docs/reference/gdk/tmpl/gdkdisplay.sgml b/docs/reference/gdk/tmpl/gdkdisplay.sgml index a7cf8e857..69637705d 100644 --- a/docs/reference/gdk/tmpl/gdkdisplay.sgml +++ b/docs/reference/gdk/tmpl/gdkdisplay.sgml @@ -324,3 +324,22 @@ Applications should never have any reason to use this facility @Returns: +<!-- ##### FUNCTION gdk_display_supports_selection_notification ##### --> +<para> + +</para> + +@display: +@Returns: + + +<!-- ##### FUNCTION gdk_display_request_selection_notification ##### --> +<para> + +</para> + +@display: +@selection: +@Returns: + + diff --git a/docs/reference/gtk/tmpl/gtkenums.sgml b/docs/reference/gtk/tmpl/gtkenums.sgml index c37882d0f..1a58ba7b7 100644 --- a/docs/reference/gtk/tmpl/gtkenums.sgml +++ b/docs/reference/gtk/tmpl/gtkenums.sgml @@ -336,14 +336,14 @@ Indicated the relief to be drawn around a #GtkButton. </para> @GTK_SELECTION_NONE: No selection is possible. -@GTK_SELECTION_SINGLE: Zero or one element may be selected. +@GTK_SELECTION_SINGLE: Zero or one element may be selected. @GTK_SELECTION_BROWSE: Exactly one element is always selected (this can be false after you have changed the selection mode). @GTK_SELECTION_MULTIPLE: Any number of elements may be selected. Clicks toggle the state of an item. Any number of elements may be selected. Click-drag selects a range of elements; the Ctrl key may be used to enlarge the selection, and Shift key to select between the focus and the child - pointed to. + pointed to. @GTK_SELECTION_EXTENDED: Deprecated, behaves identical to %GTK_SELECTION_MULTIPLE. diff --git a/gdk/gdkdisplay.h b/gdk/gdkdisplay.h index 2bbc7eb8e..75c1b9c3e 100644 --- a/gdk/gdkdisplay.h +++ b/gdk/gdkdisplay.h @@ -164,6 +164,10 @@ void gdk_display_get_maximal_cursor_size (GdkDisplay *display, GdkWindow *gdk_display_get_default_group (GdkDisplay *display); +gboolean gdk_display_supports_selection_notification (GdkDisplay *display); +gboolean gdk_display_request_selection_notification (GdkDisplay *display, + GdkAtom selection); + G_END_DECLS -#endif /* __GDK_DISPLAY_H__ */ +#endif /* __GDK_DISPLAY_H__ */ diff --git a/gdk/gdkevents.h b/gdk/gdkevents.h index e7cafb913..000775dbf 100644 --- a/gdk/gdkevents.h +++ b/gdk/gdkevents.h @@ -29,6 +29,7 @@ typedef struct _GdkEventCrossing GdkEventCrossing; typedef struct _GdkEventConfigure GdkEventConfigure; typedef struct _GdkEventProperty GdkEventProperty; typedef struct _GdkEventSelection GdkEventSelection; +typedef struct _GdkEventOwnerChange GdkEventOwnerChange; typedef struct _GdkEventProximity GdkEventProximity; typedef struct _GdkEventClient GdkEventClient; typedef struct _GdkEventDND GdkEventDND; @@ -118,7 +119,8 @@ typedef enum GDK_NO_EXPOSE = 30, GDK_SCROLL = 31, GDK_WINDOW_STATE = 32, - GDK_SETTING = 33 + GDK_SETTING = 33, + GDK_OWNER_CHANGE = 34 } GdkEventType; /* Event masks. (Used to select what types of events a window @@ -219,6 +221,13 @@ typedef enum GDK_SETTING_ACTION_DELETED } GdkSettingAction; +typedef enum +{ + GDK_OWNER_CHANGE_NEW_OWNER, + GDK_OWNER_CHANGE_DESTROY, + GDK_OWNER_CHANGE_CLOSE +} GdkOwnerChange; + struct _GdkEventAny { GdkEventType type; @@ -366,6 +375,18 @@ struct _GdkEventSelection GdkNativeWindow requestor; }; +struct _GdkEventOwnerChange +{ + GdkEventType type; + GdkWindow *window; + gint8 send_event; + GdkNativeWindow owner; + GdkOwnerChange reason; + GdkAtom selection; + guint32 time; + guint32 selection_time; +}; + /* This event type will be used pretty rarely. It only is important for XInput aware programs that are drawing their own cursor */ @@ -438,6 +459,7 @@ union _GdkEvent GdkEventConfigure configure; GdkEventProperty property; GdkEventSelection selection; + GdkEventOwnerChange owner_change; GdkEventProximity proximity; GdkEventClient client; GdkEventDND dnd; diff --git a/gdk/x11/gdkdisplay-x11.c b/gdk/x11/gdkdisplay-x11.c index a765a063f..66c4766b1 100644 --- a/gdk/x11/gdkdisplay-x11.c +++ b/gdk/x11/gdkdisplay-x11.c @@ -43,6 +43,10 @@ #include <X11/XKBlib.h> #endif +#ifdef HAVE_XFIXES +#include <X11/extensions/Xfixes.h> +#endif + static void gdk_display_x11_class_init (GdkDisplayX11Class *class); static void gdk_display_x11_dispose (GObject *object); static void gdk_display_x11_finalize (GObject *object); @@ -147,6 +151,7 @@ gdk_display_open (const gchar *display_name) XClassHint *class_hint; gulong pid; gint i; + gint ignore; xdisplay = XOpenDisplay (display_name); if (!xdisplay) @@ -193,6 +198,21 @@ gdk_display_open (const gchar *display_name) display_x11->have_render = GDK_UNKNOWN; +#ifdef HAVE_XFIXES + if (XFixesQueryExtension (display_x11->xdisplay, + &display_x11->xfixes_event_base, + &ignore)) + { + display_x11->have_xfixes = TRUE; + + gdk_x11_register_standard_event_type (display, + display_x11->xfixes_event_base, + XFixesNumberEvents); + } + else +#endif + display_x11->have_xfixes = FALSE; + if (_gdk_synchronize) XSynchronize (display_x11->xdisplay, True); @@ -969,3 +989,63 @@ gdk_notify_startup_complete (void) g_free (message); } + + +/** + * gdk_display_supports_selection_notification: + * @display: a #GdkDisplay + * + * Returns whether #GdkEventOwnerChange events will be + * sent when the owner of a selection changes. + * + * Return value: whether #GdkEventOwnerChange events will + * be sent. + * + * Since: 2.6 + **/ +gboolean +gdk_display_supports_selection_notification (GdkDisplay *display) +{ + GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display); + + return display_x11->have_xfixes; +} + +/** + * gdk_display_request_selection_notification: + * @display: a #GdkDisplay + * @selection: the #GdkAtom naming the selection for which + * ownership change notification is requested + * + * Request #GdkEventOwnerChange events for ownership changes + * of the selection named by the given atom. + * + * Return value: whether #GdkEventOwnerChange events will + * be sent. + * + * Since: 2.6 + **/ +gboolean gdk_display_request_selection_notification (GdkDisplay *display, + GdkAtom selection) + +{ +#ifdef HAVE_XFIXES + GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display); + Atom atom; + + if (display_x11->have_xfixes) + { + atom = gdk_x11_atom_to_xatom_for_display (display, + selection); + XFixesSelectSelectionInput (display_x11->xdisplay, + display_x11->leader_window, + atom, + XFixesSetSelectionOwnerNotifyMask | + XFixesSelectionWindowDestroyNotifyMask | + XFixesSelectionClientCloseNotifyMask); + return TRUE; + } + else +#endif + return FALSE; +} diff --git a/gdk/x11/gdkdisplay-x11.h b/gdk/x11/gdkdisplay-x11.h index 0d3d6838f..3ce7d941a 100644 --- a/gdk/x11/gdkdisplay-x11.h +++ b/gdk/x11/gdkdisplay-x11.h @@ -78,7 +78,9 @@ struct _GdkDisplayX11 gboolean use_xshm; gboolean have_shm_pixmaps; GdkTristate have_render; - + gboolean have_xfixes; + gint xfixes_event_base; + /* Information about current pointer and keyboard grabs held by this * client. If gdk_pointer_xgrab_window or gdk_keyboard_xgrab_window * window is NULL, then the other associated fields are ignored diff --git a/gdk/x11/gdkevents-x11.c b/gdk/x11/gdkevents-x11.c index 6f31369af..56a29fd8f 100644 --- a/gdk/x11/gdkevents-x11.c +++ b/gdk/x11/gdkevents-x11.c @@ -46,6 +46,10 @@ #include <X11/XKBlib.h> #endif +#ifdef HAVE_XFIXES +#include <X11/extensions/Xfixes.h> +#endif + #include <X11/Xatom.h> typedef struct _GdkIOClosure GdkIOClosure; @@ -1955,6 +1959,24 @@ gdk_event_translate (GdkDisplay *display, } else #endif +#ifdef HAVE_XFIXES + if (xevent->type - display_x11->xfixes_event_base == XFixesSelectionNotify) + { + XFixesSelectionNotifyEvent *selection_notify = (XFixesSelectionNotifyEvent *)xevent; + event->owner_change.type = GDK_OWNER_CHANGE; + event->owner_change.window = window; + event->owner_change.owner = selection_notify->owner; + event->owner_change.reason = selection_notify->subtype; + event->owner_change.selection = + gdk_x11_xatom_to_atom_for_display (display, + selection_notify->selection); + event->owner_change.time = selection_notify->timestamp; + event->owner_change.selection_time = selection_notify->selection_timestamp; + + return_val = TRUE; + } + else +#endif { /* something else - (e.g., a Xinput event) */ diff --git a/gtk/gtkclipboard.c b/gtk/gtkclipboard.c index 107b40d69..fbaafafed 100644 --- a/gtk/gtkclipboard.c +++ b/gtk/gtkclipboard.c @@ -25,6 +25,7 @@ #include "gtkclipboard.h" #include "gtkinvisible.h" #include "gtkmain.h" +#include "gtkmarshalers.h" #ifdef GDK_WINDOWING_X11 #include "x11/gdkx.h" @@ -34,6 +35,11 @@ #include "win32/gdkwin32.h" #endif +enum { + OWNER_CHANGE, + LAST_SIGNAL +}; + typedef struct _GtkClipboardClass GtkClipboardClass; typedef struct _RequestContentsInfo RequestContentsInfo; @@ -60,6 +66,9 @@ struct _GtkClipboard struct _GtkClipboardClass { GObjectClass parent_class; + + void (*owner_change) (GtkClipboard *clipboard, + GdkEventOwnerChange *event); }; struct _RequestContentsInfo @@ -83,11 +92,13 @@ struct _RequestTargetsInfo static void gtk_clipboard_class_init (GtkClipboardClass *class); static void gtk_clipboard_finalize (GObject *object); -static void clipboard_unset (GtkClipboard *clipboard); -static void selection_received (GtkWidget *widget, - GtkSelectionData *selection_data, - guint time); - +static void clipboard_unset (GtkClipboard *clipboard); +static void selection_received (GtkWidget *widget, + GtkSelectionData *selection_data, + guint time); +static GtkClipboard *clipboard_peek (GdkDisplay *display, + GdkAtom selection, + gboolean only_if_exists); enum { TARGET_STRING, TARGET_TEXT, @@ -102,6 +113,7 @@ static const gchar clipboards_owned_key[] = "gtk-clipboards-owned"; static GQuark clipboards_owned_key_id = 0; static GObjectClass *parent_class; +static guint clipboard_signals[LAST_SIGNAL] = { 0 }; GType gtk_clipboard_get_type (void) @@ -138,10 +150,22 @@ gtk_clipboard_class_init (GtkClipboardClass *class) parent_class = g_type_class_peek_parent (class); gobject_class->finalize = gtk_clipboard_finalize; + + class->owner_change = NULL; + + clipboard_signals[OWNER_CHANGE] = + g_signal_new ("owner_change", + G_TYPE_FROM_CLASS (gobject_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (GtkClipboardClass, owner_change), + NULL, NULL, + _gtk_marshal_VOID__BOXED, + G_TYPE_NONE, 1, + GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); } static void -gtk_clipboard_finalize (GObject *object) +gtk_clipboard_finalize (GObject *object) { clipboard_unset (GTK_CLIPBOARD (object)); @@ -204,44 +228,16 @@ clipboard_display_closed (GdkDisplay *display, * Since: 2.2 **/ GtkClipboard * -gtk_clipboard_get_for_display (GdkDisplay *display, GdkAtom selection) +gtk_clipboard_get_for_display (GdkDisplay *display, + GdkAtom selection) { - GtkClipboard *clipboard = NULL; - GSList *clipboards; - GSList *tmp_list; - g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL); g_return_val_if_fail (!display->closed, NULL); - if (selection == GDK_NONE) - selection = GDK_SELECTION_CLIPBOARD; - - clipboards = g_object_get_data (G_OBJECT (display), "gtk-clipboard-list"); - - tmp_list = clipboards; - while (tmp_list) - { - clipboard = tmp_list->data; - if (clipboard->selection == selection) - break; - - tmp_list = tmp_list->next; - } - - if (!tmp_list) - { - clipboard = g_object_new (GTK_TYPE_CLIPBOARD, NULL); - clipboard->selection = selection; - clipboard->display = display; - clipboards = g_slist_prepend (clipboards, clipboard); - g_object_set_data (G_OBJECT (display), "gtk-clipboard-list", clipboards); - g_signal_connect (display, "closed", - G_CALLBACK (clipboard_display_closed), clipboard); - } - - return clipboard; + return clipboard_peek (display, selection, FALSE); } + /** * gtk_clipboard_get(): * @selection: a #GdkAtom which identifies the clipboard @@ -1108,3 +1104,66 @@ gtk_clipboard_wait_for_targets (GtkClipboard *clipboard, return result; } + +static GtkClipboard * +clipboard_peek (GdkDisplay *display, + GdkAtom selection, + gboolean only_if_exists) +{ + GtkClipboard *clipboard = NULL; + GSList *clipboards; + GSList *tmp_list; + + if (selection == GDK_NONE) + selection = GDK_SELECTION_CLIPBOARD; + + clipboards = g_object_get_data (G_OBJECT (display), "gtk-clipboard-list"); + + tmp_list = clipboards; + while (tmp_list) + { + clipboard = tmp_list->data; + if (clipboard->selection == selection) + break; + + tmp_list = tmp_list->next; + } + + if (!tmp_list && !only_if_exists) + { + clipboard = g_object_new (GTK_TYPE_CLIPBOARD, NULL); + clipboard->selection = selection; + clipboard->display = display; + clipboards = g_slist_prepend (clipboards, clipboard); + g_object_set_data (G_OBJECT (display), "gtk-clipboard-list", clipboards); + g_signal_connect (display, "closed", + G_CALLBACK (clipboard_display_closed), clipboard); + gdk_display_request_selection_notification (display, selection); + } + + return clipboard; +} + + +/** + * _gtk_clipboard_handle_event: + * @event: a owner change event + * + * Emits the ::owner_change signal on the appropriate @clipboard. + * + * Since: 2.6 + **/ +void +_gtk_clipboard_handle_event (GdkEventOwnerChange *event) +{ + GdkDisplay *display; + GtkClipboard *clipboard; + + display = gdk_drawable_get_display (event->window); + clipboard = clipboard_peek (display, event->selection, TRUE); + + if (clipboard) + g_signal_emit (clipboard, + clipboard_signals[OWNER_CHANGE], 0, event, NULL); +} + diff --git a/gtk/gtkclipboard.h b/gtk/gtkclipboard.h index 3d2268393..d706567e5 100644 --- a/gtk/gtkclipboard.h +++ b/gtk/gtkclipboard.h @@ -104,6 +104,9 @@ gboolean gtk_clipboard_wait_for_targets (GtkClipboard *clipboard, GdkAtom **targets, gint *n_targets); +/* private */ +void _gtk_clipboard_handle_event (GdkEventOwnerChange *event); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/gtk/gtkmain.c b/gtk/gtkmain.c index 9b301dbfc..d75ff7248 100644 --- a/gtk/gtkmain.c +++ b/gtk/gtkmain.c @@ -1438,6 +1438,12 @@ gtk_main_do_event (GdkEvent *event) return; } + if (event->type == GDK_OWNER_CHANGE) + { + _gtk_clipboard_handle_event (&event->owner_change); + return; + } + /* Find the widget which got the event. We store the widget * in the user_data field of GdkWindow's. * Ignore the event if we don't have a widget for it, except |