Re: Clipboard improvements
- From: Matthias Clasen <mclasen redhat com>
- To: gtk-devel-list gnome org
- Subject: Re: Clipboard improvements
- Date: Thu, 06 May 2004 15:33:07 -0400
I forgot to attach the patch...
Matthias
Index: docs/reference/gdk/tmpl/events.sgml
===================================================================
RCS file: /cvs/gnome/gtk+/docs/reference/gdk/tmpl/events.sgml,v
retrieving revision 1.19
diff -u -r1.19 events.sgml
--- docs/reference/gdk/tmpl/events.sgml 27 Aug 2003 22:59:47 -0000 1.19
+++ docs/reference/gdk/tmpl/events.sgml 6 May 2004 15:20:15 -0000
@@ -84,6 +84,7 @@
@GDK_SCROLL:
@GDK_WINDOW_STATE:
@GDK_SETTING:
+ GDK_OWNER_CHANGE:
<!-- ##### ENUM GdkEventMask ##### -->
<para>
Index: gdk/gdkdisplay.h
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/gdkdisplay.h,v
retrieving revision 1.17
diff -u -r1.17 gdkdisplay.h
--- gdk/gdkdisplay.h 16 Dec 2003 00:56:46 -0000 1.17
+++ gdk/gdkdisplay.h 6 May 2004 15:20:15 -0000
@@ -164,6 +164,8 @@
GdkWindow *gdk_display_get_default_group (GdkDisplay *display);
+gboolean gdk_display_supports_selection_notification (GdkDisplay *display);
+
G_END_DECLS
-#endif /* __GDK_DISPLAY_H__ */
+#endif /* __GDK_DISPLAY_H__ */
Index: gdk/gdkevents.h
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/gdkevents.h,v
retrieving revision 1.21
diff -u -r1.21 gdkevents.h
--- gdk/gdkevents.h 10 Aug 2003 23:37:29 -0000 1.21
+++ gdk/gdkevents.h 6 May 2004 15:20:15 -0000
@@ -29,6 +29,7 @@
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 @@
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 @@
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 @@
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 @@
GdkEventConfigure configure;
GdkEventProperty property;
GdkEventSelection selection;
+ GdkEventOwnerChange owner_change;
GdkEventProximity proximity;
GdkEventClient client;
GdkEventDND dnd;
Index: gdk/x11/gdkdisplay-x11.c
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/x11/gdkdisplay-x11.c,v
retrieving revision 1.41
diff -u -r1.41 gdkdisplay-x11.c
--- gdk/x11/gdkdisplay-x11.c 18 Apr 2004 14:33:07 -0000 1.41
+++ gdk/x11/gdkdisplay-x11.c 6 May 2004 15:20:16 -0000
@@ -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 @@
XClassHint *class_hint;
gulong pid;
gint i;
+ gint ignore;
xdisplay = XOpenDisplay (display_name);
if (!xdisplay)
@@ -193,6 +198,21 @@
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);
@@ -968,4 +988,25 @@
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;
}
Index: gdk/x11/gdkdisplay-x11.h
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/x11/gdkdisplay-x11.h,v
retrieving revision 1.16
diff -u -r1.16 gdkdisplay-x11.h
--- gdk/x11/gdkdisplay-x11.h 18 Apr 2004 14:33:07 -0000 1.16
+++ gdk/x11/gdkdisplay-x11.h 6 May 2004 15:20:16 -0000
@@ -78,7 +78,9 @@
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
Index: gdk/x11/gdkevents-x11.c
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/x11/gdkevents-x11.c,v
retrieving revision 1.131
diff -u -r1.131 gdkevents-x11.c
--- gdk/x11/gdkevents-x11.c 6 May 2004 02:57:01 -0000 1.131
+++ gdk/x11/gdkevents-x11.c 6 May 2004 15:20:17 -0000
@@ -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;
@@ -1952,6 +1956,24 @@
_gdk_keymap_state_changed (display);
break;
}
+ }
+ 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
Index: gtk/gtkclipboard.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkclipboard.c,v
retrieving revision 1.26
diff -u -r1.26 gtkclipboard.c
--- gtk/gtkclipboard.c 23 Apr 2004 20:01:53 -0000 1.26
+++ gtk/gtkclipboard.c 6 May 2004 15:20:17 -0000
@@ -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 _GtkClipboardClass
{
GObjectClass parent_class;
+
+ gboolean (*owner_change) (GtkClipboard *clipboard,
+ GdkEventOwnerChange *event);
};
struct _RequestContentsInfo
@@ -83,11 +92,13 @@
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 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 @@
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),
+ _gtk_boolean_handled_accumulator, NULL,
+ _gtk_marshal_BOOLEAN__BOXED,
+ G_TYPE_BOOLEAN, 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 @@
* 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
@@ -1107,4 +1103,69 @@
}
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);
+ }
+
+ 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)
+ {
+ gboolean return_val = FALSE;
+
+ g_signal_emit (clipboard,
+ clipboard_signals[OWNER_CHANGE], 0, event, &return_val);
+ }
}
Index: gtk/gtkclipboard.h
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkclipboard.h,v
retrieving revision 1.7
diff -u -r1.7 gtkclipboard.h
--- gtk/gtkclipboard.h 24 Dec 2003 00:14:13 -0000 1.7
+++ gtk/gtkclipboard.h 6 May 2004 15:20:17 -0000
@@ -104,6 +104,9 @@
GdkAtom **targets,
gint *n_targets);
+/* private */
+void _gtk_clipboard_handle_event (GdkEventOwnerChange *event);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
Index: gtk/gtkmain.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkmain.c,v
retrieving revision 1.234
diff -u -r1.234 gtkmain.c
--- gtk/gtkmain.c 6 Mar 2004 03:37:59 -0000 1.234
+++ gtk/gtkmain.c 6 May 2004 15:20:17 -0000
@@ -1438,6 +1438,12 @@
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
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]