Check for XFIXES extension.

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().
This commit is contained in:
Matthias Clasen 2004-05-18 20:56:54 +00:00 committed by Matthias Clasen
parent 261d540438
commit 7b8616bf76
18 changed files with 402 additions and 43 deletions

View File

@ -1,3 +1,34 @@
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> 2004-05-18 Matthias Clasen <mclasen@redhat.com>
* gtk/gtkintl.h: Include glib/gi18n-lib.h and only define * gtk/gtkintl.h: Include glib/gi18n-lib.h and only define

View File

@ -1,3 +1,34 @@
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> 2004-05-18 Matthias Clasen <mclasen@redhat.com>
* gtk/gtkintl.h: Include glib/gi18n-lib.h and only define * gtk/gtkintl.h: Include glib/gi18n-lib.h and only define

View File

@ -1,3 +1,34 @@
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> 2004-05-18 Matthias Clasen <mclasen@redhat.com>
* gtk/gtkintl.h: Include glib/gi18n-lib.h and only define * gtk/gtkintl.h: Include glib/gi18n-lib.h and only define

View File

@ -1,3 +1,34 @@
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> 2004-05-18 Matthias Clasen <mclasen@redhat.com>
* gtk/gtkintl.h: Include glib/gi18n-lib.h and only define * gtk/gtkintl.h: Include glib/gi18n-lib.h and only define

View File

@ -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> 2004-05-14 Matthias Clasen <mclasen@redhat.com>
* gtk/tree_widget.sgml: Minor update. * gtk/tree_widget.sgml: Minor update.

View File

@ -129,6 +129,15 @@ They are not covered by the same stability guarantees as the regular
@Returns: @Returns:
<!-- ##### FUNCTION gdk_pixbuf_format_is_scalable ##### -->
<para>
</para>
@format:
@Returns:
<!-- ##### STRUCT GdkPixbufFormat ##### --> <!-- ##### STRUCT GdkPixbufFormat ##### -->
<para> <para>
A #GdkPixbufFormat contains information about the image format accepted by a A #GdkPixbufFormat contains information about the image format accepted by a
@ -153,6 +162,7 @@ operations.
</para> </para>
@GDK_PIXBUF_FORMAT_WRITABLE: the module can write out images in the format. @GDK_PIXBUF_FORMAT_WRITABLE: the module can write out images in the format.
@GDK_PIXBUF_FORMAT_SCALABLE:
@Since: 2.2 @Since: 2.2
<!-- ##### STRUCT GdkPixbufModulePattern ##### --> <!-- ##### STRUCT GdkPixbufModulePattern ##### -->

View File

@ -145,6 +145,8 @@ gdk_display_supports_cursor_alpha
gdk_display_get_default_cursor_size gdk_display_get_default_cursor_size
gdk_display_get_maximal_cursor_size gdk_display_get_maximal_cursor_size
gdk_display_get_default_group gdk_display_get_default_group
gdk_display_supports_selection_notification
gdk_display_request_selection_notification
<SUBSECTION Standard> <SUBSECTION Standard>
GDK_DISPLAY_OBJECT GDK_DISPLAY_OBJECT

View File

@ -84,6 +84,7 @@ when parts of a drawable were copied. This is not very useful.
@GDK_SCROLL: @GDK_SCROLL:
@GDK_WINDOW_STATE: @GDK_WINDOW_STATE:
@GDK_SETTING: @GDK_SETTING:
@GDK_OWNER_CHANGE:
<!-- ##### ENUM GdkEventMask ##### --> <!-- ##### ENUM GdkEventMask ##### -->
<para> <para>

View File

@ -324,3 +324,22 @@ Applications should never have any reason to use this facility
@Returns: @Returns:
<!-- ##### FUNCTION gdk_display_supports_selection_notification ##### -->
<para>
</para>
@display:
@Returns:
<!-- ##### FUNCTION gdk_display_request_selection_notification ##### -->
<para>
</para>
@display:
@selection:
@Returns:

View File

@ -336,14 +336,14 @@ Indicated the relief to be drawn around a #GtkButton.
</para> </para>
@GTK_SELECTION_NONE: No selection is possible. @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 @GTK_SELECTION_BROWSE: Exactly one element is always selected
(this can be false after you have changed the selection mode). (this can be false after you have changed the selection mode).
@GTK_SELECTION_MULTIPLE: Any number of elements may be selected. @GTK_SELECTION_MULTIPLE: Any number of elements may be selected.
Clicks toggle the state of an item. 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 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 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_EXTENDED: Deprecated, behaves identical to
%GTK_SELECTION_MULTIPLE. %GTK_SELECTION_MULTIPLE.

View File

@ -164,6 +164,10 @@ void gdk_display_get_maximal_cursor_size (GdkDisplay *display,
GdkWindow *gdk_display_get_default_group (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 G_END_DECLS
#endif /* __GDK_DISPLAY_H__ */ #endif /* __GDK_DISPLAY_H__ */

View File

@ -29,6 +29,7 @@ typedef struct _GdkEventCrossing GdkEventCrossing;
typedef struct _GdkEventConfigure GdkEventConfigure; typedef struct _GdkEventConfigure GdkEventConfigure;
typedef struct _GdkEventProperty GdkEventProperty; typedef struct _GdkEventProperty GdkEventProperty;
typedef struct _GdkEventSelection GdkEventSelection; typedef struct _GdkEventSelection GdkEventSelection;
typedef struct _GdkEventOwnerChange GdkEventOwnerChange;
typedef struct _GdkEventProximity GdkEventProximity; typedef struct _GdkEventProximity GdkEventProximity;
typedef struct _GdkEventClient GdkEventClient; typedef struct _GdkEventClient GdkEventClient;
typedef struct _GdkEventDND GdkEventDND; typedef struct _GdkEventDND GdkEventDND;
@ -118,7 +119,8 @@ typedef enum
GDK_NO_EXPOSE = 30, GDK_NO_EXPOSE = 30,
GDK_SCROLL = 31, GDK_SCROLL = 31,
GDK_WINDOW_STATE = 32, GDK_WINDOW_STATE = 32,
GDK_SETTING = 33 GDK_SETTING = 33,
GDK_OWNER_CHANGE = 34
} GdkEventType; } GdkEventType;
/* Event masks. (Used to select what types of events a window /* Event masks. (Used to select what types of events a window
@ -219,6 +221,13 @@ typedef enum
GDK_SETTING_ACTION_DELETED GDK_SETTING_ACTION_DELETED
} GdkSettingAction; } GdkSettingAction;
typedef enum
{
GDK_OWNER_CHANGE_NEW_OWNER,
GDK_OWNER_CHANGE_DESTROY,
GDK_OWNER_CHANGE_CLOSE
} GdkOwnerChange;
struct _GdkEventAny struct _GdkEventAny
{ {
GdkEventType type; GdkEventType type;
@ -366,6 +375,18 @@ struct _GdkEventSelection
GdkNativeWindow requestor; 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 /* This event type will be used pretty rarely. It only is important
for XInput aware programs that are drawing their own cursor */ for XInput aware programs that are drawing their own cursor */
@ -438,6 +459,7 @@ union _GdkEvent
GdkEventConfigure configure; GdkEventConfigure configure;
GdkEventProperty property; GdkEventProperty property;
GdkEventSelection selection; GdkEventSelection selection;
GdkEventOwnerChange owner_change;
GdkEventProximity proximity; GdkEventProximity proximity;
GdkEventClient client; GdkEventClient client;
GdkEventDND dnd; GdkEventDND dnd;

View File

@ -43,6 +43,10 @@
#include <X11/XKBlib.h> #include <X11/XKBlib.h>
#endif #endif
#ifdef HAVE_XFIXES
#include <X11/extensions/Xfixes.h>
#endif
static void gdk_display_x11_class_init (GdkDisplayX11Class *class); static void gdk_display_x11_class_init (GdkDisplayX11Class *class);
static void gdk_display_x11_dispose (GObject *object); static void gdk_display_x11_dispose (GObject *object);
static void gdk_display_x11_finalize (GObject *object); static void gdk_display_x11_finalize (GObject *object);
@ -147,6 +151,7 @@ gdk_display_open (const gchar *display_name)
XClassHint *class_hint; XClassHint *class_hint;
gulong pid; gulong pid;
gint i; gint i;
gint ignore;
xdisplay = XOpenDisplay (display_name); xdisplay = XOpenDisplay (display_name);
if (!xdisplay) if (!xdisplay)
@ -193,6 +198,21 @@ gdk_display_open (const gchar *display_name)
display_x11->have_render = GDK_UNKNOWN; 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) if (_gdk_synchronize)
XSynchronize (display_x11->xdisplay, True); XSynchronize (display_x11->xdisplay, True);
@ -969,3 +989,63 @@ gdk_notify_startup_complete (void)
g_free (message); 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;
}

View File

@ -78,7 +78,9 @@ struct _GdkDisplayX11
gboolean use_xshm; gboolean use_xshm;
gboolean have_shm_pixmaps; gboolean have_shm_pixmaps;
GdkTristate have_render; GdkTristate have_render;
gboolean have_xfixes;
gint xfixes_event_base;
/* Information about current pointer and keyboard grabs held by this /* Information about current pointer and keyboard grabs held by this
* client. If gdk_pointer_xgrab_window or gdk_keyboard_xgrab_window * client. If gdk_pointer_xgrab_window or gdk_keyboard_xgrab_window
* window is NULL, then the other associated fields are ignored * window is NULL, then the other associated fields are ignored

View File

@ -46,6 +46,10 @@
#include <X11/XKBlib.h> #include <X11/XKBlib.h>
#endif #endif
#ifdef HAVE_XFIXES
#include <X11/extensions/Xfixes.h>
#endif
#include <X11/Xatom.h> #include <X11/Xatom.h>
typedef struct _GdkIOClosure GdkIOClosure; typedef struct _GdkIOClosure GdkIOClosure;
@ -1954,6 +1958,24 @@ gdk_event_translate (GdkDisplay *display,
} }
} }
else 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 #endif
{ {
/* something else - (e.g., a Xinput event) */ /* something else - (e.g., a Xinput event) */

View File

@ -25,6 +25,7 @@
#include "gtkclipboard.h" #include "gtkclipboard.h"
#include "gtkinvisible.h" #include "gtkinvisible.h"
#include "gtkmain.h" #include "gtkmain.h"
#include "gtkmarshalers.h"
#ifdef GDK_WINDOWING_X11 #ifdef GDK_WINDOWING_X11
#include "x11/gdkx.h" #include "x11/gdkx.h"
@ -34,6 +35,11 @@
#include "win32/gdkwin32.h" #include "win32/gdkwin32.h"
#endif #endif
enum {
OWNER_CHANGE,
LAST_SIGNAL
};
typedef struct _GtkClipboardClass GtkClipboardClass; typedef struct _GtkClipboardClass GtkClipboardClass;
typedef struct _RequestContentsInfo RequestContentsInfo; typedef struct _RequestContentsInfo RequestContentsInfo;
@ -60,6 +66,9 @@ struct _GtkClipboard
struct _GtkClipboardClass struct _GtkClipboardClass
{ {
GObjectClass parent_class; GObjectClass parent_class;
void (*owner_change) (GtkClipboard *clipboard,
GdkEventOwnerChange *event);
}; };
struct _RequestContentsInfo struct _RequestContentsInfo
@ -83,11 +92,13 @@ struct _RequestTargetsInfo
static void gtk_clipboard_class_init (GtkClipboardClass *class); static void gtk_clipboard_class_init (GtkClipboardClass *class);
static void gtk_clipboard_finalize (GObject *object); static void gtk_clipboard_finalize (GObject *object);
static void clipboard_unset (GtkClipboard *clipboard); static void clipboard_unset (GtkClipboard *clipboard);
static void selection_received (GtkWidget *widget, static void selection_received (GtkWidget *widget,
GtkSelectionData *selection_data, GtkSelectionData *selection_data,
guint time); guint time);
static GtkClipboard *clipboard_peek (GdkDisplay *display,
GdkAtom selection,
gboolean only_if_exists);
enum { enum {
TARGET_STRING, TARGET_STRING,
TARGET_TEXT, TARGET_TEXT,
@ -102,6 +113,7 @@ static const gchar clipboards_owned_key[] = "gtk-clipboards-owned";
static GQuark clipboards_owned_key_id = 0; static GQuark clipboards_owned_key_id = 0;
static GObjectClass *parent_class; static GObjectClass *parent_class;
static guint clipboard_signals[LAST_SIGNAL] = { 0 };
GType GType
gtk_clipboard_get_type (void) gtk_clipboard_get_type (void)
@ -138,10 +150,22 @@ gtk_clipboard_class_init (GtkClipboardClass *class)
parent_class = g_type_class_peek_parent (class); parent_class = g_type_class_peek_parent (class);
gobject_class->finalize = gtk_clipboard_finalize; 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 static void
gtk_clipboard_finalize (GObject *object) gtk_clipboard_finalize (GObject *object)
{ {
clipboard_unset (GTK_CLIPBOARD (object)); clipboard_unset (GTK_CLIPBOARD (object));
@ -204,44 +228,16 @@ clipboard_display_closed (GdkDisplay *display,
* Since: 2.2 * Since: 2.2
**/ **/
GtkClipboard * 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 (GDK_IS_DISPLAY (display), NULL);
g_return_val_if_fail (!display->closed, NULL); g_return_val_if_fail (!display->closed, NULL);
if (selection == GDK_NONE) return clipboard_peek (display, selection, FALSE);
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;
} }
/** /**
* gtk_clipboard_get(): * gtk_clipboard_get():
* @selection: a #GdkAtom which identifies the clipboard * @selection: a #GdkAtom which identifies the clipboard
@ -1108,3 +1104,66 @@ gtk_clipboard_wait_for_targets (GtkClipboard *clipboard,
return result; 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);
}

View File

@ -104,6 +104,9 @@ gboolean gtk_clipboard_wait_for_targets (GtkClipboard *clipboard,
GdkAtom **targets, GdkAtom **targets,
gint *n_targets); gint *n_targets);
/* private */
void _gtk_clipboard_handle_event (GdkEventOwnerChange *event);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */

View File

@ -1438,6 +1438,12 @@ gtk_main_do_event (GdkEvent *event)
return; 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 /* Find the widget which got the event. We store the widget
* in the user_data field of GdkWindow's. * in the user_data field of GdkWindow's.
* Ignore the event if we don't have a widget for it, except * Ignore the event if we don't have a widget for it, except