diff options
author | Alex Larsson <alexl@redhat.com> | 2002-04-29 22:53:45 +0000 |
---|---|---|
committer | Owen Taylor <otaylor@src.gnome.org> | 2002-04-29 22:53:45 +0000 |
commit | 4632fb81c77ba63341e49ea6e323772df1a19a9b (patch) | |
tree | 0898e7ad59470320c70fc360ddfd4780c6c49dec | |
parent | bc25b9b250976f90331b8488745e3abd2a23ae07 (diff) | |
download | gtk+-4632fb81c77ba63341e49ea6e323772df1a19a9b.tar.gz |
Integrate Erwann Chenede's multihead changes for the gtk/ directory.
Mon Apr 29 18:28:00 2002 Owen Taylor <otaylor@redhat.com>
Integrate Erwann Chenede's multihead changes for the gtk/ directory.
* gtk/gtkclipboard.[ch]: Add gtk_clipboard_get_for_display(),
make internals multihead aware.
* gtk/gtkcolorsel.[ch]: Add
gtk_color_selection_set_change_palette_with_screen_hook () [ugh!]
make up for non-multihead safety of
gtk_color_selection_set_change_palette_hook()
* gtk/gtkinvisible.[ch] gtk/gtkmenu.[ch] gtkwindow.[ch]: Add
gtk_{invisible,menu,window}_set_screen(); add "screen" properties
for GtkWindow and GtkMenu.
* gtk/gtkplug.[ch]: Add gtk_plug_construct_for_display(),
gtk_plug_new_for_display(). Multihead fixes.
* gtk/gtkselection.[ch]: Add gtk_selection_owner_set_for_display(),
make internals multihead aware.
* gtk/gtksettings.[ch]: Add gtk_settings_get_for_screen(), get
rid of now-useless gtk_settings_constructor().
* gtk/gtkstyle.[ch]: Add gtk_style_get_font_for_display(), fix
check/radio button indicators bitmap handling to be multihead
safe.
* gtk/gtkwidget.[ch]: Add gtk_widget_get_screen(), gtk_widget_has_screen(),
gtk_widget_get_display(), gtk_widget_get_clipboard(),
gtk_widget_get_root_window().
* gtk/gtkbindings.c gtk/gtkbutton.c gtk/gtkclist.c gtk/gtkcombo.c
gtk/gtkctree.c gtk/gtkdnd.c gtk/gtkfilesel.c gtk/gtkgamma.c
gtk/gtkhandlebox.c gtk/gtkhsv.c gtk/gtkimcontext.c gtk/gtklabel.c
gtk/gtklist.c gtk/gtkmain.c gtk/gtkmenuitem.c gtk/gtkmenushell.c
gtk/gtknotebook.c gtk/gtkoldeditable.c gtk/gtkoptionmenu.c
gtk/gtkpaned.c gtk/gtkpreview.c gtk/gtksocket.c gtk/gtktext.c
gtk/gtktextbuffer.c gtk/gtktextview.c gtk/gtktipsquery.c
gtk/gtktooltips.c gtk/gtktreeview.c gtk/gtktreeviewcolumn.c:
misc mechanical multihead-safety fixes.
* gtk/gtkclipboard.c: Use a GtkImage rather than a pixmap for
the dropper, look up the color palette only at realization time,
other multihead fixes.
* gtk/gtkcombo.c (gtk_combo_unrealize): Popdown the list when
unrealizing.
* gtk/gtkentry.c: Only claim ownership of the primary selection
when realized, misc multihead fixes.
* gtk/gtkfontsel.c: Only fill in fonts when attached to a screen,
fix gtk_font_selection_get_font() for multihead.
* gtk/gtkgc.c: make the depth => drawable hash per-screen.
* gtk/gtkinvisible.c: Add a constructor that realizes the
widget, so we get a realized widget with g_object_new() as
well gtk_invisible_new() as before.
* gtk/gtkmain.c: Get rid of unused gtk_visual/gtk_colormap
variables.
* gtk/gtktextdisplay.c: Add warnings if stipple bitmaps
are used on the wrong screen.
* gtk/gtktoolbar.c: Make handling of GtkSettings-based layout
read properties and connect to settings when the screen is changed,
rather than on init/finalize.
* gtk/gtkwindow.c: Fix icon handing to be multihead safe ...
default icon pixmaps/mask are only shared between windows on the
same screen. Misc multihead fixes.
Sat Apr 27 13:49:53 2002 Owen Taylor <otaylor@redhat.com>
* gtk/gtkclipboard.c (gtk_clipboard_get_for_display):
Update docs to reference GDK_SELECTION_CLIPBOARD rather GDK_NONE.
2002-04-29 Alex Larsson <alexl@redhat.com>
* gdk/linux-fb/gdkproperty-fb.c (gdk_property_get):
Fix silly bug, noticed by Sven Neumann.
Sun Apr 28 22:43:55 2002 Jonathan Blandford <jrb@gnome.org>
* gtk/gtktreemodelsort.c (gtk_tree_model_sort_set_sort_func): Fix
so that you can set a new sort func.
57 files changed, 1951 insertions, 824 deletions
diff --git a/docs/reference/gtk/tmpl/gtkinvisible.sgml b/docs/reference/gtk/tmpl/gtkinvisible.sgml index 50d2f76aab..f45d661ec9 100644 --- a/docs/reference/gtk/tmpl/gtkinvisible.sgml +++ b/docs/reference/gtk/tmpl/gtkinvisible.sgml @@ -27,9 +27,8 @@ The #GtkInvisible-struct struct contains no public fields. <!-- ##### FUNCTION gtk_invisible_new ##### --> <para> -Creates a new #GtkInvisible. </para> -@Returns: a new #GtkInvisible. +@Returns: diff --git a/docs/reference/gtk/tmpl/gtkplug.sgml b/docs/reference/gtk/tmpl/gtkplug.sgml index 296c0b7341..c3aca5db9c 100644 --- a/docs/reference/gtk/tmpl/gtkplug.sgml +++ b/docs/reference/gtk/tmpl/gtkplug.sgml @@ -36,20 +36,14 @@ inside the first applications window. <!-- ##### FUNCTION gtk_plug_construct ##### --> <para> -Finishes the creation of a #GtkPlug widget. This function -will generally only be used by classes deriving -from #GtkPlug. </para> -@plug: a #GtkPlug widget. -@socket_id: the window ID of the socket. +@plug: +@socket_id: <!-- ##### FUNCTION gtk_plug_new ##### --> <para> -Creates a new plug widget inside the #GtkSocket identified -by @socket_id. If @socket_id is 0, the plug is left "unplugged" and -can later be plugged into a #GtkSocket by gtk_socket_add_id(). </para> @socket_id: the window ID of the socket, or 0. diff --git a/gtk/gtkbindings.c b/gtk/gtkbindings.c index 57e4bac0d2..c9dfffeeda 100644 --- a/gtk/gtkbindings.c +++ b/gtk/gtkbindings.c @@ -1076,6 +1076,7 @@ gtk_bindings_activate (GtkObject *object, GdkModifierType modifiers) { GSList *entries = NULL; + GdkDisplay *display; GtkKeyHash *key_hash; gboolean handled = FALSE; gboolean is_release; @@ -1088,7 +1089,9 @@ gtk_bindings_activate (GtkObject *object, is_release = (modifiers & GDK_RELEASE_MASK) != 0; modifiers = modifiers & BINDING_MOD_MASK () & ~GDK_RELEASE_MASK; - key_hash = binding_key_hash_for_keymap (gdk_keymap_get_default ()); + display = gtk_widget_get_display (GTK_WIDGET (object)); + key_hash = binding_key_hash_for_keymap (gdk_keymap_get_for_display (display)); + entries = _gtk_key_hash_lookup_keyval (key_hash, keyval, modifiers); handled = gtk_bindings_activate_list (object, entries, is_release); @@ -1113,6 +1116,7 @@ _gtk_bindings_activate_event (GtkObject *object, GdkEventKey *event) { GSList *entries = NULL; + GdkDisplay *display; GtkKeyHash *key_hash; gboolean handled = FALSE; @@ -1121,7 +1125,9 @@ _gtk_bindings_activate_event (GtkObject *object, if (!GTK_IS_WIDGET (object)) return FALSE; - key_hash = binding_key_hash_for_keymap (gdk_keymap_get_default ()); + display = gtk_widget_get_display (GTK_WIDGET (object)); + key_hash = binding_key_hash_for_keymap (gdk_keymap_get_for_display (display)); + entries = _gtk_key_hash_lookup (key_hash, event->hardware_keycode, event->state & BINDING_MOD_MASK () & ~GDK_RELEASE_MASK, diff --git a/gtk/gtkbutton.c b/gtk/gtkbutton.c index 7a50b67ced..aab09a5311 100644 --- a/gtk/gtkbutton.c +++ b/gtk/gtkbutton.c @@ -1084,7 +1084,8 @@ gtk_button_finish_activate (GtkButton *button, g_source_remove (button->activate_timeout); button->activate_timeout = 0; - gdk_keyboard_ungrab (gtk_get_current_event_time ()); + gdk_display_keyboard_ungrab (gtk_widget_get_display (widget), + gtk_get_current_event_time ()); gtk_grab_remove (widget); button->button_down = FALSE; diff --git a/gtk/gtkclipboard.c b/gtk/gtkclipboard.c index 97d9ea9931..847bb85c4d 100644 --- a/gtk/gtkclipboard.c +++ b/gtk/gtkclipboard.c @@ -49,6 +49,7 @@ struct _GtkClipboard guint32 timestamp; gboolean have_selection; + GdkDisplay *display; }; struct _RequestContentsInfo @@ -68,9 +69,6 @@ static void selection_received (GtkWidget *widget, GtkSelectionData *selection_data, guint time); -static GSList *clipboards; -static GtkWidget *clipboard_widget; - enum { TARGET_STRING, TARGET_TEXT, @@ -84,15 +82,17 @@ static GQuark request_contents_key_id = 0; static const gchar *clipboards_owned_key = "gtk-clipboards-owned"; static GQuark clipboards_owned_key_id = 0; - /** - * gtk_clipboard_get: + * gtk_clipboard_get_for_display: + * @display: the display for which the clipboard is to be retrieved or created * @selection: a #GdkAtom which identifies the clipboard * to use. * * Returns the clipboard object for the given selection. * Cut/copy/paste menu items and keyboard shortcuts should use - * the default clipboard, returned by passing #GDK_NONE for @selection. + * the default clipboard, returned by passing %GDK_SELECTION_CLIPBOARD for @selection. + * (%GDK_NONE is supported as a synonym for GDK_SELECTION_CLIPBOARD + * for backwards compatibility reasons.) * The currently-selected object or text should be provided on the clipboard * identified by #GDK_SELECTION_PRIMARY. Cut/copy/paste menu items * conceptually copy the contents of the #GDK_SELECTION_PRIMARY clipboard @@ -121,13 +121,18 @@ static GQuark clipboards_owned_key_id = 0; * cannot be freed. **/ GtkClipboard * -gtk_clipboard_get (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); + if (selection == GDK_NONE) - selection = gdk_atom_intern ("CLIPBOARD", FALSE); + selection = GDK_SELECTION_CLIPBOARD; + + clipboards = g_object_get_data (G_OBJECT (display), "gtk-clipboard-list"); tmp_list = clipboards; while (tmp_list) @@ -143,19 +148,41 @@ gtk_clipboard_get (GdkAtom selection) { clipboard = g_new0 (GtkClipboard, 1); clipboard->selection = selection; + clipboard->display = display; clipboards = g_slist_prepend (clipboards, clipboard); + g_object_set_data (G_OBJECT (display), "gtk-clipboard-list", clipboards); } return clipboard; } +/** + * gtk_clipboard_get(): + * @selection: a #GdkAtom which identifies the clipboard + * to use. + * + * Returns the clipboard object for the given selection. + * See gtk_clipboard_get_for_display() for complete details. + * + * Return value: the appropriate clipboard object. If no + * clipboard already exists, a new one will + * be created. Once a clipboard object has + * been created, it is persistent for all time and + * cannot be freed. + **/ +GtkClipboard * +gtk_clipboard_get (GdkAtom selection) +{ + return gtk_clipboard_get_for_display (gdk_get_default_display (), selection); +} + static void selection_get_cb (GtkWidget *widget, GtkSelectionData *selection_data, guint time, guint info) { - GtkClipboard *clipboard = gtk_clipboard_get (selection_data->selection); + GtkClipboard *clipboard = gtk_widget_get_clipboard (widget, selection_data->selection); if (clipboard && clipboard->get_func) clipboard->get_func (clipboard, selection_data, info, clipboard->user_data); @@ -165,7 +192,7 @@ static gboolean selection_clear_event_cb (GtkWidget *widget, GdkEventSelection *event) { - GtkClipboard *clipboard = gtk_clipboard_get (event->selection); + GtkClipboard *clipboard = gtk_widget_get_clipboard (widget, event->selection); if (clipboard) { @@ -177,9 +204,10 @@ selection_clear_event_cb (GtkWidget *widget, } static GtkWidget * -make_clipboard_widget (gboolean provider) +make_clipboard_widget (GdkDisplay *display, + gboolean provider) { - GtkWidget *widget = gtk_invisible_new (); + GtkWidget *widget = gtk_invisible_new_for_screen (gdk_display_get_default_screen (display)); gtk_signal_connect (GTK_OBJECT (widget), "selection_received", GTK_SIGNAL_FUNC (selection_received), NULL); @@ -198,12 +226,17 @@ make_clipboard_widget (gboolean provider) return widget; } - -static void -ensure_clipboard_widget () +static GtkWidget * +get_clipboard_widget (GdkDisplay *display) { - if (!clipboard_widget) - clipboard_widget = make_clipboard_widget (TRUE); + GtkWidget *clip_widget = g_object_get_data (G_OBJECT (display), "gtk-clipboard-widget"); + if (!clip_widget) + { + clip_widget = make_clipboard_widget (display, TRUE); + g_object_set_data (G_OBJECT (display), "gtk-clipboard-widget", clip_widget); + } + + return clip_widget; } /* This function makes a very good guess at what the correct @@ -224,10 +257,9 @@ ensure_clipboard_widget () static guint32 clipboard_get_timestamp (GtkClipboard *clipboard) { + GtkWidget *clipboard_widget = get_clipboard_widget (clipboard->display); guint32 timestamp = gtk_get_current_event_time (); - ensure_clipboard_widget (); - if (timestamp == GDK_CURRENT_TIME) { #ifdef GDK_WINDOWING_X11 @@ -321,10 +353,12 @@ gtk_clipboard_set_contents (GtkClipboard *clipboard, gpointer user_data, gboolean have_owner) { - ensure_clipboard_widget (); + GtkWidget *clipboard_widget = get_clipboard_widget (clipboard->display); - if (gtk_selection_owner_set (clipboard_widget, clipboard->selection, - clipboard_get_timestamp (clipboard))) + if (gtk_selection_owner_set_for_display (clipboard->display, + clipboard_widget, + clipboard->selection, + clipboard_get_timestamp (clipboard))) { clipboard->have_selection = TRUE; @@ -509,8 +543,10 @@ gtk_clipboard_clear (GtkClipboard *clipboard) g_return_if_fail (clipboard != NULL); if (clipboard->have_selection) - gtk_selection_owner_set (NULL, clipboard->selection, - clipboard_get_timestamp (clipboard)); + gtk_selection_owner_set_for_display (clipboard->display, + NULL, + clipboard->selection, + clipboard_get_timestamp (clipboard)); } static void @@ -595,13 +631,13 @@ selection_received (GtkWidget *widget, RequestContentsInfo *request_info = get_request_contents_info (widget); set_request_contents_info (widget, NULL); - request_info->callback (gtk_clipboard_get (selection_data->selection), + request_info->callback (gtk_widget_get_clipboard (widget, selection_data->selection), selection_data, request_info->user_data); g_free (request_info); - if (widget != clipboard_widget) + if (widget != get_clipboard_widget (gtk_widget_get_display (widget))) gtk_widget_destroy (widget); } @@ -628,15 +664,16 @@ gtk_clipboard_request_contents (GtkClipboard *clipboard, { RequestContentsInfo *info; GtkWidget *widget; + GtkWidget *clipboard_widget; g_return_if_fail (clipboard != NULL); g_return_if_fail (target != GDK_NONE); g_return_if_fail (callback != NULL); - ensure_clipboard_widget (); + clipboard_widget = get_clipboard_widget (clipboard->display); if (get_request_contents_info (clipboard_widget)) - widget = make_clipboard_widget (FALSE); + widget = make_clipboard_widget (clipboard->display, FALSE); else widget = clipboard_widget; @@ -840,6 +877,21 @@ gtk_clipboard_wait_for_text (GtkClipboard *clipboard) return results.data; } +/** + * gtk_clipboard_get_display: + * @clipboard: a #GtkClipboard + * + * Gets the #GdkDisplay associated with @clipboard + * + * Return value: the #GdkDisplay associated with @clipboard + **/ +GdkDisplay * +gtk_clipboard_get_display (GtkClipboard *clipboard) +{ + g_return_val_if_fail (clipboard != NULL, NULL); + + return clipboard->display; +} /** * gtk_clipboard_wait_is_text_available: diff --git a/gtk/gtkclipboard.h b/gtk/gtkclipboard.h index 94a9bb0d5c..fa0b01360b 100644 --- a/gtk/gtkclipboard.h +++ b/gtk/gtkclipboard.h @@ -28,7 +28,6 @@ extern "C" { #include <gtk/gtkselection.h> -typedef struct _GtkClipboard GtkClipboard; typedef void (* GtkClipboardReceivedFunc) (GtkClipboard *clipboard, GtkSelectionData *selection_data, @@ -47,8 +46,15 @@ typedef void (* GtkClipboardGetFunc) (GtkClipboard *clipboard, gpointer user_data_or_owner); typedef void (* GtkClipboardClearFunc) (GtkClipboard *clipboard, gpointer user_data_or_owner); - -GtkClipboard *gtk_clipboard_get (GdkAtom selection); + +GtkClipboard *gtk_clipboard_get_for_display (GdkDisplay *display, + GdkAtom selection); +#ifndef GDK_MULTIHEAD_SAFE +GtkClipboard *gtk_clipboard_get (GdkAtom selection); +#endif + +GdkDisplay *gtk_clipboard_get_display (GtkClipboard *clipboard); + gboolean gtk_clipboard_set_with_data (GtkClipboard *clipboard, const GtkTargetEntry *targets, diff --git a/gtk/gtkclist.c b/gtk/gtkclist.c index a109391609..23d633a8a6 100644 --- a/gtk/gtkclist.c +++ b/gtk/gtkclist.c @@ -1928,7 +1928,8 @@ abort_column_resize (GtkCList *clist) GTK_CLIST_UNSET_FLAG (clist, CLIST_IN_DRAG); gtk_grab_remove (GTK_WIDGET (clist)); - gdk_pointer_ungrab (GDK_CURRENT_TIME); + gdk_display_pointer_ungrab (gtk_widget_get_display (GTK_WIDGET (clist)), + GDK_CURRENT_TIME); clist->drag_pos = -1; if (clist->x_drag >= 0 && clist->x_drag <= clist->clist_window_width - 1) @@ -3626,13 +3627,20 @@ fake_toggle_row (GtkCList *clist, GTK_CLIST_ROW (work)); } +static gboolean +clist_has_grab (GtkCList *clist) +{ + return (GTK_WIDGET_HAS_GRAB (clist) && + gdk_display_pointer_is_grabbed (gtk_widget_get_display (GTK_WIDGET (clist)))); +} + static void toggle_focus_row (GtkCList *clist) { g_return_if_fail (clist != 0); g_return_if_fail (GTK_IS_CLIST (clist)); - if ((gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (clist)) || + if (clist_has_grab (clist) || clist->focus_row < 0 || clist->focus_row >= clist->rows) return; @@ -3669,7 +3677,7 @@ toggle_add_mode (GtkCList *clist) g_return_if_fail (clist != 0); g_return_if_fail (GTK_IS_CLIST (clist)); - if ((gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (clist)) || + if (clist_has_grab (clist) || clist->selection_mode != GTK_SELECTION_MULTIPLE) return; @@ -3791,7 +3799,7 @@ real_select_all (GtkCList *clist) { g_return_if_fail (GTK_IS_CLIST (clist)); - if (gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (clist)) + if (clist_has_grab (clist)) return; switch (clist->selection_mode) @@ -3831,7 +3839,7 @@ real_unselect_all (GtkCList *clist) g_return_if_fail (GTK_IS_CLIST (clist)); - if (gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (clist)) + if (clist_has_grab (clist)) return; switch (clist->selection_mode) @@ -3916,7 +3924,7 @@ real_undo_selection (GtkCList *clist) g_return_if_fail (GTK_IS_CLIST (clist)); - if ((gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (clist)) || + if (clist_has_grab (clist) || clist->selection_mode != GTK_SELECTION_MULTIPLE) return; @@ -4268,7 +4276,7 @@ start_selection (GtkCList *clist) { g_return_if_fail (GTK_IS_CLIST (clist)); - if (gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (clist)) + if (clist_has_grab (clist)) return; set_anchor (clist, GTK_CLIST_ADD_MODE(clist), clist->focus_row, @@ -4280,7 +4288,8 @@ end_selection (GtkCList *clist) { g_return_if_fail (GTK_IS_CLIST (clist)); - if (gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_FOCUS(clist)) + if (gdk_display_pointer_is_grabbed (gtk_widget_get_display (GTK_WIDGET (clist))) && + GTK_WIDGET_HAS_FOCUS (clist)) return; GTK_CLIST_GET_CLASS (clist)->resync_selection (clist, NULL); @@ -4294,7 +4303,7 @@ extend_selection (GtkCList *clist, { g_return_if_fail (GTK_IS_CLIST (clist)); - if ((gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (clist)) || + if (clist_has_grab (clist) || clist->selection_mode != GTK_SELECTION_MULTIPLE) return; @@ -4536,7 +4545,8 @@ gtk_clist_realize (GtkWidget *widget) GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK); attributes_mask = GDK_WA_CURSOR; - attributes.cursor = gdk_cursor_new (GDK_SB_H_DOUBLE_ARROW); + attributes.cursor = gdk_cursor_new_for_screen (gtk_widget_get_screen (widget), + GDK_SB_H_DOUBLE_ARROW); clist->cursor_drag = attributes.cursor; attributes.x = LIST_WIDTH (clist) + 1; @@ -4728,7 +4738,7 @@ gtk_clist_unmap (GtkWidget *widget) { GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED); - if (gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (clist)) + if (clist_has_grab (clist)) { remove_grab (clist); @@ -5116,7 +5126,7 @@ gtk_clist_button_release (GtkWidget *widget, GTK_CLIST_UNSET_FLAG (clist, CLIST_IN_DRAG); gtk_widget_get_pointer (widget, &x, NULL); gtk_grab_remove (widget); - gdk_pointer_ungrab (event->time); + gdk_display_pointer_ungrab (gtk_widget_get_display (widget), event->time); if (clist->x_drag >= 0) draw_xor_line (clist); @@ -5191,7 +5201,7 @@ gtk_clist_motion (GtkWidget *widget, g_return_val_if_fail (GTK_IS_CLIST (widget), FALSE); clist = GTK_CLIST (widget); - if (!(gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (clist))) + if (!clist_has_grab (clist)) return FALSE; if (clist->drag_button > 0) @@ -6837,7 +6847,7 @@ scroll_horizontal (GtkCList *clist, g_return_if_fail (clist != 0); g_return_if_fail (GTK_IS_CLIST (clist)); - if (gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (clist)) + if (clist_has_grab (clist)) return; for (last_column = clist->columns - 1; @@ -6911,7 +6921,7 @@ scroll_vertical (GtkCList *clist, g_return_if_fail (GTK_IS_CLIST (clist)); - if (gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (clist)) + if (clist_has_grab (clist)) return; switch (clist->selection_mode) @@ -7082,11 +7092,15 @@ vertical_timeout (GtkCList *clist) static void remove_grab (GtkCList *clist) { + GtkWidget *widget = GTK_WIDGET (clist); + if (GTK_WIDGET_HAS_GRAB (clist)) { - gtk_grab_remove (GTK_WIDGET (clist)); - if (gdk_pointer_is_grabbed ()) - gdk_pointer_ungrab (GDK_CURRENT_TIME); + GdkDisplay *display = gtk_widget_get_display (widget); + + gtk_grab_remove (widget); + if (gdk_display_pointer_is_grabbed (display)) + gdk_display_pointer_ungrab (display, GDK_CURRENT_TIME); } if (clist->htimer) @@ -7224,7 +7238,7 @@ real_sort_list (GtkCList *clist) if (clist->rows <= 1) return; - if (gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (clist)) + if (clist_has_grab (clist)) return; gtk_clist_freeze (clist); @@ -7803,7 +7817,8 @@ gtk_clist_set_button_actions (GtkCList *clist, if (button < MAX_BUTTON) { - if (gdk_pointer_is_grabbed () || GTK_WIDGET_HAS_GRAB (clist)) + if (gdk_display_pointer_is_grabbed (gtk_widget_get_display (GTK_WIDGET (clist))) || + GTK_WIDGET_HAS_GRAB (clist)) { remove_grab (clist); clist->drag_button = 0; diff --git a/gtk/gtkcolorsel.c b/gtk/gtkcolorsel.c index 3f78baaf3b..db5174131c 100644 --- a/gtk/gtkcolorsel.c +++ b/gtk/gtkcolorsel.c @@ -56,6 +56,7 @@ #include "gtkmain.h" #include "gtksettings.h" #include "gtkintl.h" +#include "gtkimage.h" #include <string.h> @@ -143,8 +144,6 @@ struct _ColorSelectionPrivate static void gtk_color_selection_init (GtkColorSelection *colorsel); static void gtk_color_selection_class_init (GtkColorSelectionClass *klass); static void gtk_color_selection_destroy (GtkObject *object); -static void gtk_color_selection_finalize (GObject *object); -static void gtk_color_selection_realize (GtkWidget *widget); static void update_color (GtkColorSelection *colorsel); static void gtk_color_selection_set_property (GObject *object, guint prop_id, @@ -155,6 +154,9 @@ static void gtk_color_selection_get_property (GObject *object GValue *value, GParamSpec *pspec); +static void gtk_color_selection_realize (GtkWidget *widget); +static void gtk_color_selection_unrealize (GtkWidget *widget); + static gint gtk_color_selection_get_palette_size (GtkColorSelection *colorsel); static gboolean gtk_color_selection_get_palette_color (GtkColorSelection *colorsel, gint index, @@ -166,7 +168,10 @@ static void gtk_color_selection_unset_palette_color (GtkColorSelection *colo gint index); static GdkGC *get_focus_gc (GtkWidget *drawing_area, gint *focus_width); -static void default_change_palette_func (const GdkColor *colors, +static void default_noscreen_change_palette_func (const GdkColor *colors, + gint n_colors); +static void default_change_palette_func (GdkScreen *screen, + const GdkColor *colors, gint n_colors); static gpointer parent_class = NULL; @@ -174,9 +179,8 @@ static guint color_selection_signals[LAST_SIGNAL] = { 0 }; static gchar* default_colors = "black:white:gray50:red:purple:blue:light blue:green:yellow:orange:lavender:brown:goldenrod4:dodger blue:pink:light green:gray10:gray30:gray75:gray90"; -static GtkColorSelectionChangePaletteFunc change_palette_hook = default_change_palette_func; - -static GdkColor current_colors[GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT]; +static GtkColorSelectionChangePaletteFunc noscreen_change_palette_hook = default_noscreen_change_palette_func; +static GtkColorSelectionChangePaletteWithScreenFunc change_palette_hook = default_change_palette_func; /* The cursor for the dropper */ #define DROPPER_WIDTH 17 @@ -199,8 +203,6 @@ static char dropper_mask[] = { 0x7c, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x02, 0x00, 0x00, }; -static GdkCursor *picker_cursor = NULL; - /* XPM */ static char *picker[] = { @@ -269,6 +271,8 @@ color_sample_drag_begin (GtkWidget *widget, priv = colorsel->private_data; window = gtk_window_new (GTK_WINDOW_POPUP); + gtk_window_set_screen (GTK_WINDOW (window), + gtk_widget_get_screen (widget)); gtk_widget_set_app_paintable (GTK_WIDGET (window), TRUE); gtk_widget_set_usize (window, 48, 32); gtk_widget_realize (window); @@ -694,6 +698,8 @@ palette_drag_begin (GtkWidget *widget, priv = colorsel->private_data; window = gtk_window_new (GTK_WINDOW_POPUP); + gtk_window_set_screen (GTK_WINDOW (window), + gtk_widget_get_screen (widget)); gtk_widget_set_app_paintable (GTK_WIDGET (window), TRUE); gtk_widget_set_usize (window, 48, 32); gtk_widget_realize (window); @@ -744,6 +750,46 @@ palette_drag_end (GtkWidget *widget, gtk_object_set_data (GTK_OBJECT (widget), "gtk-color-selection-drag-window", NULL); } +static GdkColor * +get_current_colors (GtkColorSelection *colorsel) +{ + GtkSettings *settings; + GdkColor *colors = NULL; + gint n_colors = 0; + gchar *palette; + + settings = gtk_widget_get_settings (GTK_WIDGET (colorsel)); + g_object_get (G_OBJECT (settings), + "gtk-color-palette", &palette, + NULL); + + if (!gtk_color_selection_palette_from_string (palette, &colors, &n_colors)) + { + gtk_color_selection_palette_from_string (default_colors, &colors, &n_colors); + } + else + { + /* If there are less colors provided than the number of slots in the + * color selection, we fill in the rest from the defaults. + */ + if (n_colors < (GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT)) + { + GdkColor *tmp_colors = colors; + gint tmp_n_colors = n_colors; + + gtk_color_selection_palette_from_string (default_colors, &colors, &n_colors); + memcpy (colors, tmp_colors, sizeof (GdkColor) * tmp_n_colors); + + g_free (tmp_colors); + } + } + + g_assert (n_colors >= GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT); + g_free (palette); + + return colors; +} + /* Changes the model color */ static void palette_change_color (GtkWidget *drawing_area, @@ -753,6 +799,8 @@ palette_change_color (GtkWidget *drawing_area, gint x, y; ColorSelectionPrivate *priv; GdkColor gdk_color; + GdkColor *current_colors; + GdkScreen *screen; g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel)); g_return_if_fail (GTK_IS_DRAWING_AREA (drawing_area)); @@ -783,10 +831,25 @@ palette_change_color (GtkWidget *drawing_area, g_assert (x < GTK_CUSTOM_PALETTE_WIDTH || y < GTK_CUSTOM_PALETTE_HEIGHT); + current_colors = get_current_colors (colorsel); current_colors[y * GTK_CUSTOM_PALETTE_WIDTH + x] = gdk_color; - if (change_palette_hook) - (* change_palette_hook) (current_colors, GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT); + screen = gtk_widget_get_screen (GTK_WIDGET (colorsel)); + if (change_palette_hook != default_change_palette_func) + (* change_palette_hook) (screen, current_colors, + GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT); + else if (noscreen_change_palette_hook != default_noscreen_change_palette_func) + { + if (screen != gdk_get_default_screen ()) + g_warning ("gtk_color_selection_set_change_palette_hook used by widget is not on the default screen."); + (* noscreen_change_palette_hook) (current_colors, + GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT); + } + else + (* change_palette_hook) (screen, current_colors, + GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT); + + g_free (current_colors); } /* Changes the view color */ @@ -857,6 +920,7 @@ popup_position_func (GtkMenu *menu, GtkWidget *widget; GtkRequisition req; gint root_x, root_y; + GdkScreen *screen; widget = GTK_WIDGET (user_data); @@ -871,8 +935,9 @@ popup_position_func (GtkMenu *menu, *y = root_y + widget->allocation.height / 2; /* Ensure sanity */ - *x = CLAMP (*x, 0, MAX (0, gdk_screen_width () - req.width)); - *y = CLAMP (*y, 0, MAX (0, gdk_screen_height () - req.height)); + screen = gtk_widget_get_screen (widget); + *x = CLAMP (*x, 0, MAX (0, gdk_screen_get_width (screen) - req.width)); + *y = CLAMP (*y, 0, MAX (0, gdk_screen_get_height (screen) - req.height)); } static void @@ -1088,28 +1153,30 @@ palette_new (GtkColorSelection *colorsel) * */ -static void -initialize_cursor (void) +static GdkCursor * +make_picker_cursor (GdkScreen *screen) { + GdkCursor *cursor; GdkColor fg, bg; GdkPixmap *pixmap = - gdk_bitmap_create_from_data (NULL, - dropper_bits, - DROPPER_WIDTH, DROPPER_HEIGHT); + gdk_bitmap_create_from_data (gdk_screen_get_root_window (screen), + dropper_bits, DROPPER_WIDTH, DROPPER_HEIGHT); + GdkPixmap *mask = - gdk_bitmap_create_from_data (NULL, - dropper_mask, - DROPPER_WIDTH, DROPPER_HEIGHT); + gdk_bitmap_create_from_data (gdk_screen_get_root_window (screen), + dropper_mask, DROPPER_WIDTH, DROPPER_HEIGHT); + - gdk_color_white (gdk_colormap_get_system (), &bg); - gdk_color_black (gdk_colormap_get_system (), &fg); + gdk_color_white (gdk_screen_get_system_colormap (screen), &bg); + gdk_color_black (gdk_screen_get_system_colormap (screen), &fg); - picker_cursor = gdk_cursor_new_from_pixmap (pixmap, mask, &fg, &bg, DROPPER_X_HOT ,DROPPER_Y_HOT); + cursor = gdk_cursor_new_from_pixmap (pixmap, mask, &fg, &bg, DROPPER_X_HOT ,DROPPER_Y_HOT); gdk_pixmap_unref (pixmap); gdk_pixmap_unref (mask); - + + return cursor; } static void @@ -1122,12 +1189,13 @@ grab_color_at_mouse (GtkWidget *invisible, guint32 pixel; GtkColorSelection *colorsel = data; ColorSelectionPrivate *priv; - GdkColormap *colormap = gdk_colormap_get_system (); GdkColor color; + GdkColormap *colormap = gdk_screen_get_system_colormap (gtk_widget_get_screen (invisible)); + GdkWindow *root_window = gdk_screen_get_root_window (gtk_widget_get_screen (invisible)); priv = colorsel->private_data; - image = gdk_image_get (GDK_ROOT_PARENT (), x_root, y_root, 1, 1); + image = gdk_image_get (root_window, x_root, y_root, 1, 1); pixel = gdk_image_get_pixel (image, 0, 0); gdk_image_unref (image); @@ -1152,12 +1220,14 @@ shutdown_eyedropper (GtkWidget *widget) { GtkColorSelection *colorsel; ColorSelectionPrivate *priv; + GdkDisplay *display = gtk_widget_get_display (widget); + guint32 time = gtk_get_current_event_time (); colorsel = GTK_COLOR_SELECTION (widget); priv = colorsel->private_data; - gdk_keyboard_ungrab (gtk_get_current_event_time ()); - gdk_pointer_ungrab (gtk_get_current_event_time ()); + gdk_display_keyboard_ungrab (display, time); + gdk_display_pointer_ungrab (display, time); gtk_grab_remove (priv->dropper_grab_widget); } @@ -1256,16 +1326,14 @@ static void get_screen_color (GtkWidget *button) { GtkColorSelection *colorsel = gtk_object_get_data (GTK_OBJECT (button), "COLORSEL"); - ColorSelectionPrivate *priv = colorsel->private_data; + ColorSelectionPrivate *priv = colorsel->private_data; + GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (button)); + GdkCursor *picker_cursor; + GdkGrabStatus grab_status; - if (picker_cursor == NULL) - { - initialize_cursor (); - } - if (priv->dropper_grab_widget == NULL) { - priv->dropper_grab_widget = gtk_invisible_new (); + priv->dropper_grab_widget = gtk_invisible_new_for_screen (screen); gtk_widget_add_events (priv->dropper_grab_widget, GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK); @@ -1281,14 +1349,18 @@ get_screen_color (GtkWidget *button) return; } - if (gdk_pointer_grab (priv->dropper_grab_widget->window, - FALSE, - GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK, - NULL, - picker_cursor, - gtk_get_current_event_time ()) != GDK_GRAB_SUCCESS) + picker_cursor = make_picker_cursor (screen); + grab_status = gdk_pointer_grab (priv->dropper_grab_widget->window, + FALSE, + GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK, + NULL, + picker_cursor, + gtk_get_current_event_time ()); + gdk_cursor_unref (picker_cursor); + + if (grab_status != GDK_GRAB_SUCCESS) { - gdk_keyboard_ungrab (GDK_CURRENT_TIME); + gdk_display_keyboard_ungrab (gtk_widget_get_display (button), GDK_CURRENT_TIME); g_warning ("Failed to grab pointer to do eyedropper"); return; } @@ -1574,44 +1646,13 @@ update_color (GtkColorSelection *colorsel) g_object_unref (colorsel); } - -static void -fill_palette_from_string (const gchar *str) -{ - GdkColor *colors = NULL; - gint n_colors = 0; - - if (str == NULL) - return; - - if (!gtk_color_selection_palette_from_string (str, &colors, &n_colors)) - return; - - if (n_colors > (GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT)) - n_colors = GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT; - - memcpy (current_colors, colors, sizeof (GdkColor) * n_colors); - - g_free (colors); -} - -static void -palette_change_notify_class (GObject *object, - GParamSpec *pspec) -{ - gchar *str = NULL; - - g_object_get (object, pspec->name, &str, NULL); - - fill_palette_from_string (str); - - g_free (str); -} - static void update_palette (GtkColorSelection *colorsel) { + GdkColor *current_colors; gint i, j; + + current_colors = get_current_colors (colorsel); for (i = 0; i < GTK_CUSTOM_PALETTE_HEIGHT; i++) { @@ -1626,6 +1667,8 @@ update_palette (GtkColorSelection *colorsel) ¤t_colors[index]); } } + + g_free (current_colors); } static void @@ -1637,14 +1680,22 @@ palette_change_notify_instance (GObject *object, } static void -default_change_palette_func (const GdkColor *colors, +default_noscreen_change_palette_func (const GdkColor *colors, + gint n_colors) +{ + default_change_palette_func (gdk_get_default_screen (), colors, n_colors); +} + +static void +default_change_palette_func (GdkScreen *screen, + const GdkColor *colors, gint n_colors) { gchar *str; str = gtk_color_selection_palette_to_string (colors, n_colors); - gtk_settings_set_string_property (gtk_settings_get_default (), + gtk_settings_set_string_property (gtk_settings_get_for_screen (screen), "gtk-color-palette", str, "gtk_color_selection_palette_to_string"); @@ -1691,13 +1742,13 @@ gtk_color_selection_class_init (GtkColorSelectionClass *klass) parent_class = gtk_type_class (GTK_TYPE_VBOX); object_class->destroy = gtk_color_selection_destroy; - gobject_class->finalize = gtk_color_selection_finalize; gobject_class->set_property = gtk_color_selection_set_property; gobject_class->get_property = gtk_color_selection_get_property; - - widget_class->realize = gtk_color_selection_realize; + widget_class->realize = gtk_color_selection_realize; + widget_class->unrealize = gtk_color_selection_unrealize; + g_object_class_install_property (gobject_class, PROP_HAS_OPACITY_CONTROL, g_param_spec_boolean ("has_opacity_control", @@ -1749,12 +1800,10 @@ gtk_color_selection_init (GtkColorSelection *colorsel) { GtkWidget *top_hbox; GtkWidget *top_right_vbox; - GtkWidget *table, *label, *hbox, *frame, *vbox; + GtkWidget *table, *label, *hbox, *frame, *vbox, *button; GtkAdjustment *adjust; - GdkPixmap *dropper_pixmap; - GtkWidget *dropper_image; - GtkWidget *button; - GdkBitmap *mask = NULL; + GdkPixbuf *picker_pix = NULL; + GtkWidget *picker_image; gint i, j; ColorSelectionPrivate *priv; @@ -1799,12 +1848,10 @@ gtk_color_selection_init (GtkColorSelection *colorsel) gtk_object_set_data (GTK_OBJECT (button), "COLORSEL", colorsel); gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (get_screen_color), NULL); - dropper_pixmap = gdk_pixmap_colormap_create_from_xpm_d (NULL, gtk_widget_get_colormap (button), &mask, NULL, picker); - dropper_image = gtk_pixmap_new (dropper_pixmap, mask); - gdk_pixmap_unref (dropper_pixmap); - if (mask) - gdk_pixmap_unref (mask); - gtk_container_add (GTK_CONTAINER (button), dropper_image); + picker_pix = gdk_pixbuf_new_from_xpm_data ((const char **) &picker); + picker_image = gtk_image_new_from_pixbuf (picker_pix); + gtk_container_add (GTK_CONTAINER (button), picker_image); + gtk_widget_show (GTK_WIDGET (picker_image)); gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0); gtk_tooltips_set_tip (priv->tooltips, @@ -1940,63 +1987,31 @@ gtk_color_selection_destroy (GtkObject *object) } static void -gtk_color_selection_finalize (GObject *object) +gtk_color_selection_realize (GtkWidget *widget) { - GtkColorSelection *cselection = GTK_COLOR_SELECTION (object); - - if (cselection->private_data) - { - ColorSelectionPrivate *priv; + GtkColorSelection *colorsel = GTK_COLOR_SELECTION (widget); + ColorSelectionPrivate *priv = colorsel->private_data; + GtkSettings *settings = gtk_widget_get_settings (widget); - priv = cselection->private_data; + priv->settings_connection = g_signal_connect (settings, + "notify::gtk-color-palette", + G_CALLBACK (palette_change_notify_instance), + widget); + update_palette (colorsel); - if (priv->settings_connection) - g_signal_handler_disconnect (gtk_settings_get_default (), - priv->settings_connection); - - g_free (cselection->private_data); - cselection->private_data = NULL; - } - - G_OBJECT_CLASS (parent_class)->finalize (object); + GTK_WIDGET_CLASS (parent_class)->realize (widget); } static void -gtk_color_selection_realize (GtkWidget *widget) +gtk_color_selection_unrealize (GtkWidget *widget) { GtkColorSelection *colorsel = GTK_COLOR_SELECTION (widget); ColorSelectionPrivate *priv = colorsel->private_data; - gchar *palette; - static gboolean initialized = FALSE; - - if (!initialized) - { - g_object_get (gtk_settings_get_default (), - "gtk-color-palette", &palette, - NULL); - - fill_palette_from_string (palette); - g_free (palette); - - g_signal_connect (gtk_settings_get_default (), - "notify::gtk-color-palette", - G_CALLBACK (palette_change_notify_class), - NULL); - - initialized = TRUE; - } - - /* Set default colors */ + GtkSettings *settings = gtk_widget_get_settings (widget); - update_palette (colorsel); - priv->settings_connection = - g_signal_connect (gtk_settings_get_default (), - "notify::gtk-color-palette", - G_CALLBACK (palette_change_notify_instance), - colorsel); + g_signal_handler_disconnect (settings, priv->settings_connection); - if (GTK_WIDGET_CLASS (parent_class)->realize) - GTK_WIDGET_CLASS (parent_class)->realize (widget); + GTK_WIDGET_CLASS (parent_class)->unrealize (widget); } /** @@ -2755,6 +2770,10 @@ gtk_color_selection_palette_to_string (const GdkColor *colors, * modify the palette in a color selection. This function should save * the new palette contents, and update the GtkSettings property * "gtk-color-palette" so all GtkColorSelection widgets will be modified. + * + * This function is deprecated in favor of + * gtk_color_selection_set_change_palette_with_screen_hook(), and does + * not work in multihead environments. * * Return value: the previous change palette hook (that was replaced). **/ @@ -2763,6 +2782,29 @@ gtk_color_selection_set_change_palette_hook (GtkColorSelectionChangePaletteFunc { GtkColorSelectionChangePaletteFunc old; + old = noscreen_change_palette_hook; + + noscreen_change_palette_hook = func; + + return old; +} + +/** + * gtk_color_selection_set_change_palette_hook: + * @func: a function to call when the custom palette needs saving. + * + * Installs a global function to be called whenever the user tries to + * modify the palette in a color selection. This function should save + * the new palette contents, and update the GtkSettings property + * "gtk-color-palette" so all GtkColorSelection widgets will be modified. + * + * Return value: the previous change palette hook (that was replaced). + **/ +GtkColorSelectionChangePaletteWithScreenFunc +gtk_color_selection_set_change_palette_with_screen_hook (GtkColorSelectionChangePaletteWithScreenFunc func) +{ + GtkColorSelectionChangePaletteWithScreenFunc old; + old = change_palette_hook; change_palette_hook = func; diff --git a/gtk/gtkcolorsel.h b/gtk/gtkcolorsel.h index 59397d4701..499fb748e6 100644 --- a/gtk/gtkcolorsel.h +++ b/gtk/gtkcolorsel.h @@ -49,6 +49,9 @@ typedef struct _GtkColorSelectionClass GtkColorSelectionClass; typedef void (* GtkColorSelectionChangePaletteFunc) (const GdkColor *colors, gint n_colors); +typedef void (* GtkColorSelectionChangePaletteWithScreenFunc) (GdkScreen *screen, + const GdkColor *colors, + gint n_colors); struct _GtkColorSelection { @@ -107,7 +110,11 @@ gboolean gtk_color_selection_palette_from_string (const gchar *str, gchar* gtk_color_selection_palette_to_string (const GdkColor *colors, gint n_colors); -GtkColorSelectionChangePaletteFunc gtk_color_selection_set_change_palette_hook (GtkColorSelectionChangePaletteFunc func); +#ifndef GDK_MULTIHEAD_SAFE +GtkColorSelectionChangePaletteFunc gtk_color_selection_set_change_palette_hook (GtkColorSelectionChangePaletteFunc func); +#endif + +GtkColorSelectionChangePaletteWithScreenFunc gtk_color_selection_set_change_palette_with_screen_hook (GtkColorSelectionChangePaletteWithScreenFunc func); #ifndef GTK_DISABLE_DEPRECATED /* Deprecated calls: */ diff --git a/gtk/gtkcombo.c b/gtk/gtkcombo.c index 434941cd71..c7e2ed3ddc 100644 --- a/gtk/gtkcombo.c +++ b/gtk/gtkcombo.c @@ -62,6 +62,8 @@ enum { static void gtk_combo_class_init (GtkComboClass *klass); static void gtk_combo_init (GtkCombo *combo); +static void gtk_combo_realize (GtkWidget *widget); +static void gtk_combo_unrealize (GtkWidget *widget); static void gtk_combo_destroy (GtkObject *combo); static GtkListItem *gtk_combo_find (GtkCombo *combo); static gchar * gtk_combo_func (GtkListItem *li); @@ -175,6 +177,8 @@ gtk_combo_class_init (GtkComboClass * klass) oclass->destroy = gtk_combo_destroy; widget_class->size_allocate = gtk_combo_size_allocate; + widget_class->realize = gtk_combo_realize; + widget_class->unrealize = gtk_combo_unrealize; } static void @@ -292,7 +296,8 @@ gtk_combo_window_key_press (GtkWidget *window, if (GTK_WIDGET_HAS_GRAB (combo->popwin)) { gtk_grab_remove (combo->popwin); - gdk_pointer_ungrab (event->time); + gdk_display_pointer_ungrab (gtk_widget_get_display (window), + event->time); } } @@ -423,7 +428,7 @@ gtk_combo_get_pos (GtkCombo * combo, gint * x, gint * y, gint * height, gint * w real_height = MIN (combo->entry->requisition.height, combo->entry->allocation.height); *y += real_height; - avail_height = gdk_screen_height () - *y; + avail_height = gdk_screen_get_height (gtk_widget_get_screen (widget)) - *y; gtk_widget_size_request (combo->list, &list_requisition); min_height = MIN (list_requisition.height, @@ -520,7 +525,8 @@ gtk_combo_popdown_list (GtkCombo *combo) if (GTK_WIDGET_HAS_GRAB (combo->popwin)) { gtk_grab_remove (combo->popwin); - gdk_pointer_ungrab (GDK_CURRENT_TIME); + gdk_display_pointer_ungrab (gtk_widget_get_display (GTK_WIDGET (combo)), + GDK_CURRENT_TIME); } gtk_widget_hide (combo->popwin); @@ -742,12 +748,20 @@ gtk_combo_list_key_press (GtkWidget * widget, GdkEventKey * event, GtkCombo * co } static void +combo_event_box_realize (GtkWidget *widget) +{ + GdkCursor *cursor = gdk_cursor_new_for_screen (gtk_widget_get_screen (widget), + GDK_TOP_LEFT_ARROW); + gdk_window_set_cursor (widget->window, cursor); + gdk_cursor_destroy (cursor); +} + +static void gtk_combo_init (GtkCombo * combo) { GtkWidget *arrow; GtkWidget *frame; GtkWidget *event_box; - GdkCursor *cursor; combo->case_sensitive = FALSE; combo->value_in_list = FALSE; @@ -789,12 +803,10 @@ gtk_combo_init (GtkCombo * combo) event_box = gtk_event_box_new (); gtk_container_add (GTK_CONTAINER (combo->popwin), event_box); + g_signal_connect (event_box, "realize", + G_CALLBACK (combo_event_box_realize), NULL); gtk_widget_show (event_box); - gtk_widget_realize (event_box); - cursor = gdk_cursor_new (GDK_TOP_LEFT_ARROW); - gdk_window_set_cursor (event_box->window, cursor); - gdk_cursor_destroy (cursor); frame = gtk_frame_new (NULL); gtk_container_add (GTK_CONTAINER (event_box), frame); @@ -840,6 +852,28 @@ gtk_combo_init (GtkCombo * combo) GTK_SIGNAL_FUNC (gtk_combo_list_enter), combo); } +static void +gtk_combo_realize (GtkWidget *widget) +{ + GtkCombo *combo = GTK_COMBO (widget); + + gtk_window_set_screen (GTK_WINDOW (combo->popwin), + gtk_widget_get_screen (widget)); + + GTK_WIDGET_CLASS( parent_class )->realize (widget); +} + +static void +gtk_combo_unrealize (GtkWidget *widget) +{ + GtkCombo *combo = GTK_COMBO (widget); + + gtk_combo_popdown_list (combo); + gtk_widget_unrealize (combo->popwin); + + GTK_WIDGET_CLASS (parent_class)->unrealize (widget); +} + GtkType gtk_combo_get_type (void) { diff --git a/gtk/gtkctree.c b/gtk/gtkctree.c index e38a8f7109..3750b364fd 100644 --- a/gtk/gtkctree.c +++ b/gtk/gtkctree.c @@ -2480,7 +2480,8 @@ change_focus_row_expansion (GtkCTree *ctree, clist = GTK_CLIST (ctree); - if (gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (ctree)) + if (gdk_display_pointer_is_grabbed (gtk_widget_get_display (GTK_WIDGET (ctree))) && + GTK_WIDGET_HAS_GRAB (ctree)) return; if (!(node = @@ -4765,10 +4766,12 @@ gtk_ctree_node_set_shift (GtkCTree *ctree, static void remove_grab (GtkCList *clist) { - if (gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (clist)) + if (gdk_display_pointer_is_grabbed (gtk_widget_get_display (GTK_WIDGET (clist))) && + GTK_WIDGET_HAS_GRAB (clist)) { gtk_grab_remove (GTK_WIDGET (clist)); - gdk_pointer_ungrab (GDK_CURRENT_TIME); + gdk_display_pointer_ungrab (gtk_widget_get_display (GTK_WIDGET (clist)), + GDK_CURRENT_TIME); } if (clist->htimer) diff --git a/gtk/gtkcurve.c b/gtk/gtkcurve.c index c2eec38668..f3fb148ffe 100644 --- a/gtk/gtkcurve.c +++ b/gtk/gtkcurve.c @@ -652,7 +652,8 @@ gtk_curve_graph_events (GtkWidget *widget, GdkEvent *event, GtkCurve *c) c->cursor_type = new_type; - cursor = gdk_cursor_new (c->cursor_type); + cursor = gdk_cursor_new_for_screen (gtk_widget_get_screen (w), + c->cursor_type); gdk_window_set_cursor (w->window, cursor); gdk_cursor_destroy (cursor); } @@ -722,14 +723,15 @@ gtk_curve_size_graph (GtkCurve *curve) { gint width, height; gfloat aspect; + GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (curve)); width = (curve->max_x - curve->min_x) + 1; height = (curve->max_y - curve->min_y) + 1; aspect = width / (gfloat) height; - if (width > gdk_screen_width () / 4) - width = gdk_screen_width () / 4; - if (height > gdk_screen_height () / 4) - height = gdk_screen_height () / 4; + if (width > gdk_screen_get_width (screen) / 4) + width = gdk_screen_get_width (screen) / 4; + if (height > gdk_screen_get_height (screen) / 4) + height = gdk_screen_get_height (screen) / 4; if (aspect < 1.0) width = height * aspect; @@ -857,6 +859,7 @@ gtk_curve_set_vector (GtkCurve *c, int veclen, gfloat vector[]) GtkCurveType old_type; gfloat rx, dx, ry; gint i, height; + GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (c)); old_type = c->curve_type; c->curve_type = GTK_CURVE_TYPE_FREE; @@ -866,8 +869,8 @@ gtk_curve_set_vector (GtkCurve *c, int veclen, gfloat vector[]) else { height = (c->max_y - c->min_y); - if (height > gdk_screen_height () / 4) - height = gdk_screen_height () / 4; + if (height > gdk_screen_get_height (screen) / 4) + height = gdk_screen_get_height (screen) / 4; c->height = height; c->num_points = veclen; diff --git a/gtk/gtkdnd.c b/gtk/gtkdnd.c index ca209fade0..ab7b35ef46 100644 --- a/gtk/gtkdnd.c +++ b/gtk/gtkdnd.c @@ -36,7 +36,6 @@ #include "gtkstock.h" #include "gtkwindow.h" -static GSList *drag_widgets = NULL; static GSList *source_widgets = NULL; typedef struct _GtkDragSourceSite GtkDragSourceSite; @@ -180,8 +179,9 @@ static void gtk_drag_get_event_actions (GdkEvent *event, GdkDragAction actions, GdkDragAction *suggested_action, GdkDragAction *possible_actions); -static GdkCursor * gtk_drag_get_cursor (GdkDragAction action); -static GtkWidget *gtk_drag_get_ipc_widget (void); +static GdkCursor * gtk_drag_get_cursor (GdkScreen *screen, + GdkDragAction action); +static GtkWidget *gtk_drag_get_ipc_widget (GdkScreen *screen); static void gtk_drag_release_ipc_widget (GtkWidget *widget); static gboolean gtk_drag_highlight_expose (GtkWidget *widget, @@ -366,20 +366,25 @@ static const gint n_drag_cursors = sizeof (drag_cursors) / sizeof (drag_cursors[ *************************************************************/ static GtkWidget * -gtk_drag_get_ipc_widget (void) +gtk_drag_get_ipc_widget (GdkScreen *screen) { GtkWidget *result; + GSList *drag_widgets = g_object_get_data (G_OBJECT (screen), + "gtk-dnd-ipc-widgets"); if (drag_widgets) { GSList *tmp = drag_widgets; result = drag_widgets->data; drag_widgets = drag_widgets->next; + g_object_set_data (G_OBJECT (screen), + "gtk-dnd-ipc-widgets", + drag_widgets); g_slist_free_1 (tmp); } else { - result = gtk_invisible_new (); + result = gtk_invisible_new_for_screen (screen); gtk_widget_show (result); } @@ -397,7 +402,13 @@ gtk_drag_get_ipc_widget (void) static void gtk_drag_release_ipc_widget (GtkWidget *widget) { + GdkScreen *screen = gtk_widget_get_screen (widget); + GSList *drag_widgets = g_object_get_data (G_OBJECT (screen), + "gtk-dnd-ipc-widgets"); drag_widgets = g_slist_prepend (drag_widgets, widget); + g_object_set_data (G_OBJECT (screen), + "gtk-dnd-ipc-widgets", + drag_widgets); } static guint32 @@ -538,29 +549,39 @@ gtk_drag_get_event_actions (GdkEvent *event, } static GdkCursor * -gtk_drag_get_cursor (GdkDragAction action) +gtk_drag_get_cursor (GdkScreen *screen, + GdkDragAction action) { gint i; for (i = 0 ; i < n_drag_cursors - 1; i++) if (drag_cursors[i].action == action) break; + if (drag_cursors[i].cursor != NULL) + { + if (screen != gdk_cursor_get_screen (drag_cursors[i].cursor)) + { + gdk_cursor_unref (drag_cursors[i].cursor); + drag_cursors[i].cursor = NULL; + } + } if (drag_cursors[i].cursor == NULL) { + GdkColormap *colormap; GdkColor fg, bg; GdkPixmap *pixmap = - gdk_bitmap_create_from_data (NULL, - drag_cursors[i].bits, - CURSOR_WIDTH, CURSOR_HEIGHT); + gdk_bitmap_create_from_data (gdk_screen_get_root_window (screen), + drag_cursors[i].bits, CURSOR_WIDTH, CURSOR_HEIGHT); + GdkPixmap *mask = - gdk_bitmap_create_from_data (NULL, - drag_cursors[i].mask, - CURSOR_WIDTH, CURSOR_HEIGHT); + gdk_bitmap_create_from_data (gdk_screen_get_root_window (screen), + drag_cursors[i].mask, CURSOR_WIDTH, CURSOR_HEIGHT); - gdk_color_white (gdk_colormap_get_system (), &bg); - gdk_color_black (gdk_colormap_get_system (), &fg); + colormap = gdk_screen_get_system_colormap (screen); + gdk_color_white (colormap, &bg); + gdk_color_black (colormap, &fg); drag_cursors[i].cursor = gdk_cursor_new_from_pixmap (pixmap, mask, &fg, &bg, 0, 0); @@ -597,7 +618,7 @@ gtk_drag_get_data (GtkWidget *widget, g_return_if_fail (widget != NULL); g_return_if_fail (context != NULL); - selection_widget = gtk_drag_get_ipc_widget (); + selection_widget = gtk_drag_get_ipc_widget (gtk_widget_get_screen (widget)); gdk_drag_context_ref (context); gtk_widget_ref (widget); @@ -684,7 +705,7 @@ gtk_drag_finish (GdkDragContext *context, if (target != GDK_NONE) { - GtkWidget *selection_widget = gtk_drag_get_ipc_widget (); + GtkWidget *selection_widget = gtk_drag_get_ipc_widget (gdk_drawable_get_screen (context->source_window)); gdk_drag_context_ref (context); @@ -1375,7 +1396,7 @@ gtk_drag_proxy_begin (GtkWidget *widget, dest_info->proxy_source = NULL; } - ipc_widget = gtk_drag_get_ipc_widget (); + ipc_widget = gtk_drag_get_ipc_widget (gtk_widget_get_screen (widget)); context = gdk_drag_begin (ipc_widget->window, dest_info->context->targets); @@ -1786,7 +1807,7 @@ gtk_drag_begin (GtkWidget *widget, tmp_list = tmp_list->prev; } - ipc_widget = gtk_drag_get_ipc_widget (); + ipc_widget = gtk_drag_get_ipc_widget (gtk_widget_get_screen (widget)); source_widgets = g_slist_prepend (source_widgets, ipc_widget); context = gdk_drag_begin (ipc_widget->window, targets); @@ -1816,7 +1837,7 @@ gtk_drag_begin (GtkWidget *widget, gtk_drag_get_event_actions (event, info->button, actions, &suggested_action, &possible_actions); - info->cursor = gtk_drag_get_cursor (suggested_action); + info->cursor = gtk_drag_get_cursor (gtk_widget_get_screen (widget), suggested_action); /* Set cur_x, cur_y here so if the "drag_begin" signal shows * the drag icon, it will be in the right place @@ -1828,11 +1849,8 @@ gtk_drag_begin (GtkWidget *widget, } else { - gint x, y; - gdk_window_get_pointer (GDK_ROOT_PARENT (), &x, &y, NULL); - - info->cur_x = x; - info->cur_y = y; + gdk_window_get_pointer (gtk_widget_get_root_window (widget), + &info->cur_x, &info->cur_y, NULL); } gtk_signal_emit_by_name (GTK_OBJECT (widget), "drag_begin", @@ -2163,13 +2181,19 @@ set_icon_stock_pixbuf (GdkDragContext *context, gint width, height; GdkPixmap *pixmap; GdkPixmap *mask; - + GdkScreen *screen; + GdkColormap *colormap; + g_return_if_fail (context != NULL); g_return_if_fail (pixbuf != NULL || stock_id != NULL); g_return_if_fail (pixbuf == NULL || stock_id == NULL); - - gtk_widget_push_colormap (gdk_rgb_get_colormap ()); + + screen = gdk_drawable_get_screen (context->source_window); + colormap = gdk_screen_get_rgb_colormap (screen); + + gtk_widget_push_colormap (colormap); window = gtk_window_new (GTK_WINDOW_POPUP); + gtk_window_set_screen (GTK_WINDOW (window), screen); gtk_widget_pop_colormap (); gtk_widget_set_events (window, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK); @@ -2197,7 +2221,7 @@ set_icon_stock_pixbuf (GdkDragContext *context, gdk_pixbuf_get_height (pixbuf)); gtk_widget_realize (window); - gdk_pixbuf_render_pixmap_and_mask (pixbuf, &pixmap, &mask, 128); + gdk_pixbuf_render_pixmap_and_mask_for_colormap (pixbuf, colormap, &pixmap, &mask, 128); gdk_window_set_back_pixmap (window->window, pixmap, FALSE); @@ -2291,6 +2315,7 @@ gtk_drag_set_icon_pixmap (GdkDragContext *context, gtk_widget_push_colormap (colormap); window = gtk_window_new (GTK_WINDOW_POPUP); + gtk_window_set_screen (GTK_WINDOW (window), gdk_drawable_get_screen (context->source_window)); gtk_widget_set_events (window, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK); gtk_widget_set_app_paintable (GTK_WIDGET (window), TRUE); @@ -2433,7 +2458,8 @@ _gtk_drag_source_handle_event (GtkWidget *widget, } else { - cursor = gtk_drag_get_cursor (event->dnd.context->action); + cursor = gtk_drag_get_cursor (gtk_widget_get_screen (widget), + event->dnd.context->action); if (info->cursor != cursor) { gdk_pointer_grab (widget->window, FALSE, @@ -2488,7 +2514,10 @@ gtk_drag_source_check_selection (GtkDragSourceInfo *info, tmp_list = tmp_list->next; } - gtk_selection_owner_set (info->ipc_widget, selection, time); + gtk_selection_owner_set_for_display (gtk_widget_get_display (info->widget), + info->ipc_widget, + selection, + time); info->selections = g_list_prepend (info->selections, GUINT_TO_POINTER (selection)); @@ -2580,12 +2609,15 @@ static void gtk_drag_source_release_selections (GtkDragSourceInfo *info, guint32 time) { + GdkDisplay *display = gtk_widget_get_display (info->widget); GList *tmp_list = info->selections; + while (tmp_list) { GdkAtom selection = GDK_POINTER_TO_ATOM (tmp_list->data); - if (gdk_selection_owner_get (selection) == info->ipc_widget->window) - gtk_selection_owner_set (NULL, selection, time); + if (gdk_selection_owner_get_for_display (display, selection) == info->ipc_widget->window) + gtk_selection_owner_set_for_display (display, NULL, selection, time); + tmp_list = tmp_list->next; } @@ -2988,10 +3020,10 @@ gtk_drag_end (GtkDragSourceInfo *info, guint32 time) { GdkEvent send_event; GtkWidget *source_widget = info->widget; + GdkDisplay *display = gtk_widget_get_display (source_widget); - gdk_pointer_ungrab (time); - gdk_keyboard_ungrab (time); - + gdk_display_pointer_ungrab (display, time); + gdk_display_keyboard_ungrab (display, time); gtk_grab_remove (info->ipc_widget); gtk_signal_disconnect_by_func (GTK_OBJECT (info->ipc_widget), @@ -3009,7 +3041,7 @@ gtk_drag_end (GtkDragSourceInfo *info, guint32 time) */ send_event.button.type = GDK_BUTTON_RELEASE; - send_event.button.window = GDK_ROOT_PARENT (); + send_event.button.window = gtk_widget_get_root_window (source_widget); send_event.button.send_event = TRUE; send_event.button.time = time; send_event.button.x = 0; @@ -3042,7 +3074,9 @@ gtk_drag_motion_cb (GtkWidget *widget, if (event->is_hint) { - gdk_window_get_pointer (GDK_ROOT_PARENT(), &x_root, &y_root, NULL); + GdkWindow *root_window = gtk_widget_get_root_window (widget); + + gdk_window_get_pointer (root_window, &x_root, &y_root, NULL); event->x_root = x_root; event->y_root = y_root; } @@ -3067,6 +3101,7 @@ gtk_drag_key_cb (GtkWidget *widget, { GtkDragSourceInfo *info = (GtkDragSourceInfo *)data; GdkModifierType state; + GdkWindow *root_window; if (event->type == GDK_KEY_PRESS) { @@ -3086,7 +3121,8 @@ gtk_drag_key_cb (GtkWidget *widget, * to query it here. We could use XGetModifierMapping, but * that would be overkill. */ - gdk_window_get_pointer (GDK_ROOT_PARENT(), NULL, NULL, &state); + root_window = gtk_widget_get_root_window (widget); + gdk_window_get_pointer (root_window, NULL, NULL, &state); event->state = state; gtk_drag_update (info, info->cur_x, info->cur_y, (GdkEvent *)event); diff --git a/gtk/gtkentry.c b/gtk/gtkentry.c index 99f80152e9..5200bf2165 100644 --- a/gtk/gtkentry.c +++ b/gtk/gtkentry.c @@ -961,7 +961,7 @@ gtk_entry_realize (GtkWidget *widget) get_text_area_size (entry, &attributes.x, &attributes.y, &attributes.width, &attributes.height); - attributes.cursor = gdk_cursor_new (GDK_XTERM); + attributes.cursor = gdk_cursor_new_for_screen (gtk_widget_get_screen (widget), GDK_XTERM); attributes_mask |= GDK_WA_CURSOR; entry->text_area = gdk_window_new (widget->window, &attributes, attributes_mask); @@ -979,14 +979,20 @@ gtk_entry_realize (GtkWidget *widget) gtk_im_context_set_client_window (entry->im_context, entry->text_area); gtk_entry_adjust_scroll (entry); + gtk_entry_update_primary_selection (entry); } static void gtk_entry_unrealize (GtkWidget *widget) { GtkEntry *entry = GTK_ENTRY (widget); + GtkClipboard *clipboard; gtk_im_context_set_client_window (entry->im_context, entry->text_area); + + clipboard = gtk_widget_get_clipboard (widget, GDK_SELECTION_PRIMARY); + if (gtk_clipboard_get_owner (clipboard) == G_OBJECT (entry)) + gtk_clipboard_clear (clipboard); if (entry->text_area) { @@ -1418,7 +1424,7 @@ gtk_entry_motion_notify (GtkWidget *widget, { GdkCursor *cursor; - cursor = gdk_cursor_new (GDK_XTERM); + cursor = gdk_cursor_new_for_screen (gtk_widget_get_screen (widget), GDK_XTERM); gdk_window_set_cursor (entry->text_area, cursor); gdk_cursor_unref (cursor); entry->mouse_cursor_obscured = FALSE; @@ -1562,7 +1568,7 @@ gtk_entry_focus_in (GtkWidget *widget, entry->need_im_reset = TRUE; gtk_im_context_focus_in (entry->im_context); - g_signal_connect (gdk_keymap_get_default (), + g_signal_connect (gdk_keymap_get_for_display (gtk_widget_get_display (widget)), "direction_changed", G_CALLBACK (gtk_entry_keymap_direction_changed), entry); @@ -1584,7 +1590,7 @@ gtk_entry_focus_out (GtkWidget *widget, gtk_entry_check_cursor_blink (entry); - g_signal_handlers_disconnect_by_func (gdk_keymap_get_default (), + g_signal_handlers_disconnect_by_func (gdk_keymap_get_for_display (gtk_widget_get_display (widget)), (gpointer) gtk_entry_keymap_direction_changed, entry); @@ -1599,7 +1605,7 @@ gtk_entry_grab_focus (GtkWidget *widget) GTK_WIDGET_CLASS (parent_class)->grab_focus (widget); - g_object_get (G_OBJECT (gtk_settings_get_default ()), + g_object_get (G_OBJECT (gtk_widget_get_settings (widget)), "gtk-entry-select-on-focus", &select_on_focus, NULL); @@ -1843,7 +1849,7 @@ gtk_entry_real_insert_text (GtkEditable *editable, n_chars = g_utf8_strlen (new_text, new_text_length); if (entry->text_max_length > 0 && n_chars + entry->text_length > entry->text_max_length) { - gdk_beep (); + gdk_display_beep (gtk_widget_get_display (GTK_WIDGET (entry))); n_chars = entry->text_max_length - entry->text_length; new_text_length = g_utf8_offset_to_pointer (new_text, n_chars) - new_text; } @@ -1947,8 +1953,9 @@ static gint get_better_cursor_x (GtkEntry *entry, gint offset) { + GdkKeymap *keymap = gdk_keymap_get_for_display (gtk_widget_get_display (GTK_WIDGET (entry))); GtkTextDirection keymap_direction = - (gdk_keymap_get_direction (gdk_keymap_get_default ()) == PANGO_DIRECTION_LTR) ? + (gdk_keymap_get_direction (keymap) == PANGO_DIRECTION_LTR) ? GTK_TEXT_DIR_LTR : GTK_TEXT_DIR_RTL; GtkTextDirection widget_direction = gtk_widget_get_direction (GTK_WIDGET (entry)); gboolean split_cursor; @@ -2157,7 +2164,9 @@ gtk_entry_copy_clipboard (GtkEntry *entry) if (gtk_editable_get_selection_bounds (editable, &start, &end)) { gchar *str = gtk_entry_get_public_chars (entry, start, end); - gtk_clipboard_set_text (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD), str, -1); + gtk_clipboard_set_text (gtk_widget_get_clipboard (GTK_WIDGET (entry), + GDK_SELECTION_CLIPBOARD), + str, -1); g_free (str); } } @@ -2676,8 +2685,9 @@ static void gtk_entry_draw_cursor (GtkEntry *entry, CursorType type) { + GdkKeymap *keymap = gdk_keymap_get_for_display (gtk_widget_get_display (GTK_WIDGET (entry))); GtkTextDirection keymap_direction = - (gdk_keymap_get_direction (gdk_keymap_get_default ()) == PANGO_DIRECTION_LTR) ? + (gdk_keymap_get_direction (keymap) == PANGO_DIRECTION_LTR) ? GTK_TEXT_DIR_LTR : GTK_TEXT_DIR_RTL; GtkTextDirection widget_direction = gtk_widget_get_direction (GTK_WIDGET (entry)); @@ -2937,8 +2947,9 @@ gtk_entry_move_visually (GtkEntry *entry, strong = TRUE; else { + GdkKeymap *keymap = gdk_keymap_get_for_display (gtk_widget_get_display (GTK_WIDGET (entry))); GtkTextDirection keymap_direction = - (gdk_keymap_get_direction (gdk_keymap_get_default ()) == PANGO_DIRECTION_LTR) ? + (gdk_keymap_get_direction (keymap) == PANGO_DIRECTION_LTR) ? GTK_TEXT_DIR_LTR : GTK_TEXT_DIR_RTL; strong = keymap_direction == gtk_widget_get_direction (GTK_WIDGET (entry)); @@ -3170,7 +3181,7 @@ gtk_entry_paste (GtkEntry *entry, GdkAtom selection) { g_object_ref (G_OBJECT (entry)); - gtk_clipboard_request_text (gtk_clipboard_get (selection), + gtk_clipboard_request_text (gtk_widget_get_clipboard (GTK_WIDGET (entry), selection), paste_received, entry); } @@ -3210,8 +3221,13 @@ gtk_entry_update_primary_selection (GtkEntry *entry) { "COMPOUND_TEXT", 0, 0 } }; - GtkClipboard *clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY); + GtkClipboard *clipboard; gint start, end; + + if (!GTK_WIDGET_REALIZED (entry)) + return; + + clipboard = gtk_widget_get_clipboard (GTK_WIDGET (entry), GDK_SELECTION_PRIMARY); if (gtk_editable_get_selection_bounds (GTK_EDITABLE (entry), &start, &end)) { @@ -3784,6 +3800,7 @@ popup_position_func (GtkMenu *menu, { GtkEntry *entry = GTK_ENTRY (user_data); GtkWidget *widget = GTK_WIDGET (entry); + GdkScreen *screen = gtk_widget_get_screen (widget); GtkRequisition req; g_return_if_fail (GTK_WIDGET_REALIZED (entry)); @@ -3795,8 +3812,8 @@ popup_position_func (GtkMenu *menu, *x += widget->allocation.width / 2; *y += widget->allocation.height; - *x = CLAMP (*x, 0, MAX (0, gdk_screen_width () - req.width)); - *y = CLAMP (*y, 0, MAX (0, gdk_screen_height () - req.height)); + *x = CLAMP (*x, 0, MAX (0, gdk_screen_get_width (screen) - req.width)); + *y = CLAMP (*y, 0, MAX (0, gdk_screen_get_height (screen) - req.height)); } @@ -3925,7 +3942,7 @@ gtk_entry_do_popup (GtkEntry *entry, info->time = gtk_get_current_event_time (); } - gtk_clipboard_request_contents (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD), + gtk_clipboard_request_contents (gtk_widget_get_clipboard (GTK_WIDGET (entry), GDK_SELECTION_CLIPBOARD), gdk_atom_intern ("TARGETS", FALSE), popup_targets_received, info); diff --git a/gtk/gtkfilesel.c b/gtk/gtkfilesel.c index 9de3daa872..10992602ef 100644 --- a/gtk/gtkfilesel.c +++ b/gtk/gtkfilesel.c @@ -1734,7 +1734,7 @@ gtk_file_selection_insert_text (GtkWidget *widget, if (!filename) { - gdk_beep (); + gdk_display_beep (gtk_widget_get_display (widget)); gtk_signal_emit_stop_by_name (GTK_OBJECT (widget), "insert_text"); return FALSE; } diff --git a/gtk/gtkfontsel.c b/gtk/gtkfontsel.c index 6e5b402428..f46e2ccb26 100644 --- a/gtk/gtkfontsel.c +++ b/gtk/gtkfontsel.c @@ -119,6 +119,8 @@ static void gtk_font_selection_get_property (GObject *object, GParamSpec *pspec); static void gtk_font_selection_init (GtkFontSelection *fontsel); static void gtk_font_selection_finalize (GObject *object); +static void gtk_font_selection_hierarchy_changed (GtkWidget *widget, + GtkWidget *previous_toplevel); /* These are the callbacks & related functions. */ static void gtk_font_selection_select_font (GtkTreeSelection *selection, @@ -190,11 +192,14 @@ static void gtk_font_selection_class_init (GtkFontSelectionClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); font_selection_parent_class = gtk_type_class (GTK_TYPE_VBOX); gobject_class->set_property = gtk_font_selection_set_property; gobject_class->get_property = gtk_font_selection_get_property; + + widget_class->hierarchy_changed = gtk_font_selection_hierarchy_changed; g_object_class_install_property (gobject_class, PROP_FONT_NAME, @@ -439,8 +444,6 @@ gtk_font_selection_init (GtkFontSelection *fontsel) g_list_free (focus_chain); /* Insert the fonts. */ - gtk_font_selection_show_available_fonts (fontsel); - g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (fontsel->family_list)), "changed", G_CALLBACK (gtk_font_selection_select_font), fontsel); @@ -448,13 +451,9 @@ gtk_font_selection_init (GtkFontSelection *fontsel) GTK_SIGNAL_FUNC (gtk_font_selection_scroll_on_map), fontsel); - gtk_font_selection_show_available_styles (fontsel); - g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (fontsel->face_list)), "changed", G_CALLBACK (gtk_font_selection_select_style), fontsel); - gtk_font_selection_show_available_sizes (fontsel, TRUE); - g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (fontsel->size_list)), "changed", G_CALLBACK (gtk_font_selection_select_size), fontsel); @@ -487,8 +486,6 @@ gtk_font_selection_init (GtkFontSelection *fontsel) gtk_box_pack_start (GTK_BOX (text_box), fontsel->preview_entry, TRUE, TRUE, 0); - gtk_font_selection_update_preview (fontsel); - gtk_widget_pop_composite_child(); } @@ -519,6 +516,63 @@ gtk_font_selection_finalize (GObject *object) } static void +fontsel_screen_changed (GtkFontSelection *fontsel) +{ + GdkScreen *old_screen = g_object_get_data (G_OBJECT (fontsel), "gtk-font-selection-screen"); + GdkScreen *screen; + + if (gtk_widget_has_screen (GTK_WIDGET (fontsel))) + screen = gtk_widget_get_screen (GTK_WIDGET (fontsel)); + else + screen = NULL; + + if (screen == old_screen) + return; + + if (fontsel->font) + { + gdk_font_unref (fontsel->font); + fontsel->font = NULL; + } + + if (old_screen) + g_object_unref (old_screen); + + if (screen) + { + g_object_ref (screen); + g_object_set_data (G_OBJECT (fontsel), "gtk-font-selection-screen", screen); + + gtk_font_selection_show_available_fonts (fontsel); + gtk_font_selection_show_available_sizes (fontsel, TRUE); + gtk_font_selection_show_available_styles (fontsel); + } + else + g_object_set_data (G_OBJECT (fontsel), "gtk-font-selection-screen", NULL); +} + +static void +gtk_font_selection_hierarchy_changed (GtkWidget *widget, + GtkWidget *previous_toplevel) +{ + GtkWidget *toplevel; + + if (previous_toplevel) + g_signal_handlers_disconnect_by_func (previous_toplevel, + (gpointer) fontsel_screen_changed, + widget); + + toplevel = gtk_widget_get_toplevel (widget); + if (GTK_WIDGET_TOPLEVEL (toplevel)) + g_signal_connect_swapped (toplevel, + "notify::screen", + G_CALLBACK (fontsel_screen_changed), + widget); + + fontsel_screen_changed (GTK_FONT_SELECTION (widget)); +} + +static void gtk_font_selection_preview_changed (GtkWidget *entry, GtkFontSelection *fontsel) { @@ -1027,7 +1081,7 @@ gtk_font_selection_get_font (GtkFontSelection *fontsel) if (!fontsel->font) { PangoFontDescription *font_desc = gtk_font_selection_get_font_description (fontsel); - fontsel->font = gdk_font_from_description (font_desc); + fontsel->font = gdk_font_from_description_for_display (gtk_widget_get_display (GTK_WIDGET (fontsel)), font_desc); pango_font_description_free (font_desc); } diff --git a/gtk/gtkgamma.c b/gtk/gtkgamma.c index cc4bf9d677..bb5a12c03c 100644 --- a/gtk/gtkgamma.c +++ b/gtk/gtkgamma.c @@ -393,6 +393,8 @@ button_clicked_callback (GtkWidget *w, gpointer data) gchar buf[64]; c->gamma_dialog = gtk_dialog_new (); + gtk_window_set_screen (GTK_WINDOW (c->gamma_dialog), + gtk_widget_get_screen (w)); gtk_window_set_title (GTK_WINDOW (c->gamma_dialog), _("Gamma")); g_object_add_weak_pointer (G_OBJECT (c->gamma_dialog), (gpointer *)&c->gamma_dialog); diff --git a/gtk/gtkgc.c b/gtk/gtkgc.c index f10f3a97e3..78481a6c0d 100644 --- a/gtk/gtkgc.c +++ b/gtk/gtkgc.c @@ -61,7 +61,6 @@ static gint gtk_gc_drawable_equal (GtkGCDrawable *a, static gint initialize = TRUE; static GCache *gc_cache = NULL; -static GHashTable *gc_drawable_ht = NULL; static GMemChunk *key_mem_chunk = NULL; @@ -97,6 +96,30 @@ gtk_gc_release (GdkGC *gc) g_cache_remove (gc_cache, gc); } +static void +free_gc_drawable (gpointer data) +{ + GtkGCDrawable *drawable = data; + g_object_unref (G_OBJECT (drawable->drawable)); + g_free (drawable); +} + +static GHashTable* +gtk_gc_get_drawable_ht (GdkScreen *screen) +{ + GHashTable *ht = g_object_get_data (G_OBJECT (screen), "gtk-gc-drawable-ht"); + if (!ht) + { + ht = g_hash_table_new_full ((GHashFunc) gtk_gc_drawable_hash, + (GEqualFunc) gtk_gc_drawable_equal, + NULL, free_gc_drawable); + g_object_set_data_full (G_OBJECT (screen), + "gtk-gc-drawable-ht", ht, + (GDestroyNotify)g_hash_table_destroy); + } + + return ht; +} static void gtk_gc_init (void) @@ -110,9 +133,6 @@ gtk_gc_init (void) (GHashFunc) gtk_gc_key_hash, (GHashFunc) gtk_gc_value_hash, (GEqualFunc) gtk_gc_key_equal); - - gc_drawable_ht = g_hash_table_new ((GHashFunc) gtk_gc_drawable_hash, - (GEqualFunc) gtk_gc_drawable_equal); } static GtkGCKey* @@ -143,17 +163,18 @@ gtk_gc_new (gpointer key) GtkGCKey *keyval; GtkGCDrawable *drawable; GdkGC *gc; + GHashTable *ht; keyval = key; - - drawable = g_hash_table_lookup (gc_drawable_ht, &keyval->depth); + ht = gtk_gc_get_drawable_ht (keyval->colormap->screen); + drawable = g_hash_table_lookup (ht, &keyval->depth); if (!drawable) { drawable = g_new (GtkGCDrawable, 1); drawable->depth = keyval->depth; - drawable->drawable = gdk_pixmap_new (NULL, 1, 1, drawable->depth); - - g_hash_table_insert (gc_drawable_ht, &drawable->depth, drawable); + drawable->drawable = gdk_pixmap_new (gdk_screen_get_root_window (keyval->colormap->screen), + 1, 1, drawable->depth); + g_hash_table_insert (ht, &drawable->depth, drawable); } gc = gdk_gc_new_with_values (drawable->drawable, &keyval->values, keyval->mask); @@ -377,7 +398,6 @@ gtk_gc_key_equal (gpointer a, return TRUE; } - static guint gtk_gc_drawable_hash (GtkGCDrawable *d) { diff --git a/gtk/gtkhandlebox.c b/gtk/gtkhandlebox.c index f31ed83a07..da46d0a651 100644 --- a/gtk/gtkhandlebox.c +++ b/gtk/gtkhandlebox.c @@ -432,7 +432,8 @@ gtk_handle_box_realize (GtkWidget *widget) GDK_FOCUS_CHANGE_MASK | GDK_STRUCTURE_MASK); attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; - hb->float_window = gdk_window_new (NULL, &attributes, attributes_mask); + hb->float_window = gdk_window_new (gtk_widget_get_root_window (widget), + &attributes, attributes_mask); gdk_window_set_user_data (hb->float_window, widget); gdk_window_set_decorations (hb->float_window, 0); gdk_window_set_type_hint (hb->float_window, GDK_WINDOW_TYPE_HINT_TOOLBAR); @@ -989,7 +990,8 @@ gtk_handle_box_button_changed (GtkWidget *widget, hb->attach_allocation.height = height; hb->in_drag = TRUE; - fleur = gdk_cursor_new (GDK_FLEUR); + fleur = gdk_cursor_new_for_screen (gdk_drawable_get_screen (widget->window), + GDK_FLEUR); if (gdk_pointer_grab (widget->window, FALSE, (GDK_BUTTON1_MOTION_MASK | @@ -1017,7 +1019,8 @@ gtk_handle_box_button_changed (GtkWidget *widget, if (event->window != widget->window) return FALSE; - gdk_pointer_ungrab (GDK_CURRENT_TIME); + gdk_display_pointer_ungrab (gtk_widget_get_display (widget), + GDK_CURRENT_TIME); hb->in_drag = FALSE; event_handled = TRUE; } @@ -1046,7 +1049,8 @@ gtk_handle_box_motion (GtkWidget *widget, */ new_x = 0; new_y = 0; - gdk_window_get_pointer (NULL, &new_x, &new_y, NULL); + gdk_window_get_pointer (gtk_widget_get_root_window (widget), + &new_x, &new_y, NULL); new_x += hb->float_allocation.x; new_y += hb->float_allocation.y; @@ -1189,9 +1193,9 @@ gtk_handle_box_motion (GtkWidget *widget, /* this extra move is neccessary if we use decorations, or our * window manager insists on decorations. */ - gdk_flush (); + gdk_display_sync (gtk_widget_get_display (widget)); gdk_window_move (hb->float_window, new_x, new_y); - gdk_flush (); + gdk_display_sync (gtk_widget_get_display (widget)); #endif /* 0 */ gtk_signal_emit (GTK_OBJECT (hb), handle_box_signals[SIGNAL_CHILD_DETACHED], @@ -1241,13 +1245,15 @@ gtk_handle_box_delete_event (GtkWidget *widget, static void gtk_handle_box_reattach (GtkHandleBox *hb) { + GtkWidget *widget = GTK_WIDGET (hb); + if (hb->child_detached) { hb->child_detached = FALSE; if (GTK_WIDGET_REALIZED (hb)) { gdk_window_hide (hb->float_window); - gdk_window_reparent (hb->bin_window, GTK_WIDGET (hb)->window, 0, 0); + gdk_window_reparent (hb->bin_window, widget->window, 0, 0); if (GTK_BIN (hb)->child) gtk_signal_emit (GTK_OBJECT (hb), @@ -1259,7 +1265,8 @@ gtk_handle_box_reattach (GtkHandleBox *hb) } if (hb->in_drag) { - gdk_pointer_ungrab (GDK_CURRENT_TIME); + gdk_display_pointer_ungrab (gtk_widget_get_display (GTK_WIDGET (hb)), + GDK_CURRENT_TIME); hb->in_drag = FALSE; } diff --git a/gtk/gtkhsv.c b/gtk/gtkhsv.c index 737c1b4636..a2a77f1358 100644 --- a/gtk/gtkhsv.c +++ b/gtk/gtkhsv.c @@ -753,7 +753,8 @@ set_cross_grab (GtkHSV *hsv, priv = hsv->priv; - cursor = gdk_cursor_new (GDK_CROSSHAIR); + cursor = gdk_cursor_new_for_screen (gtk_widget_get_screen (GTK_WIDGET (hsv)), + GDK_CROSSHAIR); gdk_pointer_grab (priv->window, FALSE, (GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK @@ -853,8 +854,8 @@ gtk_hsv_button_release (GtkWidget *widget, } else g_assert_not_reached (); - gdk_pointer_ungrab (event->time); - + gdk_display_pointer_ungrab (gdk_drawable_get_display (event->window), + event->time); return TRUE; } @@ -979,7 +980,8 @@ paint_ring (GtkHSV *hsv, /* Create clipping mask */ - mask = gdk_pixmap_new (NULL, width, height, 1); + mask = gdk_pixmap_new (GTK_WIDGET (hsv)->window, width, height, 1); + gc = gdk_gc_new (mask); color.pixel = 0; @@ -1219,7 +1221,8 @@ paint_triangle (GtkHSV *hsv, /* Create clipping mask */ - mask = gdk_pixmap_new (NULL, width, height, 1); + mask = gdk_pixmap_new (GTK_WIDGET (hsv)->window, width, height, 1); + gc = gdk_gc_new (mask); color.pixel = 0; diff --git a/gtk/gtkimcontextsimple.c b/gtk/gtkimcontextsimple.c index 937a1a81eb..4a2c99a6d9 100644 --- a/gtk/gtkimcontextsimple.c +++ b/gtk/gtkimcontextsimple.c @@ -1041,7 +1041,7 @@ no_sequence_matches (GtkIMContextSimple *context_simple, context_simple->compose_buffer[0] = 0; if (n_compose > 1) /* Invalid sequence */ { - gdk_beep(); + gdk_display_beep (gdk_drawable_get_display (event->window)); return TRUE; } @@ -1067,6 +1067,7 @@ is_hex_keyval (guint keyval) static guint canonical_hex_keyval (GdkEventKey *event) { + GdkKeymap *keymap = gdk_keymap_get_for_display (gdk_drawable_get_display (event->window)); guint keyval; guint *keyvals = NULL; gint n_vals = 0; @@ -1079,9 +1080,10 @@ canonical_hex_keyval (GdkEventKey *event) /* See if this key would have generated a hex keyval in * any other state, and return that hex keyval if so */ - gdk_keymap_get_entries_for_keycode (NULL, - event->hardware_keycode, NULL, - &keyvals, &n_vals); + gdk_keymap_get_entries_for_keycode (keymap, + event->hardware_keycode, + NULL, + &keyvals, &n_vals); keyval = 0; i = 0; diff --git a/gtk/gtkinvisible.c b/gtk/gtkinvisible.c index e15de3eb5c..7fb23ca89c 100644 --- a/gtk/gtkinvisible.c +++ b/gtk/gtkinvisible.c @@ -27,6 +27,13 @@ #include <gdk/gdk.h> #include "gtksignal.h" #include "gtkinvisible.h" +#include "gtkintl.h" + +enum { + PROP_0, + PROP_SCREEN, + LAST_ARG +}; static void gtk_invisible_class_init (GtkInvisibleClass *klass); static void gtk_invisible_init (GtkInvisible *invisible); @@ -37,6 +44,20 @@ static void gtk_invisible_style_set (GtkWidget *widget, static void gtk_invisible_show (GtkWidget *widget); static void gtk_invisible_size_allocate (GtkWidget *widget, GtkAllocation *allocation); +static void gtk_invisible_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void gtk_invisible_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); + +static GObject *gtk_invisible_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_params); + +GObjectClass *parent_class; GtkType gtk_invisible_get_type (void) @@ -66,11 +87,15 @@ gtk_invisible_get_type (void) static void gtk_invisible_class_init (GtkInvisibleClass *class) { + GObjectClass *gobject_class; GtkObjectClass *object_class; GtkWidgetClass *widget_class; widget_class = (GtkWidgetClass*) class; object_class = (GtkObjectClass*) class; + gobject_class = (GObjectClass*) class; + + parent_class = g_type_class_peek_parent (class); widget_class->realize = gtk_invisible_realize; widget_class->style_set = gtk_invisible_style_set; @@ -78,6 +103,17 @@ gtk_invisible_class_init (GtkInvisibleClass *class) widget_class->size_allocate = gtk_invisible_size_allocate; object_class->destroy = gtk_invisible_destroy; + gobject_class->set_property = gtk_invisible_set_property; + gobject_class->get_property = gtk_invisible_get_property; + gobject_class->constructor = gtk_invisible_constructor; + + g_object_class_install_property (gobject_class, + PROP_SCREEN, + g_param_spec_object ("screen", + _("Screen"), + _("The screen where this window will be displayed."), + GDK_TYPE_SCREEN, + G_PARAM_READWRITE)); } static void @@ -92,6 +128,7 @@ gtk_invisible_init (GtkInvisible *invisible) gtk_object_sink (GTK_OBJECT (invisible)); invisible->has_user_ref_count = TRUE; + invisible->screen = gdk_get_default_screen (); colormap = _gtk_widget_peek_colormap (); if (colormap) @@ -110,13 +147,78 @@ gtk_invisible_destroy (GtkObject *object) } } +/** + * gtk_invisible_new_for_screen: + * @screen: a #GdkScreen which identifies on which + * the new #GtkInvisible will be created. + * + * Creates a new #GtkInvisible object for a specified screen + * + * Return value: a newly created #GtkInvisible object + **/ +GtkWidget* +gtk_invisible_new_for_screen (GdkScreen *screen) +{ + g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL); + + return g_object_new (GTK_TYPE_INVISIBLE, "screen", screen, NULL); +} + +/** + * gtk_invisible_new: + * + * Creates a new #GtkInvisible. + * + * Return value: a new #GtkInvisible. + **/ GtkWidget* gtk_invisible_new (void) { - GtkWidget *result = GTK_WIDGET (gtk_type_new (GTK_TYPE_INVISIBLE)); - gtk_widget_realize (result); + return g_object_new (GTK_TYPE_INVISIBLE, NULL); +} - return result; +/** + * gtk_invisible_set_screen: + * @invisible: a #GtkInvisible. + * @screen: a #GdkScreen. + * + * Sets the #GdkScreen where the #GtkInvisible object will be displayed. + **/ +void +gtk_invisible_set_screen (GtkInvisible *invisible, + GdkScreen *screen) +{ + gboolean was_realized; + + g_return_if_fail (GTK_IS_INVISIBLE (invisible)); + g_return_if_fail (GDK_IS_SCREEN (screen)); + + if (screen == invisible->screen) + return; + + was_realized = GTK_WIDGET_REALIZED (invisible); + + if (was_realized) + gtk_widget_unrealize (GTK_WIDGET (invisible)); + invisible->screen = screen; + if (was_realized) + gtk_widget_realize (GTK_WIDGET (invisible)); +} + +/** + * gtk_invisible_get_screen: + * @invisible: a #GtkInvisible. + * + * Returns the #GdkScreen object associated with @invisible + * + * Return value : the associated #GdkScreen. + **/ +GdkScreen * +gtk_invisible_get_screen (GtkInvisible *invisible) +{ + g_return_val_if_fail (GTK_IS_INVISIBLE (invisible), NULL); + + return invisible->screen; } static void @@ -138,7 +240,9 @@ gtk_invisible_realize (GtkWidget *widget) attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_NOREDIR; - widget->window = gdk_window_new (NULL, &attributes, attributes_mask); + widget->window = gdk_window_new (gtk_widget_get_root_window (widget), + &attributes, attributes_mask); + gdk_window_set_user_data (widget->window, widget); widget->style = gtk_style_attach (widget->style, widget->window); @@ -163,4 +267,63 @@ gtk_invisible_size_allocate (GtkWidget *widget, GtkAllocation *allocation) { widget->allocation = *allocation; +} + + +static void +gtk_invisible_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GtkInvisible *invisible = GTK_INVISIBLE (object); + + switch (prop_id) + { + case PROP_SCREEN: + gtk_invisible_set_screen (invisible, g_value_get_object (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } + +static void +gtk_invisible_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GtkInvisible *invisible = GTK_INVISIBLE (object); + + switch (prop_id) + { + case PROP_SCREEN: + g_value_set_object (value, invisible->screen); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +/* We use a constructor here so that we can realize the invisible on + * the correct screen after the "screen" property has been set + */ +static GObject* +gtk_invisible_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_params) +{ + GObject *object; + + object = (* G_OBJECT_CLASS (parent_class)->constructor) (type, + n_construct_properties, + construct_params); + + gtk_widget_realize (GTK_WIDGET (object)); + + return object; +} + diff --git a/gtk/gtkinvisible.h b/gtk/gtkinvisible.h index d363bb8dd4..044d3deeb9 100644 --- a/gtk/gtkinvisible.h +++ b/gtk/gtkinvisible.h @@ -29,10 +29,7 @@ #include <gtk/gtkwidget.h> -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - +G_BEGIN_DECLS #define GTK_TYPE_INVISIBLE (gtk_invisible_get_type ()) #define GTK_INVISIBLE(obj) (GTK_CHECK_CAST ((obj), GTK_TYPE_INVISIBLE, GtkInvisible)) @@ -49,7 +46,7 @@ struct _GtkInvisible { GtkWidget widget; gboolean has_user_ref_count; - gpointer gtk_reserved1; /* For future GdkScreen * */ + GdkScreen *screen; }; struct _GtkInvisibleClass @@ -63,12 +60,14 @@ struct _GtkInvisibleClass void (*_gtk_reserved4) (void); }; -GtkType gtk_invisible_get_type (void) G_GNUC_CONST; -GtkWidget* gtk_invisible_new (void); +GtkType gtk_invisible_get_type (void) G_GNUC_CONST; -#ifdef __cplusplus -} -#endif /* __cplusplus */ +GtkWidget* gtk_invisible_new (void); +GtkWidget* gtk_invisible_new_for_screen (GdkScreen *screen); +void gtk_invisible_set_screen (GtkInvisible *invisible, + GdkScreen *screen); +GdkScreen* gtk_invisible_get_screen (GtkInvisible *invisible); +G_END_DECLS #endif /* __GTK_INVISIBLE_H__ */ diff --git a/gtk/gtklabel.c b/gtk/gtklabel.c index bafd83c75b..5a58e9eb47 100644 --- a/gtk/gtklabel.c +++ b/gtk/gtklabel.c @@ -674,7 +674,7 @@ gtk_label_mnemonic_activate (GtkWidget *widget, /* barf if there was nothing to activate */ g_warning ("Couldn't find a target for a mnemonic activation."); - gdk_beep (); + gdk_display_beep (gtk_widget_get_display (widget)); return FALSE; } @@ -711,6 +711,9 @@ gtk_label_hierarchy_changed (GtkWidget *widget, GtkWidget *old_toplevel) { GtkLabel *label = GTK_LABEL (widget); + + /* in case the label has been reparented to another screen */ + gtk_label_clear_layout (label); gtk_label_setup_mnemonic (label, label->mnemonic_keyval); } @@ -1426,6 +1429,7 @@ gtk_label_ensure_layout (GtkLabel *label) pango_layout_set_width (label->layout, aux_info->width * PANGO_SCALE); else { + GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (label)); gint wrap_width; pango_layout_set_width (label->layout, -1); @@ -1439,7 +1443,7 @@ gtk_label_ensure_layout (GtkLabel *label) wrap_width = get_label_wrap_width (label); width = MIN (width, wrap_width); width = MIN (width, - PANGO_SCALE * (gdk_screen_width () + 1) / 2); + PANGO_SCALE * (gdk_screen_get_width (screen) + 1) / 2); pango_layout_set_width (label->layout, width); pango_layout_get_extents (label->layout, NULL, &logical_rect); @@ -1682,7 +1686,7 @@ gtk_label_draw_cursor (GtkLabel *label, gint xoffset, gint yoffset) GdkGC *gc; keymap_direction = - (gdk_keymap_get_direction (gdk_keymap_get_default ()) == PANGO_DIRECTION_LTR) ? + (gdk_keymap_get_direction (gdk_keymap_get_for_display (gtk_widget_get_display (widget))) == PANGO_DIRECTION_LTR) ? GTK_TEXT_DIR_LTR : GTK_TEXT_DIR_RTL; widget_direction = gtk_widget_get_direction (widget); @@ -2287,7 +2291,8 @@ gtk_label_create_window (GtkLabel *label) attributes.window_type = GDK_WINDOW_TEMP; attributes.wclass = GDK_INPUT_ONLY; attributes.override_redirect = TRUE; - attributes.cursor = gdk_cursor_new (GDK_XTERM); + attributes.cursor = gdk_cursor_new_for_screen (gtk_widget_get_screen (widget), + GDK_XTERM); attributes.event_mask = gtk_widget_get_events (widget) | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | @@ -2473,7 +2478,8 @@ gtk_label_select_region_index (GtkLabel *label, label->select_info->selection_anchor = anchor_index; label->select_info->selection_end = end_index; - clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY); + clipboard = gtk_widget_get_clipboard (GTK_WIDGET (label), + GDK_SELECTION_PRIMARY); if (anchor_index != end_index) { @@ -2742,8 +2748,9 @@ get_better_cursor (GtkLabel *label, gint *x, gint *y) { + GdkKeymap *keymap = gdk_keymap_get_for_display (gtk_widget_get_display (GTK_WIDGET (label))); GtkTextDirection keymap_direction = - (gdk_keymap_get_direction (gdk_keymap_get_default ()) == PANGO_DIRECTION_LTR) ? + (gdk_keymap_get_direction (keymap) == PANGO_DIRECTION_LTR) ? GTK_TEXT_DIR_LTR : GTK_TEXT_DIR_RTL; GtkTextDirection widget_direction = gtk_widget_get_direction (GTK_WIDGET (label)); gboolean split_cursor; @@ -2847,8 +2854,9 @@ gtk_label_move_visually (GtkLabel *label, strong = TRUE; else { + GdkKeymap *keymap = gdk_keymap_get_for_display (gtk_widget_get_display (GTK_WIDGET (label))); GtkTextDirection keymap_direction = - (gdk_keymap_get_direction (gdk_keymap_get_default ()) == PANGO_DIRECTION_LTR) ? + (gdk_keymap_get_direction (keymap) == PANGO_DIRECTION_LTR) ? GTK_TEXT_DIR_LTR : GTK_TEXT_DIR_RTL; strong = keymap_direction == gtk_widget_get_direction (GTK_WIDGET (label)); @@ -3061,7 +3069,8 @@ gtk_label_copy_clipboard (GtkLabel *label) start = len; if (start != end) - gtk_clipboard_set_text (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD), + gtk_clipboard_set_text (gtk_widget_get_clipboard (GTK_WIDGET (label), + GDK_SELECTION_CLIPBOARD), label->text + start, end - start); } } @@ -3122,6 +3131,7 @@ popup_position_func (GtkMenu *menu, GtkLabel *label; GtkWidget *widget; GtkRequisition req; + GdkScreen *screen; label = GTK_LABEL (user_data); widget = GTK_WIDGET (label); @@ -3130,7 +3140,8 @@ popup_position_func (GtkMenu *menu, return; g_return_if_fail (GTK_WIDGET_REALIZED (label)); - + + screen = gtk_widget_get_screen (widget); gdk_window_get_origin (widget->window, x, y); gtk_widget_size_request (label->select_info->popup_menu, &req); @@ -3138,8 +3149,8 @@ popup_position_func (GtkMenu *menu, *x += widget->allocation.width / 2; *y += widget->allocation.height; - *x = CLAMP (*x, 0, MAX (0, gdk_screen_width () - req.width)); - *y = CLAMP (*y, 0, MAX (0, gdk_screen_height () - req.height)); + *x = CLAMP (*x, 0, MAX (0, gdk_screen_get_width (screen) - req.width)); + *y = CLAMP (*y, 0, MAX (0, gdk_screen_get_height (screen) - req.height)); } diff --git a/gtk/gtklist.c b/gtk/gtklist.c index 56ce0321ec..318b8f12f4 100644 --- a/gtk/gtklist.c +++ b/gtk/gtklist.c @@ -476,6 +476,14 @@ gtk_list_realize (GtkWidget *widget) &widget->style->base[GTK_STATE_NORMAL]); } +static gboolean +list_has_grab (GtkList *list) +{ + return (GTK_WIDGET_HAS_GRAB (list) && + gdk_display_pointer_is_grabbed (gtk_widget_get_display (GTK_WIDGET (list)))); + +} + static void gtk_list_unmap (GtkWidget *widget) { @@ -490,7 +498,7 @@ gtk_list_unmap (GtkWidget *widget) GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED); - if (gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (list)) + if (list_has_grab (list)) { gtk_list_end_drag_selection (list); @@ -641,7 +649,7 @@ gtk_list_button_press (GtkWidget *widget, gtk_grab_add (widget); list->drag_selection = TRUE; } - else if (gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (list)) + else if (list_has_grab (list)) gtk_list_end_drag_selection (list); if (!GTK_WIDGET_HAS_FOCUS(item)) @@ -1453,7 +1461,7 @@ gtk_list_select_all (GtkList *list) if (!list->children) return; - if (gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (list)) + if (list_has_grab (list)) gtk_list_end_drag_selection (list); if (list->selection_mode == GTK_SELECTION_MULTIPLE && list->anchor >= 0) @@ -1504,7 +1512,7 @@ gtk_list_unselect_all (GtkList *list) if (!list->children) return; - if (gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (list)) + if (list_has_grab (list)) gtk_list_end_drag_selection (list); if (list->selection_mode == GTK_SELECTION_MULTIPLE && list->anchor >= 0) @@ -1548,7 +1556,7 @@ gtk_list_extend_selection (GtkList *list, g_return_if_fail (GTK_IS_LIST (list)); - if ((gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (list)) || + if (list_has_grab (list) || list->selection_mode != GTK_SELECTION_MULTIPLE) return; @@ -1599,7 +1607,7 @@ gtk_list_start_selection (GtkList *list) g_return_if_fail (GTK_IS_LIST (list)); - if (gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (list)) + if (list_has_grab (list)) return; container = GTK_CONTAINER (list); @@ -1622,8 +1630,7 @@ gtk_list_end_selection (GtkList *list) g_return_if_fail (GTK_IS_LIST (list)); - if ((gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (list)) || - list->anchor < 0) + if (list_has_grab (list) || list->anchor < 0) return; i = MIN (list->anchor, list->drag_pos); @@ -1743,8 +1750,7 @@ gtk_list_toggle_focus_row (GtkList *list) container = GTK_CONTAINER (list); - if ((gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (list)) || - !container->focus_child) + if (list_has_grab (list) || !container->focus_child) return; switch (list->selection_mode) @@ -1786,7 +1792,7 @@ gtk_list_toggle_add_mode (GtkList *list) g_return_if_fail (list != 0); g_return_if_fail (GTK_IS_LIST (list)); - if ((gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (list)) || + if (list_has_grab (list) || list->selection_mode != GTK_SELECTION_MULTIPLE) return; @@ -1812,7 +1818,7 @@ gtk_list_undo_selection (GtkList *list) g_return_if_fail (GTK_IS_LIST (list)); if (list->selection_mode != GTK_SELECTION_MULTIPLE || - (gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (list))) + list_has_grab (list)) return; if (list->anchor >= 0) @@ -2088,7 +2094,7 @@ gtk_list_scroll_horizontal (GtkList *list, g_return_if_fail (list != 0); g_return_if_fail (GTK_IS_LIST (list)); - if (gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (list)) + if (list_has_grab (list)) return; if (!(adj = @@ -2134,7 +2140,7 @@ gtk_list_scroll_vertical (GtkList *list, { g_return_if_fail (GTK_IS_LIST (list)); - if (gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (list)) + if (list_has_grab (list)) return; if (list->selection_mode == GTK_SELECTION_MULTIPLE) diff --git a/gtk/gtkmain.c b/gtk/gtkmain.c index ed63d8010f..68917b4007 100644 --- a/gtk/gtkmain.c +++ b/gtk/gtkmain.c @@ -141,13 +141,6 @@ static GMemChunk *quit_mem_chunk = NULL; static GSList *key_snoopers = NULL; -static GdkVisual *gtk_visual; /* The visual to be used in creating new - * widgets. - */ -static GdkColormap *gtk_colormap; /* The colormap to be used in creating new - * widgets. - */ - guint gtk_debug_flags = 0; /* Global GTK debug flag */ #ifdef G_ENABLE_DEBUG @@ -737,13 +730,6 @@ gtk_init_check (int *argc, } } - /* Initialize the default visual and colormap to be - * used in creating widgets. (We want to use the system - * defaults so as to be nice to the colormap). - */ - gtk_visual = gdk_visual_get_system (); - gtk_colormap = gdk_colormap_get_system (); - gtk_type_init (0); _gtk_accel_map_init (); _gtk_rc_init (); @@ -776,7 +762,8 @@ gtk_init (int *argc, char ***argv) { if (!gtk_init_check (argc, argv)) { - g_warning ("cannot open display: %s", gdk_get_display ()); + char *display_name_arg = gdk_get_display_arg_name (); + g_warning ("cannot open display: %s", display_name_arg ? display_name_arg : " "); exit (1); } } @@ -1114,6 +1101,7 @@ rewrite_event_for_grabs (GdkEvent *event) GdkWindow *grab_window; GtkWidget *event_widget, *grab_widget; gboolean owner_events; + GdkDisplay *display; switch (event->type) { @@ -1125,14 +1113,16 @@ rewrite_event_for_grabs (GdkEvent *event) case GDK_MOTION_NOTIFY: case GDK_PROXIMITY_IN: case GDK_PROXIMITY_OUT: - if (!gdk_pointer_grab_info_libgtk_only (gdk_get_default_display(), &grab_window, &owner_events) || + display = gdk_drawable_get_display (event->proximity.window); + if (!gdk_pointer_grab_info_libgtk_only (display, &grab_window, &owner_events) || !owner_events) return NULL; break; case GDK_KEY_PRESS: case GDK_KEY_RELEASE: - if (!gdk_keyboard_grab_info_libgtk_only (gdk_get_default_display(), &grab_window, &owner_events) || + display = gdk_drawable_get_display (event->key.window); + if (!gdk_keyboard_grab_info_libgtk_only (display, &grab_window, &owner_events) || !owner_events) return NULL; break; diff --git a/gtk/gtkmenu.c b/gtk/gtkmenu.c index 493381c7be..9cfea5bb22 100644 --- a/gtk/gtkmenu.c +++ b/gtk/gtkmenu.c @@ -617,7 +617,8 @@ popup_grab_on_window (GdkWindow *window, return TRUE; else { - gdk_pointer_ungrab (activate_time); + gdk_display_pointer_ungrab (gdk_drawable_get_display (window), + activate_time); return FALSE; } } @@ -639,6 +640,7 @@ gtk_menu_popup (GtkMenu *menu, GtkWidget *parent; GdkEvent *current_event; GtkMenuShell *menu_shell; + GtkMenuAttachData *attach_data; g_return_if_fail (GTK_IS_MENU (menu)); @@ -646,6 +648,21 @@ gtk_menu_popup (GtkMenu *menu, menu_shell = GTK_MENU_SHELL (menu); menu_shell->parent_menu_shell = parent_menu_shell; + + if (!g_object_get_data (G_OBJECT (menu), "gtk-menu-explicit-screen")) + { + /* The screen was not set explicitly, if the menu is + * attached to a widget, try to get screen from its + * toplevel window else go with the default + */ + attach_data = gtk_object_get_data (GTK_OBJECT (menu), attach_data_key); + if (attach_data) + { + if (!GTK_WIDGET_REALIZED (menu)) + gtk_window_set_screen (GTK_WINDOW (menu->toplevel), + gtk_widget_get_screen (attach_data->attach_widget)); + } + } /* Find the last viewable ancestor, and make an X grab on it */ @@ -832,8 +849,10 @@ gtk_menu_popdown (GtkMenu *menu) */ if (menu_shell->have_xgrab) { - gdk_pointer_ungrab (GDK_CURRENT_TIME); - gdk_keyboard_ungrab (GDK_CURRENT_TIME); + GdkDisplay *display = gtk_widget_get_display (GTK_WIDGET (menu)); + + gdk_display_pointer_ungrab (display, GDK_CURRENT_TIME); + gdk_display_keyboard_ungrab (display, GDK_CURRENT_TIME); } } @@ -1094,19 +1113,19 @@ gtk_menu_set_tearoff_state (GtkMenu *menu, if (!menu->tearoff_window) { - menu->tearoff_window = g_object_connect (gtk_widget_new (GTK_TYPE_WINDOW, - "type", GTK_WINDOW_TOPLEVEL, - NULL), - "signal::destroy", gtk_widget_destroyed, &menu->tearoff_window, - NULL); + menu->tearoff_window = gtk_widget_new (GTK_TYPE_WINDOW, + "type", GTK_WINDOW_TOPLEVEL, + "screen", gtk_widget_get_screen (menu->toplevel), + "app_paintable", TRUE, + NULL); + gtk_window_set_type_hint (GTK_WINDOW (menu->tearoff_window), GDK_WINDOW_TYPE_HINT_MENU); gtk_window_set_mnemonic_modifier (GTK_WINDOW (menu->tearoff_window), 0); - gtk_widget_set_app_paintable (menu->tearoff_window, TRUE); - gtk_signal_connect (GTK_OBJECT (menu->tearoff_window), - "event", - GTK_SIGNAL_FUNC (gtk_menu_window_event), - GTK_OBJECT (menu)); + g_signal_connect (menu->tearoff_window, "destroy", + G_CALLBACK (gtk_widget_destroyed), &menu->tearoff_window); + g_signal_connect (menu->tearoff_window, "event", + G_CALLBACK (gtk_menu_window_event), menu); gtk_menu_update_title (menu); @@ -1350,7 +1369,8 @@ menu_grab_transfer_window_get (GtkMenu *menu) attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_NOREDIR; - window = gdk_window_new (NULL, &attributes, attributes_mask); + window = gdk_window_new (gtk_widget_get_root_window (GTK_WIDGET (menu)), + &attributes, attributes_mask); gdk_window_set_user_data (window, menu); gdk_window_show (window); @@ -1736,6 +1756,7 @@ gtk_menu_key_press (GtkWidget *widget, gchar *accel = NULL; guint accel_key, accel_mods; GdkModifierType consumed_modifiers; + GdkDisplay *display; g_return_val_if_fail (GTK_IS_MENU (widget), FALSE); g_return_val_if_fail (event != NULL, FALSE); @@ -1747,10 +1768,12 @@ gtk_menu_key_press (GtkWidget *widget, if (GTK_WIDGET_CLASS (parent_class)->key_press_event (widget, event)) return TRUE; + + display = gtk_widget_get_display (widget); - g_object_get (G_OBJECT (gtk_settings_get_default ()), - "gtk-menu-bar-accel", - &accel, + g_object_get (G_OBJECT (gtk_widget_get_settings (widget)), + "gtk-menu-bar-accel", &accel, + "gtk-can-change-accels", &can_change_accels, NULL); if (accel) @@ -1791,12 +1814,8 @@ gtk_menu_key_press (GtkWidget *widget, break; } - g_object_get (G_OBJECT (gtk_settings_get_default ()), - "gtk-can-change-accels", &can_change_accels, - NULL); - /* Figure out what modifiers went into determining the key symbol */ - gdk_keymap_translate_keyboard_state (gdk_keymap_get_default (), + gdk_keymap_translate_keyboard_state (gdk_keymap_get_for_display (display), event->hardware_keycode, event->state, event->group, NULL, NULL, NULL, &consumed_modifiers); @@ -1827,7 +1846,7 @@ gtk_menu_key_press (GtkWidget *widget, * (basically, those items are accelerator-locked). */ /* g_print("item has no path or is locked, menu prefix: %s\n", menu->accel_path); */ - gdk_beep (); + gdk_display_beep (display); } else { @@ -1856,7 +1875,7 @@ gtk_menu_key_press (GtkWidget *widget, * locked already */ /* g_print("failed to change\n"); */ - gdk_beep (); + gdk_display_beep (display); } } } @@ -2310,20 +2329,23 @@ gtk_menu_position (GtkMenu *menu) GtkWidget *widget; GtkRequisition requisition; gint x, y; - gint screen_width; - gint screen_height; gint scroll_offset; gint menu_height; gboolean push_in; - + GdkScreen *screen; + GdkRectangle *monitor; + gint monitor_num; + g_return_if_fail (GTK_IS_MENU (menu)); widget = GTK_WIDGET (menu); - screen_width = gdk_screen_width (); - screen_height = gdk_screen_height (); + gdk_window_get_pointer (gtk_widget_get_root_window (widget), + &x, &y, NULL); - gdk_window_get_pointer (NULL, &x, &y, NULL); + screen = gtk_widget_get_screen (widget); + monitor_num = gdk_screen_get_monitor_at_point (screen, x, y); + monitor = gdk_screen_get_monitor_geometry (screen, monitor_num); /* We need the requisition to figure out the right place to * popup the menu. In fact, we always need to ask here, since @@ -2338,8 +2360,8 @@ gtk_menu_position (GtkMenu *menu) (* menu->position_func) (menu, &x, &y, &push_in, menu->position_func_data); else { - x = CLAMP (x - 2, 0, MAX (0, screen_width - requisition.width)); - y = CLAMP (y - 2, 0, MAX (0, screen_height - requisition.height)); + x = CLAMP (x - 2, monitor->x, MAX (monitor->x, monitor->x + monitor->width - requisition.width)); + y = CLAMP (y - 2, monitor->y, MAX (monitor->y, monitor->y + monitor->height - requisition.height)); } scroll_offset = 0; @@ -2348,27 +2370,30 @@ gtk_menu_position (GtkMenu *menu) { menu_height = GTK_WIDGET (menu)->requisition.height; - if (y + menu_height > screen_height) + if (y + menu_height > monitor->y + monitor->height) { - scroll_offset -= y + menu_height - screen_height; - y = screen_height - menu_height; + scroll_offset -= y + menu_height - (monitor->y + monitor->height); + y = (monitor->y + monitor->height) - menu_height; } - if (y < 0) + if (y < monitor->y) { scroll_offset -= y; - y = 0; + y = monitor->y; } } - if (y + requisition.height > screen_height) - requisition.height = screen_height - y; + /* FIXME: should this be done in the various position_funcs ? */ + x = CLAMP (x, monitor->x, MAX (monitor->x, monitor->x + monitor->width - requisition.width)); + + if (y + requisition.height > monitor->y + monitor->height) + requisition.height = (monitor->y + monitor->height) - y; - if (y < 0) + if (y < monitor->y) { scroll_offset -= y; requisition.height -= -y; - y = 0; + y = monitor->y; } if (scroll_offset > 0) @@ -2654,4 +2679,21 @@ gtk_menu_hide_all (GtkWidget *widget) gtk_container_foreach (GTK_CONTAINER (widget), (GtkCallback) gtk_widget_hide_all, NULL); } +/** + * gtk_menu_set_screen: + * @menu: a #GtkMenu. + * @screen: a #GtkScreen. + * + * Sets the #GtkScreen on which the GtkMenu will be displayed. + * This function can only be called before @menu is realized. + **/ +void +gtk_menu_set_screen (GtkMenu *menu, + GdkScreen *screen) +{ + g_return_if_fail (GTK_IS_MENU (menu)); + gtk_window_set_screen (GTK_WINDOW (menu->toplevel), + screen); + g_object_set_data (G_OBJECT (menu), "gtk-menu-explicit-screen", screen); +} diff --git a/gtk/gtkmenu.h b/gtk/gtkmenu.h index 26fed83194..5c1d47d085 100644 --- a/gtk/gtkmenu.h +++ b/gtk/gtkmenu.h @@ -186,6 +186,8 @@ void gtk_menu_reorder_child (GtkMenu *menu, GtkWidget *child, gint position); +void gtk_menu_set_screen (GtkMenu *menu, + GdkScreen *screen); #ifndef GTK_DISABLE_DEPRECATED #define gtk_menu_append(menu,child) gtk_menu_shell_append ((GtkMenuShell *)(menu),(child)) #define gtk_menu_prepend(menu,child) gtk_menu_shell_prepend ((GtkMenuShell *)(menu),(child)) diff --git a/gtk/gtkmenuitem.c b/gtk/gtkmenuitem.c index dfb753169f..ec34f441bf 100644 --- a/gtk/gtkmenuitem.c +++ b/gtk/gtkmenuitem.c @@ -878,6 +878,7 @@ gtk_menu_item_position_menu (GtkMenu *menu, GtkMenuItem *menu_item; GtkWidget *widget; GtkWidget *parent_menu_item; + GdkScreen *screen; gint screen_width; gint screen_height; gint twidth, theight; @@ -893,8 +894,9 @@ gtk_menu_item_position_menu (GtkMenu *menu, twidth = GTK_WIDGET (menu)->requisition.width; theight = GTK_WIDGET (menu)->requisition.height; - screen_width = gdk_screen_width (); - screen_height = gdk_screen_height (); + screen = gtk_widget_get_screen (widget); + screen_width = gdk_screen_get_width (screen); + screen_height = gdk_screen_get_height (screen); if (!gdk_window_get_origin (widget->window, &tx, &ty)) { diff --git a/gtk/gtkmenushell.c b/gtk/gtkmenushell.c index f90f56fbf7..02da9df78a 100644 --- a/gtk/gtkmenushell.c +++ b/gtk/gtkmenushell.c @@ -802,9 +802,11 @@ gtk_real_menu_shell_deactivate (GtkMenuShell *menu_shell) } if (menu_shell->have_xgrab) { + GdkDisplay *display = gtk_widget_get_display (GTK_WIDGET (menu_shell)); + menu_shell->have_xgrab = FALSE; - gdk_pointer_ungrab (GDK_CURRENT_TIME); - gdk_keyboard_ungrab (GDK_CURRENT_TIME); + gdk_display_pointer_ungrab (display, GDK_CURRENT_TIME); + gdk_display_keyboard_ungrab (display, GDK_CURRENT_TIME); } } } @@ -930,7 +932,7 @@ gtk_menu_shell_activate_item (GtkMenuShell *menu_shell, /* flush the x-queue, so any grabs are removed and * the menu is actually taken down */ - gdk_flush (); + gdk_display_sync (gtk_widget_get_display (menu_item)); } gtk_widget_activate (menu_item); diff --git a/gtk/gtknotebook.c b/gtk/gtknotebook.c index 3f933700fa..9e2dab5489 100644 --- a/gtk/gtknotebook.c +++ b/gtk/gtknotebook.c @@ -647,7 +647,7 @@ gtk_notebook_change_current_page (GtkNotebook *notebook, if (current) gtk_notebook_switch_page (notebook, current->data, -1); else - gdk_beep (); + gdk_display_beep (gtk_widget_get_display (GTK_WIDGET (notebook))); } static GtkDirectionType @@ -1964,7 +1964,7 @@ focus_tabs_move (GtkNotebook *notebook, if (new_page) gtk_notebook_switch_focus_tab (notebook, new_page); else - gdk_beep (); + gdk_display_beep (gtk_widget_get_display (GTK_WIDGET (notebook))); return TRUE; } diff --git a/gtk/gtkoldeditable.c b/gtk/gtkoldeditable.c index ee65d32010..3016fd9c55 100644 --- a/gtk/gtkoldeditable.c +++ b/gtk/gtkoldeditable.c @@ -721,6 +721,9 @@ gtk_old_editable_claim_selection (GtkOldEditable *old_editable, gboolean claim, guint32 time) { + GtkWidget *widget = GTK_WIDGET (old_editable); + GdkDisplay *display = gtk_widget_get_display (widget); + g_return_if_fail (GTK_IS_OLD_EDITABLE (old_editable)); g_return_if_fail (GTK_WIDGET_REALIZED (old_editable)); @@ -728,13 +731,16 @@ gtk_old_editable_claim_selection (GtkOldEditable *old_editable, if (claim) { - if (gtk_selection_owner_set (GTK_WIDGET (old_editable), GDK_SELECTION_PRIMARY, time)) + if (gtk_selection_owner_set_for_display (display, widget, + GDK_SELECTION_PRIMARY, time)) old_editable->has_selection = TRUE; } else { - if (gdk_selection_owner_get (GDK_SELECTION_PRIMARY) == GTK_WIDGET (old_editable)->window) - gtk_selection_owner_set (NULL, GDK_SELECTION_PRIMARY, time); + if (gdk_selection_owner_get_for_display (display, GDK_SELECTION_PRIMARY) == widget->window) + gtk_selection_owner_set_for_display (display, + NULL, + GDK_SELECTION_PRIMARY, time); } } @@ -801,7 +807,10 @@ gtk_old_editable_real_copy_clipboard (GtkOldEditable *old_editable) if (text) { - gtk_clipboard_set_text (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD), text, -1); + GtkClipboard *clipboard = gtk_widget_get_clipboard (GTK_WIDGET (old_editable), + GDK_SELECTION_CLIPBOARD); + + gtk_clipboard_set_text (clipboard, text, -1); g_free (text); } } @@ -810,9 +819,11 @@ gtk_old_editable_real_copy_clipboard (GtkOldEditable *old_editable) static void gtk_old_editable_real_paste_clipboard (GtkOldEditable *old_editable) { + GtkClipboard *clipboard = gtk_widget_get_clipboard (GTK_WIDGET (old_editable), + GDK_SELECTION_CLIPBOARD); + g_object_ref (G_OBJECT (old_editable)); - gtk_clipboard_request_text (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD), - old_editable_text_received_cb, old_editable); + gtk_clipboard_request_text (clipboard, old_editable_text_received_cb, old_editable); } /** diff --git a/gtk/gtkoptionmenu.c b/gtk/gtkoptionmenu.c index 5b10f8bccf..2f45a59507 100644 --- a/gtk/gtkoptionmenu.c +++ b/gtk/gtkoptionmenu.c @@ -927,7 +927,7 @@ gtk_option_menu_position (GtkMenu *menu, children = children->next; } - screen_width = gdk_screen_width (); + screen_width = gdk_screen_get_width (gtk_widget_get_screen (widget)); if (menu_xpos < 0) menu_xpos = 0; diff --git a/gtk/gtkpaned.c b/gtk/gtkpaned.c index bf15fd2f01..53051f3d34 100644 --- a/gtk/gtkpaned.c +++ b/gtk/gtkpaned.c @@ -459,7 +459,8 @@ gtk_paned_realize (GtkWidget *widget) attributes.y = paned->handle_pos.y; attributes.width = paned->handle_pos.width; attributes.height = paned->handle_pos.height; - attributes.cursor = gdk_cursor_new (paned->cursor_type); + attributes.cursor = gdk_cursor_new_for_screen (gtk_widget_get_screen (widget), + paned->cursor_type); attributes.event_mask = gtk_widget_get_events (widget); attributes.event_mask |= (GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | @@ -698,8 +699,8 @@ gtk_paned_button_release (GtkWidget *widget, paned->in_drag = FALSE; paned->drag_pos = -1; paned->position_set = TRUE; - gdk_pointer_ungrab (event->time); - + gdk_display_pointer_ungrab (gtk_widget_get_display (widget), + event->time); return TRUE; } diff --git a/gtk/gtkplug.c b/gtk/gtkplug.c index 7b6d39172f..f70cbc3e7f 100644 --- a/gtk/gtkplug.c +++ b/gtk/gtkplug.c @@ -271,7 +271,9 @@ _gtk_plug_remove_from_socket (GtkPlug *plug, widget_was_visible = GTK_WIDGET_VISIBLE (plug); gdk_window_hide (widget->window); - gdk_window_reparent (widget->window, GDK_ROOT_PARENT (), 0, 0); + gdk_window_reparent (widget->window, + gtk_widget_get_root_window (widget), + 0, 0); GTK_PRIVATE_SET_FLAG (plug, GTK_IN_REPARENT); gtk_widget_unparent (GTK_WIDGET (plug)); @@ -306,21 +308,49 @@ _gtk_plug_remove_from_socket (GtkPlug *plug, g_object_unref (socket); } +/** + * gtk_plug_construct: + * @display: the #GdkDisplay associated with @socket_id's #GtkSocket. + * @plug: a #GtkPlug. + * @socket_id: the XID of the socket's window. + * + * Finish the Initialization of @plug for a given #GtkSocket identified by + * @socket_id. This function will generally only be used by classes deriving from #GtkPlug. + **/ void gtk_plug_construct (GtkPlug *plug, GdkNativeWindow socket_id) { + gtk_plug_construct_for_display (gdk_get_default_display (), plug, socket_id); +} + +/** + * gtk_plug_construct_for_display: + * @display: the #GdkDisplay associated with @socket_id's + * #GtkSocket. + * @plug: a #GtkPlug. + * @socket_id: the XID of the socket's window. + * + * Finish the Initialization of @plug for a given #GtkSocket identified by + * @socket_id which is currently displayed on @display. + * This function will generally only be used by classes deriving from #GtkPlug. + **/ +void +gtk_plug_construct_for_display (GdkDisplay *display, + GtkPlug *plug, + GdkNativeWindow socket_id) +{ if (socket_id) { gpointer user_data = NULL; - plug->socket_window = gdk_window_lookup (socket_id); - + plug->socket_window = gdk_window_lookup_for_display (display, socket_id); + if (plug->socket_window) gdk_window_get_user_data (plug->socket_window, &user_data); else - plug->socket_window = gdk_window_foreign_new (socket_id); - + plug->socket_window = gdk_window_foreign_new_for_display (display, socket_id); + if (user_data) { if (GTK_IS_SOCKET (user_data)) @@ -337,13 +367,39 @@ gtk_plug_construct (GtkPlug *plug, } } +/** + * gtk_plug_new: + * @socket_id: the window ID of the socket, or 0. + * + * Creates a new plug widget inside the #GtkSocket identified + * by @socket_id. If @socket_id is 0, the plug is left "unplugged" and + * can later be plugged into a #GtkSocket by gtk_socket_add_id(). + * + * Return value: the new #GtkPlug widget. + **/ GtkWidget* gtk_plug_new (GdkNativeWindow socket_id) { + return gtk_plug_new_for_display (gdk_get_default_display (), socket_id); +} + +/** + * gtk_plug_new_for_display: + * @display : the #GdkDisplay on which @socket_id is displayed + * @socket_id: the XID of the socket's window. + * + * Create a new plug widget inside the GtkSocket identified by socket_id. + * + * Return value: the new #GtkPlug widget. + */ +GtkWidget* +gtk_plug_new_for_display (GdkDisplay *display, + GdkNativeWindow socket_id) +{ GtkPlug *plug; plug = GTK_PLUG (gtk_type_new (GTK_TYPE_PLUG)); - gtk_plug_construct (plug, socket_id); + gtk_plug_construct_for_display (display, plug, socket_id); return GTK_WIDGET (plug); } @@ -455,16 +511,22 @@ gtk_plug_realize (GtkWidget *widget) attributes.window_type = GDK_WINDOW_TOPLEVEL; gdk_error_trap_push (); - widget->window = gdk_window_new (plug->socket_window, - &attributes, attributes_mask); - gdk_flush (); + if (plug->socket_window) + widget->window = gdk_window_new (plug->socket_window, + &attributes, attributes_mask); + else /* If it's a passive plug, we use the root window */ + widget->window = gdk_window_new (gtk_widget_get_root_window (widget), + &attributes, attributes_mask); + + gdk_display_sync (gtk_widget_get_display (widget)); if (gdk_error_trap_pop ()) /* Uh-oh */ { gdk_error_trap_push (); gdk_window_destroy (widget->window); gdk_flush (); gdk_error_trap_pop (); - widget->window = gdk_window_new (NULL, &attributes, attributes_mask); + widget->window = gdk_window_new (gtk_widget_get_root_window (widget), + &attributes, attributes_mask); } gdk_window_add_filter (widget->window, gtk_plug_filter_func, widget); @@ -475,7 +537,8 @@ gtk_plug_realize (GtkWidget *widget) xembed_set_info (widget->window, 0); } else - widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask); + widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), + &attributes, attributes_mask); gdk_window_set_user_data (widget->window, window); @@ -608,7 +671,7 @@ gtk_plug_set_focus (GtkWindow *window, XEvent xevent; xevent.xfocus.type = FocusIn; - xevent.xfocus.display = GDK_WINDOW_XDISPLAY (GTK_WIDGET(plug)->window); + xevent.xfocus.display = GDK_WINDOW_XDISPLAY (plug->socket_window); xevent.xfocus.window = GDK_WINDOW_XWINDOW (plug->socket_window); xevent.xfocus.mode = EMBEDDED_APP_WANTS_FOCUS; xevent.xfocus.detail = FALSE; /* Don't force */ @@ -617,7 +680,7 @@ gtk_plug_set_focus (GtkWindow *window, XSendEvent (GDK_DISPLAY (), GDK_WINDOW_XWINDOW (plug->socket_window), False, NoEventMask, &xevent); - gdk_flush (); + gdk_display_sync (gdk_drawable_get_display (plug->socket_window)); gdk_error_trap_pop (); #endif @@ -790,10 +853,10 @@ gtk_plug_focus (GtkWidget *widget, gtk_window_set_focus (GTK_WINDOW (widget), NULL); gdk_error_trap_push (); - XSetInputFocus (GDK_DISPLAY (), + XSetInputFocus (GDK_WINDOW_XDISPLAY (plug->socket_window), GDK_WINDOW_XWINDOW (plug->socket_window), RevertToParent, event->time); - gdk_flush (); + gdk_display_sync (gdk_drawable_get_display (plug->socket_window)); gdk_error_trap_pop (); gtk_plug_forward_key_press (plug, event); @@ -833,11 +896,12 @@ send_xembed_message (GtkPlug *plug, { if (plug->socket_window) { + GdkDisplay *display = gdk_drawable_get_display (plug->socket_window); XEvent xevent; xevent.xclient.window = GDK_WINDOW_XWINDOW (plug->socket_window); xevent.xclient.type = ClientMessage; - xevent.xclient.message_type = gdk_x11_get_xatom_by_name ("_XEMBED"); + xevent.xclient.message_type = gdk_x11_get_xatom_by_name_for_display (display, "_XEMBED"); xevent.xclient.format = 32; xevent.xclient.data.l[0] = time; xevent.xclient.data.l[1] = message; @@ -846,10 +910,10 @@ send_xembed_message (GtkPlug *plug, xevent.xclient.data.l[4] = data2; gdk_error_trap_push (); - XSendEvent (GDK_DISPLAY (), + XSendEvent (GDK_WINDOW_XDISPLAY(plug->socket_window), GDK_WINDOW_XWINDOW (plug->socket_window), False, NoEventMask, &xevent); - gdk_flush (); + gdk_display_sync (display); gdk_error_trap_pop (); } } @@ -882,6 +946,8 @@ handle_modality_on (GtkPlug *plug) if (!plug->modality_window) { plug->modality_window = gtk_window_new (GTK_WINDOW_POPUP); + gtk_window_set_screen (GTK_WINDOW (plug->modality_window), + gtk_widget_get_screen (GTK_WIDGET (plug))); gtk_widget_realize (plug->modality_window); gtk_window_group_add_window (plug->modality_group, GTK_WINDOW (plug->modality_window)); gtk_grab_add (plug->modality_window); @@ -899,19 +965,19 @@ handle_modality_off (GtkPlug *plug) } static void -xembed_set_info (GdkWindow *gdk_window, +xembed_set_info (GdkWindow *window, unsigned long flags) { - Display *display = GDK_WINDOW_XDISPLAY (gdk_window); - Window window = GDK_WINDOW_XWINDOW (gdk_window); + GdkDisplay *display = gdk_drawable_get_display (window); unsigned long buffer[2]; - - Atom xembed_info_atom = gdk_x11_get_xatom_by_name ("_XEMBED_INFO"); + + Atom xembed_info_atom = gdk_x11_get_xatom_by_name_for_display (display, "_XEMBED_INFO"); buffer[1] = 0; /* Protocol version */ buffer[1] = flags; - XChangeProperty (display, window, + XChangeProperty (GDK_DISPLAY_XDISPLAY (display), + GDK_WINDOW_XWINDOW (window), xembed_info_atom, xembed_info_atom, 32, PropModeReplace, (unsigned char *)buffer, 2); @@ -995,6 +1061,8 @@ handle_xembed_message (GtkPlug *plug, static GdkFilterReturn gtk_plug_filter_func (GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data) { + GdkScreen *screen = gdk_drawable_get_screen (event->any.window); + GdkDisplay *display = gdk_screen_get_display (screen); GtkPlug *plug = GTK_PLUG (data); XEvent *xevent = (XEvent *)gdk_xevent; @@ -1005,7 +1073,7 @@ gtk_plug_filter_func (GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data) switch (xevent->type) { case ClientMessage: - if (xevent->xclient.message_type == gdk_x11_get_xatom_by_name ("_XEMBED")) + if (xevent->xclient.message_type == gdk_x11_get_xatom_by_name_for_display (display, "_XEMBED")) { handle_xembed_message (plug, xevent->xclient.data.l[1], @@ -1017,7 +1085,7 @@ gtk_plug_filter_func (GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data) return GDK_FILTER_REMOVE; } - else if (xevent->xclient.message_type == gdk_x11_get_xatom_by_name ("WM_DELETE_WINDOW")) + else if (xevent->xclient.message_type == gdk_x11_get_xatom_by_name_for_display (display, "WM_DELETE_WINDOW")) { /* We filter these out because we take being reparented back to the * root window as the reliable end of the embedding protocol @@ -1061,7 +1129,7 @@ gtk_plug_filter_func (GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data) * be invisible to the app. */ - if (xre->parent == GDK_ROOT_WINDOW()) + if (xre->parent == GDK_WINDOW_XWINDOW (gdk_screen_get_root_window (screen))) { GdkEvent event; @@ -1079,11 +1147,11 @@ gtk_plug_filter_func (GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data) break; } - if (xre->parent != GDK_ROOT_WINDOW ()) + if (xre->parent != GDK_WINDOW_XWINDOW (gdk_screen_get_root_window (screen))) { /* Start of embedding protocol */ - plug->socket_window = gdk_window_lookup (xre->parent); + plug->socket_window = gdk_window_lookup_for_display (display, xre->parent); if (plug->socket_window) { gpointer user_data = NULL; @@ -1100,7 +1168,7 @@ gtk_plug_filter_func (GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data) } else { - plug->socket_window = gdk_window_foreign_new (xre->parent); + plug->socket_window = gdk_window_foreign_new_for_display (display, xre->parent); if (!plug->socket_window) /* Already gone */ break; } diff --git a/gtk/gtkplug.h b/gtk/gtkplug.h index 17e4261698..38a19f6bfe 100644 --- a/gtk/gtkplug.h +++ b/gtk/gtkplug.h @@ -76,9 +76,19 @@ struct _GtkPlugClass GtkType gtk_plug_get_type (void) G_GNUC_CONST; -void gtk_plug_construct (GtkPlug *plug, GdkNativeWindow socket_id); -GtkWidget* gtk_plug_new (GdkNativeWindow socket_id); +#ifndef GDK_MULTIHEAD_SAFE +void gtk_plug_construct (GtkPlug *plug, + GdkNativeWindow socket_id); +GtkWidget* gtk_plug_new (GdkNativeWindow socket_id); +#endif + +void gtk_plug_construct_for_display (GdkDisplay *display, + GtkPlug *plug, + GdkNativeWindow socket_id); +GtkWidget* gtk_plug_new_for_display (GdkDisplay *display, + GdkNativeWindow socket_id); + GdkNativeWindow gtk_plug_get_id (GtkPlug *plug); void _gtk_plug_add_to_socket (GtkPlug *plug, diff --git a/gtk/gtkpreview.c b/gtk/gtkpreview.c index a429d6ad66..ff6b332d89 100644 --- a/gtk/gtkpreview.c +++ b/gtk/gtkpreview.c @@ -416,13 +416,13 @@ gtk_preview_set_dither (GtkPreview *preview, GdkVisual* gtk_preview_get_visual (void) { - return gdk_rgb_get_visual (); + return gdk_screen_get_rgb_visual (gdk_get_default_screen ()); } GdkColormap* gtk_preview_get_cmap (void) { - return gdk_rgb_get_colormap (); + return gdk_screen_get_rgb_colormap (gdk_get_default_screen ()); } GtkPreviewInfo* diff --git a/gtk/gtkselection.c b/gtk/gtkselection.c index 1974fb1c76..71a3c6b36a 100644 --- a/gtk/gtkselection.c +++ b/gtk/gtkselection.c @@ -84,9 +84,10 @@ typedef struct _GtkRetrievalInfo GtkRetrievalInfo; struct _GtkSelectionInfo { - GdkAtom selection; - GtkWidget *widget; /* widget that owns selection */ - guint32 time; /* time used to acquire selection */ + GdkAtom selection; + GtkWidget *widget; /* widget that owns selection */ + guint32 time; /* time used to acquire selection */ + GdkDisplay *display; /* needed in gtk_selection_remove_all */ }; struct _GtkIncrConversion @@ -292,29 +293,32 @@ gtk_target_list_find (GtkTargetList *list, return FALSE; } - -/************************************************************* - * gtk_selection_owner_set: - * Claim ownership of a selection. - * arguments: - * widget: new selection owner - * selection: which selection - * time: time (use GDK_CURRENT_TIME only if necessary) +/** + * gtk_selection_owner_set_for_display: + * @display: the #Gdkdisplay where the selection is set + * @widget: new selection owner (a #GdkWidget), or %NULL. + * @selection: an interned atom representing the selection to claim. + * @time: timestamp with which to claim the selection * - * results: - *************************************************************/ - + * Claim ownership of a given selection for a particular widget, or, + * if @widget is %NULL, release ownership of the selection. + * + * Return value: TRUE if the operation succeeded + */ gboolean -gtk_selection_owner_set (GtkWidget *widget, - GdkAtom selection, - guint32 time) +gtk_selection_owner_set_for_display (GdkDisplay *display, + GtkWidget *widget, + GdkAtom selection, + guint32 time) { GList *tmp_list; GtkWidget *old_owner; GtkSelectionInfo *selection_info = NULL; GdkWindow *window; + g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE); g_return_val_if_fail (widget == NULL || GTK_WIDGET_REALIZED (widget), FALSE); + g_return_val_if_fail (widget == NULL || gtk_widget_get_display (widget) == display, FALSE); if (widget == NULL) window = NULL; @@ -333,7 +337,7 @@ gtk_selection_owner_set (GtkWidget *widget, tmp_list = tmp_list->next; } - if (gdk_selection_owner_set (window, selection, time, TRUE)) + if (gdk_selection_owner_set_for_display (display, window, selection, time, TRUE)) { old_owner = NULL; @@ -356,7 +360,8 @@ gtk_selection_owner_set (GtkWidget *widget, selection_info->selection = selection; selection_info->widget = widget; selection_info->time = time; - current_selections = g_list_prepend (current_selections, + selection_info->display = display; + current_selections = g_list_prepend (current_selections, selection_info); } else @@ -364,6 +369,7 @@ gtk_selection_owner_set (GtkWidget *widget, old_owner = selection_info->widget; selection_info->widget = widget; selection_info->time = time; + selection_info->display = display; } } /* If another widget in the application lost the selection, @@ -386,6 +392,30 @@ gtk_selection_owner_set (GtkWidget *widget, return FALSE; } +/** + * gtk_selection_owner_set: + * @widget: a #GtkWidget, or %NULL. + * @selection: an interned atom representing the selection to claim + * @time: timestamp with which to claim the selection + * + * Claims ownership of a given selection for a particular widget, + * or, if @widget is %NULL, release ownership of the selection. + * + * Return value: %TRUE if the operation succeeded + **/ +gboolean +gtk_selection_owner_set (GtkWidget *widget, + GdkAtom selection, + guint32 time) +{ + g_return_val_if_fail (widget == NULL || GTK_WIDGET_REALIZED (widget), FALSE); + + return gtk_selection_owner_set_for_display (gdk_get_default_display(), + widget, + selection, + time); +} + /************************************************************* * gtk_selection_add_target * Add specified target to list of supported targets @@ -570,10 +600,11 @@ gtk_selection_remove_all (GtkWidget *widget) if (selection_info->widget == widget) { - gdk_selection_owner_set (NULL, - selection_info->selection, - GDK_CURRENT_TIME, FALSE); - current_selections = g_list_remove_link (current_selections, + gdk_selection_owner_set_for_display (selection_info->display, + NULL, + selection_info->selection, + GDK_CURRENT_TIME, FALSE); + current_selections = g_list_remove_link (current_selections, tmp_list); g_list_free (tmp_list); g_free (selection_info); @@ -613,6 +644,7 @@ gtk_selection_convert (GtkWidget *widget, GtkRetrievalInfo *info; GList *tmp_list; GdkWindow *owner_window; + GdkDisplay *display; g_return_val_if_fail (widget != NULL, FALSE); @@ -647,8 +679,9 @@ gtk_selection_convert (GtkWidget *widget, /* Check if this process has current owner. If so, call handler procedure directly to avoid deadlocks with INCR. */ - - owner_window = gdk_selection_owner_get (selection); + + display = gtk_widget_get_display (widget); + owner_window = gdk_selection_owner_get_for_display (display, selection); if (owner_window != NULL) { @@ -659,6 +692,7 @@ gtk_selection_convert (GtkWidget *widget, selection_data.target = target; selection_data.data = NULL; selection_data.length = -1; + selection_data.display = display; gdk_window_get_user_data (owner_window, (gpointer *)&owner_widget); @@ -810,7 +844,8 @@ gtk_selection_data_set_text (GtkSelectionData *selection_data, gint new_length; tmp = g_strndup (str, len); - if (gdk_utf8_to_compound_text (tmp, &encoding, &format, &text, &new_length)) + if (gdk_utf8_to_compound_text_for_display (selection_data->display, tmp, + &encoding, &format, &text, &new_length)) { gtk_selection_data_set (selection_data, encoding, format, text, new_length); gdk_free_compound_text (text); @@ -849,11 +884,12 @@ gtk_selection_data_get_text (GtkSelectionData *selection_data) { gchar **list; gint i; - gint count = gdk_text_property_to_utf8_list (selection_data->type, - selection_data->format, - selection_data->data, - selection_data->length, - &list); + gint count = gdk_text_property_to_utf8_list_for_display (selection_data->display, + selection_data->type, + selection_data->format, + selection_data->data, + selection_data->length, + &list); if (count > 0) result = list[0]; @@ -1049,9 +1085,12 @@ gtk_selection_request (GtkWidget *widget, info->num_incrs = 0; /* Create GdkWindow structure for the requestor */ - info->requestor = gdk_window_lookup (event->requestor); + + info->requestor = gdk_window_lookup_for_display (gtk_widget_get_display (widget), + event->requestor); if (!info->requestor) - info->requestor = gdk_window_foreign_new (event->requestor); + info->requestor = gdk_window_foreign_new_for_display (gtk_widget_get_display (widget), + event->requestor); /* Determine conversions we need to perform */ @@ -1068,8 +1107,12 @@ gtk_selection_request (GtkWidget *widget, 0, GTK_SELECTION_MAX_SIZE, FALSE, &type, &format, &length, &mult_atoms)) { - gdk_selection_send_notify (event->requestor, event->selection, - event->target, GDK_NONE, event->time); + gdk_selection_send_notify_for_display (gtk_widget_get_display (widget), + event->requestor, + event->selection, + event->target, + GDK_NONE, + event->time); g_free (mult_atoms); g_free (info); return TRUE; @@ -1105,6 +1148,7 @@ gtk_selection_request (GtkWidget *widget, data.target = info->conversions[i].target; data.data = NULL; data.length = -1; + data.display = gtk_widget_get_display (widget); #ifdef DEBUG_SELECTION g_message ("Selection %ld, target %ld (%s) requested by 0x%x (property = %ld)", @@ -1190,13 +1234,21 @@ gtk_selection_request (GtkWidget *widget, info->conversions[0].property == GDK_NONE) { /* Reject the entire conversion */ - gdk_selection_send_notify (event->requestor, event->selection, - event->target, GDK_NONE, event->time); + gdk_selection_send_notify_for_display (gtk_widget_get_display (widget), + event->requestor, + event->selection, + event->target, + GDK_NONE, + event->time); } else { - gdk_selection_send_notify (event->requestor, event->selection, - event->target, event->property, event->time); + gdk_selection_send_notify_for_display (gtk_widget_get_display (widget), + event->requestor, + event->selection, + event->target, + event->property, + event->time); } if (info->num_incrs == 0) @@ -1659,6 +1711,7 @@ gtk_selection_retrieval_report (GtkRetrievalInfo *info, data.length = length; data.data = buffer; + data.display = gtk_widget_get_display (info->widget); gtk_signal_emit_by_name (GTK_OBJECT(info->widget), "selection_received", diff --git a/gtk/gtkselection.h b/gtk/gtkselection.h index 3e25d0d193..4e2d12b907 100644 --- a/gtk/gtkselection.h +++ b/gtk/gtkselection.h @@ -54,12 +54,13 @@ typedef struct _GtkTargetEntry GtkTargetEntry; struct _GtkSelectionData { - GdkAtom selection; - GdkAtom target; - GdkAtom type; - gint format; - guchar *data; - gint length; + GdkAtom selection; + GdkAtom target; + GdkAtom type; + gint format; + guchar *data; + gint length; + GdkDisplay *display; }; struct _GtkTargetEntry { @@ -105,9 +106,14 @@ gboolean gtk_target_list_find (GtkTargetList *list, /* Public interface */ -gboolean gtk_selection_owner_set (GtkWidget *widget, - GdkAtom selection, - guint32 time); +gboolean gtk_selection_owner_set (GtkWidget *widget, + GdkAtom selection, + guint32 time); +gboolean gtk_selection_owner_set_for_display (GdkDisplay *display, + GtkWidget *widget, + GdkAtom selection, + guint32 time); + void gtk_selection_add_target (GtkWidget *widget, GdkAtom selection, GdkAtom target, diff --git a/gtk/gtksettings.c b/gtk/gtksettings.c index f5f02eea0c..50528d02ea 100644 --- a/gtk/gtksettings.c +++ b/gtk/gtksettings.c @@ -39,9 +39,6 @@ enum { static void gtk_settings_init (GtkSettings *settings); static void gtk_settings_class_init (GtkSettingsClass *class); static void gtk_settings_finalize (GObject *object); -static GObject* gtk_settings_constructor (GType type, - guint n_construct_properties, - GObjectConstructParam *construct_properties); static void gtk_settings_get_property (GObject *object, guint property_id, GValue *value, @@ -59,7 +56,6 @@ static guint settings_install_property_parser (GtkSettingsClass *class, /* --- variables --- */ static gpointer parent_class = NULL; -static GtkSettings *the_singleton = NULL; static GQuark quark_property_parser = 0; static GSList *object_list = NULL; static guint class_n_properties = 0; @@ -135,7 +131,6 @@ gtk_settings_class_init (GtkSettingsClass *class) parent_class = g_type_class_peek_parent (class); - gobject_class->constructor = gtk_settings_constructor; gobject_class->finalize = gtk_settings_finalize; gobject_class->get_property = gtk_settings_get_property; gobject_class->set_property = gtk_settings_set_property; @@ -238,34 +233,45 @@ gtk_settings_finalize (GObject *object) G_OBJECT_CLASS (parent_class)->finalize (object); } -static GObject* -gtk_settings_constructor (GType type, - guint n_construct_properties, - GObjectConstructParam *construct_properties) +/** + * gtk_settings_get_for_screen: + * @screen : a #GdkScreen. + * + * Gets the #GtkSettings object for @screen, creating it if necessary. + * + * Return value: a #GtkSettings object. + */ +GtkSettings* +gtk_settings_get_for_screen (GdkScreen *screen) { - GObject *object; - - /* currently we're a singleton, that might change with multiple display support though */ - if (!the_singleton) + GtkSettings *settings; + + g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL); + + settings = g_object_get_data (G_OBJECT (screen), "gtk-settings"); + if (!settings) { - object = G_OBJECT_CLASS (parent_class)->constructor (type, - n_construct_properties, - construct_properties); - the_singleton = GTK_SETTINGS (g_object_ref (object)); + settings = g_object_new (GTK_TYPE_SETTINGS, NULL); + settings->screen = screen; + g_object_set_data (G_OBJECT (screen), "gtk-settings", settings); + gtk_rc_reparse_all_for_settings (settings, TRUE); } - else - object = g_object_ref (G_OBJECT (the_singleton)); - - return object; + + return settings; } +/** + * gtk_settings_get_default: + * + * Gets the #GtkSettings object for the default GDK screen, creating + * it if necessary. See gtk_settings_get_for_screen(). + * + * Return value: a #GtkSettings object + **/ GtkSettings* gtk_settings_get_default (void) { - if (!the_singleton) - g_object_new (GTK_TYPE_SETTINGS, NULL); - - return the_singleton; /* we don't add a reference count here, we'd be settings_ref_global() if we did */ + return gtk_settings_get_for_screen (gdk_get_default_screen ()); } static void @@ -298,7 +304,7 @@ gtk_settings_get_property (GObject *object, g_value_type_transformable (G_TYPE_STRING, G_VALUE_TYPE (value)) || g_value_type_transformable (GDK_TYPE_COLOR, G_VALUE_TYPE (value))) { - if (gdk_setting_get (pspec->name, value)) + if (gdk_screen_get_setting (settings->screen, pspec->name, value)) g_param_value_validate (pspec, value); else g_value_copy (settings->property_values + property_id - 1, value); @@ -311,7 +317,7 @@ gtk_settings_get_property (GObject *object, g_value_init (&val, G_TYPE_STRING); - if (!gdk_setting_get (pspec->name, &val)) + if (!gdk_screen_get_setting (settings->screen, pspec->name, &val)) { g_value_copy (settings->property_values + property_id - 1, value); } @@ -351,15 +357,12 @@ static void gtk_settings_notify (GObject *object, GParamSpec *pspec) { + GtkSettings *settings = GTK_SETTINGS (object); guint property_id = pspec->param_id; gint double_click_time; - -#if 1 - GValue tmp_value = { 0, }; - gchar *contents; - g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec)); - g_object_get_property (object, pspec->name, &tmp_value); - contents = g_strdup_value_contents (&tmp_value); + + if (settings->screen == NULL) /* initialization */ + return; switch (property_id) { @@ -368,10 +371,6 @@ gtk_settings_notify (GObject *object, gdk_set_double_click_time (double_click_time); break; } - - g_free (contents); - g_value_unset (&tmp_value); -#endif } gboolean @@ -944,7 +943,7 @@ gtk_rc_property_parse_border (const GParamSpec *pspec, void _gtk_settings_handle_event (GdkEventSetting *event) { - GtkSettings *settings = gtk_settings_get_default (); + GtkSettings *settings = gtk_settings_get_for_screen (gdk_drawable_get_screen (event->window)); if (g_object_class_find_property (G_OBJECT_GET_CLASS (settings), event->name)) g_object_notify (G_OBJECT (settings), event->name); diff --git a/gtk/gtksettings.h b/gtk/gtksettings.h index 463c5d226f..4e0864d247 100644 --- a/gtk/gtksettings.h +++ b/gtk/gtksettings.h @@ -48,6 +48,7 @@ struct _GtkSettings GValue *property_values; GtkRcContext *rc_context; + GdkScreen *screen; }; struct _GtkSettingsClass { @@ -70,7 +71,11 @@ struct _GtkSettingsValue /* --- functions --- */ GType gtk_settings_get_type (void); +#ifndef GDK_MULTIHEAD_SAFE GtkSettings* gtk_settings_get_default (void); +#endif +GtkSettings* gtk_settings_get_for_screen (GdkScreen *screen); + void gtk_settings_install_property (GParamSpec *pspec); void gtk_settings_install_property_parser (GParamSpec *pspec, GtkRcPropertyParser parser); diff --git a/gtk/gtksocket.c b/gtk/gtksocket.c index a6d6e1e735..c0677132ed 100644 --- a/gtk/gtksocket.c +++ b/gtk/gtksocket.c @@ -335,12 +335,12 @@ gtk_socket_realize (GtkWidget *widget) widget->style = gtk_style_attach (widget->style, widget->window); gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL); - XGetWindowAttributes (GDK_DISPLAY (), + XGetWindowAttributes (GDK_WINDOW_XDISPLAY (widget->window), GDK_WINDOW_XWINDOW (widget->window), &xattrs); - XSelectInput (GDK_DISPLAY (), - GDK_WINDOW_XWINDOW(widget->window), + XSelectInput (GDK_WINDOW_XDISPLAY (widget->window), + GDK_WINDOW_XWINDOW (widget->window), xattrs.your_event_mask | SubstructureNotifyMask | SubstructureRedirectMask); @@ -352,7 +352,7 @@ gtk_socket_realize (GtkWidget *widget) * our window is passed to another application, SubstructureRedirectMask * will be set by the time the other app creates its window. */ - gdk_flush(); + gdk_display_sync (gtk_widget_get_display (widget)); } static void @@ -415,7 +415,7 @@ gtk_socket_size_request (GtkWidget *widget, gdk_error_trap_push (); - if (XGetWMNormalHints (GDK_DISPLAY(), + if (XGetWMNormalHints (GDK_WINDOW_XDISPLAY (socket->plug_window), GDK_WINDOW_XWINDOW (socket->plug_window), &hints, &supplied)) { @@ -515,7 +515,7 @@ gtk_socket_size_allocate (GtkWidget *widget, socket->need_map = FALSE; } - gdk_flush (); + gdk_display_sync (gtk_widget_get_display (widget)); gdk_error_trap_pop (); } } @@ -535,12 +535,13 @@ activate_key (GtkAccelGroup *accel_group, GdkEvent *gdk_event = gtk_get_current_event (); GtkSocket *socket = g_object_get_data (G_OBJECT (accel_group), "gtk-socket"); + GdkScreen *screen = gdk_drawable_get_screen (socket->plug_window); if (gdk_event && gdk_event->type == GDK_KEY_PRESS && socket->plug_window) { xevent.xkey.type = KeyPress; xevent.xkey.window = GDK_WINDOW_XWINDOW (socket->plug_window); - xevent.xkey.root = GDK_ROOT_WINDOW (); + xevent.xkey.root = GDK_WINDOW_XWINDOW (gdk_screen_get_root_window (screen)); xevent.xkey.subwindow = None; xevent.xkey.time = gdk_event->key.time; xevent.xkey.x = 0; @@ -552,10 +553,10 @@ activate_key (GtkAccelGroup *accel_group, xevent.xkey.same_screen = True; gdk_error_trap_push (); - XSendEvent (GDK_DISPLAY (), + XSendEvent (GDK_WINDOW_XDISPLAY (socket->plug_window), GDK_WINDOW_XWINDOW (socket->plug_window), False, KeyPressMask, &xevent); - gdk_flush (); + gdk_display_sync (gdk_screen_get_display (screen)); gdk_error_trap_pop (); } @@ -707,12 +708,12 @@ gtk_socket_key_press_event (GtkWidget *widget, if (GTK_WIDGET_HAS_FOCUS (socket) && socket->plug_window && !socket->plug_widget) { + GdkScreen *screen = gdk_drawable_get_screen (socket->plug_window); XEvent xevent; xevent.xkey.type = KeyPress; - xevent.xkey.display = GDK_WINDOW_XDISPLAY (event->window); xevent.xkey.window = GDK_WINDOW_XWINDOW (socket->plug_window); - xevent.xkey.root = GDK_ROOT_WINDOW (); + xevent.xkey.root = GDK_WINDOW_XWINDOW (gdk_screen_get_root_window (screen)); xevent.xkey.time = event->time; /* FIXME, the following might cause problems for non-GTK apps */ xevent.xkey.x = 0; @@ -724,10 +725,10 @@ gtk_socket_key_press_event (GtkWidget *widget, xevent.xkey.same_screen = TRUE; /* FIXME ? */ gdk_error_trap_push (); - XSendEvent (GDK_DISPLAY (), + XSendEvent (GDK_WINDOW_XDISPLAY (socket->plug_window), GDK_WINDOW_XWINDOW (socket->plug_window), False, NoEventMask, &xevent); - gdk_flush (); + gdk_display_sync (gtk_widget_get_display (widget)); gdk_error_trap_pop (); return TRUE; @@ -759,7 +760,7 @@ gtk_socket_focus_out_event (GtkWidget *widget, GdkEventFocus *event) if (toplevel && GTK_IS_WINDOW (toplevel)) { - XSetInputFocus (GDK_DISPLAY (), + XSetInputFocus (GDK_WINDOW_XDISPLAY (toplevel->window), GDK_WINDOW_XWINDOW (toplevel->window), RevertToParent, CurrentTime); /* FIXME? */ } @@ -795,10 +796,10 @@ gtk_socket_claim_focus (GtkSocket *socket) { #if 0 gdk_error_trap_push (); - XSetInputFocus (GDK_DISPLAY (), + XSetInputFocus (GDK_WINDOW_XDISPLAY (socket->plug_window), GDK_WINDOW_XWINDOW (socket->plug_window), RevertToParent, GDK_CURRENT_TIME); - gdk_flush (); + gdk_display_sync (gdk_drawable_get_display (socket->plug_window)); gdk_error_trap_pop (); #endif } @@ -847,15 +848,16 @@ gtk_socket_focus (GtkWidget *widget, GtkDirectionType direction) #if 0 if (!socket->focus_in && socket->plug_window) { + GdkScreen *screen = gdk_drawable_get_screen (socket->plug_window); + Display *xdisplay = GDK_SCREEN_XDISPLAY (screen); XEvent xevent; gtk_socket_claim_focus (socket); xevent.xkey.type = KeyPress; - xevent.xkey.display = GDK_DISPLAY (); xevent.xkey.window = GDK_WINDOW_XWINDOW (socket->plug_window); - xevent.xkey.root = GDK_ROOT_WINDOW (); /* FIXME */ - xevent.xkey.time = GDK_CURRENT_TIME; /* FIXME */ + xevent.xkey.root = GDK_WINDOW_XWINDOW (gdk_screen_get_root_window (socket->plug_window)); + xevent.xkey.time = GDK_CURRENT_TIME; /* FIXME, the following might cause big problems for * non-GTK apps */ xevent.xkey.x = 0; @@ -868,32 +870,32 @@ gtk_socket_focus (GtkWidget *widget, GtkDirectionType direction) switch (direction) { case GTK_DIR_UP: - xevent.xkey.keycode = XKeysymToKeycode(GDK_DISPLAY(), GDK_Up); + xevent.xkey.keycode = XKeysymToKeycode(xdisplay, GDK_Up); break; case GTK_DIR_DOWN: - xevent.xkey.keycode = XKeysymToKeycode(GDK_DISPLAY(), GDK_Down); + xevent.xkey.keycode = XKeysymToKeycode(xdisplay, GDK_Down); break; case GTK_DIR_LEFT: - xevent.xkey.keycode = XKeysymToKeycode(GDK_DISPLAY(), GDK_Left); + xevent.xkey.keycode = XKeysymToKeycode(xdisplay, GDK_Left); break; case GTK_DIR_RIGHT: - xevent.xkey.keycode = XKeysymToKeycode(GDK_DISPLAY(), GDK_Right); + xevent.xkey.keycode = XKeysymToKeycode(xdisplay, GDK_Right); break; case GTK_DIR_TAB_FORWARD: - xevent.xkey.keycode = XKeysymToKeycode(GDK_DISPLAY(), GDK_Tab); + xevent.xkey.keycode = XKeysymToKeycode(xdisplay, GDK_Tab); break; case GTK_DIR_TAB_BACKWARD: - xevent.xkey.keycode = XKeysymToKeycode(GDK_DISPLAY(), GDK_Tab); + xevent.xkey.keycode = XKeysymToKeycode(xdisplay, GDK_Tab); xevent.xkey.state = ShiftMask; break; } gdk_error_trap_push (); - XSendEvent (GDK_DISPLAY (), + XSendEvent (GDK_WINDOW_XDISPLAY (socket->plug_window), GDK_WINDOW_XWINDOW (socket->plug_window), False, NoEventMask, &xevent); - gdk_flush(); + gdk_display_sync (gdk_drawable_get_display (socket->plug_window)); gdk_error_trap_pop (); return TRUE; @@ -936,7 +938,6 @@ gtk_socket_send_configure_event (GtkSocket *socket) g_return_if_fail (socket->plug_window != NULL); event.xconfigure.type = ConfigureNotify; - event.xconfigure.display = GDK_DISPLAY (); event.xconfigure.event = GDK_WINDOW_XWINDOW (socket->plug_window); event.xconfigure.window = GDK_WINDOW_XWINDOW (socket->plug_window); @@ -951,10 +952,10 @@ gtk_socket_send_configure_event (GtkSocket *socket) event.xconfigure.override_redirect = False; gdk_error_trap_push (); - XSendEvent (GDK_DISPLAY (), + XSendEvent (GDK_WINDOW_XDISPLAY (socket->plug_window), GDK_WINDOW_XWINDOW (socket->plug_window), False, NoEventMask, &event); - gdk_flush (); + gdk_display_sync (gtk_widget_get_display (GTK_WIDGET (socket))); gdk_error_trap_pop (); } @@ -965,9 +966,10 @@ gtk_socket_add_window (GtkSocket *socket, { GtkWidget *widget = GTK_WIDGET (socket); + GdkDisplay *display = gtk_widget_get_display (widget); gpointer user_data = NULL; - socket->plug_window = gdk_window_lookup (xid); + socket->plug_window = gdk_window_lookup_for_display (display, xid); if (socket->plug_window) { @@ -1001,7 +1003,7 @@ gtk_socket_add_window (GtkSocket *socket, if (!socket->plug_window) { - socket->plug_window = gdk_window_foreign_new (xid); + socket->plug_window = gdk_window_foreign_new_for_display (display, xid); if (!socket->plug_window) /* was deleted before we could get it */ { gdk_error_trap_pop (); @@ -1009,8 +1011,8 @@ gtk_socket_add_window (GtkSocket *socket, } } - XSelectInput (GDK_DISPLAY (), - GDK_WINDOW_XWINDOW(socket->plug_window), + XSelectInput (GDK_DISPLAY_XDISPLAY (display), + GDK_WINDOW_XWINDOW (socket->plug_window), StructureNotifyMask | PropertyChangeMask); if (gdk_error_trap_pop ()) @@ -1047,11 +1049,11 @@ gtk_socket_add_window (GtkSocket *socket, socket->need_map = socket->is_mapped; - if (gdk_drag_get_protocol (xid, &protocol)) + if (gdk_drag_get_protocol_for_display (display, xid, &protocol)) gtk_drag_dest_set_proxy (GTK_WIDGET (socket), socket->plug_window, protocol, TRUE); - - gdk_flush (); + + gdk_display_sync (display); gdk_error_trap_pop (); gdk_window_add_filter (socket->plug_window, @@ -1084,11 +1086,12 @@ send_xembed_message (GtkSocket *socket, if (socket->plug_window) { + GdkDisplay *display = gtk_widget_get_display (GTK_WIDGET (socket)); XEvent xevent; xevent.xclient.window = GDK_WINDOW_XWINDOW (socket->plug_window); xevent.xclient.type = ClientMessage; - xevent.xclient.message_type = gdk_x11_get_xatom_by_name ("_XEMBED"); + xevent.xclient.message_type = gdk_x11_get_xatom_by_name_for_display (display, "_XEMBED"); xevent.xclient.format = 32; xevent.xclient.data.l[0] = time; xevent.xclient.data.l[1] = message; @@ -1097,22 +1100,21 @@ send_xembed_message (GtkSocket *socket, xevent.xclient.data.l[4] = data2; gdk_error_trap_push (); - XSendEvent (GDK_DISPLAY (), + XSendEvent (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XWINDOW (socket->plug_window), False, NoEventMask, &xevent); - gdk_flush (); + gdk_display_sync (display); gdk_error_trap_pop (); } } static gboolean -xembed_get_info (GdkWindow *gdk_window, +xembed_get_info (GdkWindow *window, unsigned long *version, unsigned long *flags) { - Display *display = GDK_WINDOW_XDISPLAY (gdk_window); - Window window = GDK_WINDOW_XWINDOW (gdk_window); - Atom xembed_info_atom = gdk_x11_get_xatom_by_name ("_XEMBED_INFO"); + GdkDisplay *display = gdk_drawable_get_display (window); + Atom xembed_info_atom = gdk_x11_get_xatom_by_name_for_display (display, "_XEMBED_INFO"); Atom type; int format; unsigned long nitems, bytes_after; @@ -1121,7 +1123,8 @@ xembed_get_info (GdkWindow *gdk_window, int status; gdk_error_trap_push(); - status = XGetWindowProperty (display, window, + status = XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), + GDK_WINDOW_XWINDOW (window), xembed_info_atom, 0, 2, False, xembed_info_atom, &type, &format, @@ -1206,8 +1209,8 @@ handle_xembed_message (GtkSocket *socket, break; default: - GTK_NOTE(PLUGSOCKET, - g_message ("GtkSocket: Ignoring unknown _XEMBED message of type %ld", message)); + GTK_NOTE (PLUGSOCKET, + g_message ("GtkSocket: Ignoring unknown _XEMBED message of type %ld", message)); break; } } @@ -1239,6 +1242,7 @@ gtk_socket_filter_func (GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data) { GtkSocket *socket; GtkWidget *widget; + GdkDisplay *display; XEvent *xevent; GdkFilterReturn return_val; @@ -1246,6 +1250,7 @@ gtk_socket_filter_func (GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data) socket = GTK_SOCKET (data); widget = GTK_WIDGET (socket); xevent = (XEvent *)gdk_xevent; + display = gdk_drawable_get_display (event->any.window); return_val = GDK_FILTER_CONTINUE; @@ -1255,7 +1260,7 @@ gtk_socket_filter_func (GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data) switch (xevent->type) { case ClientMessage: - if (xevent->xclient.message_type == gdk_x11_get_xatom_by_name ("_XEMBED")) + if (xevent->xclient.message_type == gdk_x11_get_xatom_by_name_for_display (display, "_XEMBED")) { handle_xembed_message (socket, xevent->xclient.data.l[1], @@ -1369,7 +1374,7 @@ gtk_socket_filter_func (GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data) if (toplevel && GTK_IS_WINDOW (topelevel)) { - XSetInputFocus (GDK_DISPLAY (), + XSetInputFocus (GDK_WINDOW_XDISPLAY (toplevel->window), GDK_WINDOW_XWINDOW (toplevel->window), RevertToParent, CurrentTime); /* FIXME? */ } @@ -1399,18 +1404,21 @@ gtk_socket_filter_func (GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data) { GdkDragProtocol protocol; - if ((xevent->xproperty.atom == gdk_x11_get_xatom_by_name ("XdndAware")) || - (xevent->xproperty.atom == gdk_x11_get_xatom_by_name ("_MOTIF_DRAG_RECEIVER_INFO"))) + if ((xevent->xproperty.atom == gdk_x11_get_xatom_by_name_for_display (display, "XdndAware")) || + (xevent->xproperty.atom == gdk_x11_get_xatom_by_name_for_display (display, "_MOTIF_DRAG_RECEIVER_INFO"))) { gdk_error_trap_push (); - if (gdk_drag_get_protocol (xevent->xproperty.window, &protocol)) + if (gdk_drag_get_protocol_for_display (display, + xevent->xproperty.window, + &protocol)) gtk_drag_dest_set_proxy (GTK_WIDGET (socket), socket->plug_window, protocol, TRUE); - gdk_flush (); + + gdk_display_sync (display); gdk_error_trap_pop (); } - else if (xevent->xproperty.atom == gdk_x11_get_xatom_by_name ("_XEMBED_INFO")) + else if (xevent->xproperty.atom == gdk_x11_get_xatom_by_name_for_display (display, "_XEMBED_INFO")) { unsigned long flags; diff --git a/gtk/gtkstyle.c b/gtk/gtkstyle.c index d0229155db..5d3979bd60 100644 --- a/gtk/gtkstyle.c +++ b/gtk/gtkstyle.c @@ -46,7 +46,6 @@ typedef struct { GValue value; } PropertyValue; - /* --- prototypes --- */ static void gtk_style_init (GtkStyle *style); static void gtk_style_class_init (GtkStyleClass *klass); @@ -414,7 +413,7 @@ static char radio_inconsistent_aa_bits[] = { static struct { char *bits; - GdkBitmap *bmap; + GList *bmap_list; /* list of GdkBitmap */ } indicator_parts[] = { { check_aa_bits, NULL }, { check_base_bits, NULL }, @@ -775,6 +774,12 @@ gtk_style_attach (GtkStyle *style, if (!new_style) { new_style = gtk_style_duplicate (style); + if (style->colormap->screen != colormap->screen && + new_style->private_font) + { + gdk_font_unref (new_style->private_font); + new_style->private_font = NULL; + } gtk_style_realize (new_style, colormap); } @@ -2011,6 +2016,34 @@ sanitize_size (GdkWindow *window, gdk_window_get_size (window, NULL, height); } +static GdkBitmap * +get_indicator_for_screen (GdkDrawable *drawable, + IndicatorPart part) + +{ + GdkScreen *screen = gdk_drawable_get_screen (drawable); + GdkBitmap *bitmap; + GList *tmp_list; + + tmp_list = indicator_parts[part].bmap_list; + while (tmp_list) + { + bitmap = tmp_list->data; + + if (gdk_drawable_get_screen (bitmap) == screen) + return bitmap; + + tmp_list = tmp_list->next; + } + + bitmap = gdk_bitmap_create_from_data (drawable, + indicator_parts[part].bits, + INDICATOR_PART_SIZE, INDICATOR_PART_SIZE); + indicator_parts[part].bmap_list = g_list_prepend (indicator_parts[part].bmap_list, bitmap); + + return bitmap; +} + static void draw_part (GdkDrawable *drawable, GdkGC *gc, @@ -2022,13 +2055,8 @@ draw_part (GdkDrawable *drawable, if (area) gdk_gc_set_clip_rectangle (gc, area); - if (!indicator_parts[part].bmap) - indicator_parts[part].bmap = gdk_bitmap_create_from_data (drawable, - indicator_parts[part].bits, - INDICATOR_PART_SIZE, INDICATOR_PART_SIZE); - gdk_gc_set_ts_origin (gc, x, y); - gdk_gc_set_stipple (gc, indicator_parts[part].bmap); + gdk_gc_set_stipple (gc, get_indicator_for_screen (drawable, part)); gdk_gc_set_fill (gc, GDK_STIPPLED); gdk_draw_rectangle (drawable, gc, TRUE, x, y, INDICATOR_PART_SIZE, INDICATOR_PART_SIZE); @@ -3067,9 +3095,13 @@ gtk_default_draw_string (GtkStyle *style, gint y, const gchar *string) { + GdkDisplay *display; + g_return_if_fail (GTK_IS_STYLE (style)); g_return_if_fail (window != NULL); + display = gdk_drawable_get_display (window); + if (area) { gdk_gc_set_clip_rectangle (style->white_gc, area); @@ -3077,9 +3109,13 @@ gtk_default_draw_string (GtkStyle *style, } if (state_type == GTK_STATE_INSENSITIVE) - gdk_draw_string (window, gtk_style_get_font (style), style->white_gc, x + 1, y + 1, string); + gdk_draw_string (window, + gtk_style_get_font_for_display (display, style), + style->white_gc, x + 1, y + 1, string); - gdk_draw_string (window, gtk_style_get_font (style), style->fg_gc[state_type], x, y, string); + gdk_draw_string (window, + gtk_style_get_font_for_display (display, style), + style->fg_gc[state_type], x, y, string); if (area) { @@ -4628,7 +4664,8 @@ range_new (guint start, } static PangoLayout* -get_insensitive_layout (PangoLayout *layout) +get_insensitive_layout (GdkDrawable *drawable, + PangoLayout *layout) { GSList *embossed_ranges = NULL; GSList *stippled_ranges = NULL; @@ -4731,7 +4768,7 @@ get_insensitive_layout (PangoLayout *layout) 0x02, 0x01 }; - stipple = gdk_bitmap_create_from_data (NULL, + stipple = gdk_bitmap_create_from_data (drawable, gray50_bits, gray50_width, gray50_height); } @@ -4782,7 +4819,7 @@ gtk_default_draw_layout (GtkStyle *style, { PangoLayout *ins; - ins = get_insensitive_layout (layout); + ins = get_insensitive_layout (window, layout); gdk_draw_layout (window, gc, x, y, ins); @@ -5562,21 +5599,24 @@ gtk_border_get_type (void) } /** - * gtk_style_get_font: + * gtk_style_get_font_for_display: + * @display : a #GdkDisplay * @style: a #GtkStyle * * Gets the #GdkFont to use for the given style. This is - * meant only as a replacement for direct access to @style->font + * meant only as a replacement for direct access to style->font * and should not be used in new code. New code should - * use @style->font_desc instead. + * use style->font_desc instead. * * Return value: the #GdkFont for the style. This font is owned * by the style; if you want to keep around a copy, you must * call gdk_font_ref(). **/ GdkFont * -gtk_style_get_font (GtkStyle *style) +gtk_style_get_font_for_display (GdkDisplay *display, + GtkStyle *style) { + g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL); g_return_val_if_fail (GTK_IS_STYLE (style), NULL); if (style->private_font && style->private_font_desc) @@ -5599,13 +5639,14 @@ gtk_style_get_font (GtkStyle *style) { if (style->font_desc) { - style->private_font = gdk_font_from_description (style->font_desc); + /* no colormap, no screen */ + style->private_font = gdk_font_from_description_for_display (display, style->font_desc); style->private_font_desc = pango_font_description_copy (style->font_desc); } if (!style->private_font) - style->private_font = gdk_font_load ("fixed"); - + style->private_font = gdk_font_load_for_display (display, "fixed"); + if (!style->private_font) g_error ("Unable to load \"fixed\" font"); } @@ -5614,6 +5655,27 @@ gtk_style_get_font (GtkStyle *style) } /** + * gtk_style_get_font: + * @style: a #GtkStyle + * + * Gets the #GdkFont to use for the given style. This is + * meant only as a replacement for direct access to @style->font + * and should not be used in new code. New code should + * use @style->font_desc instead. + * + * Return value: the #GdkFont for the style. This font is owned + * by the style; if you want to keep around a copy, you must + * call gdk_font_ref(). + **/ +GdkFont * +gtk_style_get_font (GtkStyle *style) +{ + g_return_val_if_fail (GTK_IS_STYLE (style), NULL); + + return gtk_style_get_font_for_display (gdk_get_default_display (), style); +} + +/** * gtk_style_set_font: * @style: a #GtkStyle. * @font: a #GdkFont, or %NULL to use the #GdkFont corresponding diff --git a/gtk/gtkstyle.h b/gtk/gtkstyle.h index ce4c3901c1..d07a126d37 100644 --- a/gtk/gtkstyle.h +++ b/gtk/gtkstyle.h @@ -435,7 +435,11 @@ void gtk_style_detach (GtkStyle *style); GtkStyle* gtk_style_ref (GtkStyle *style); void gtk_style_unref (GtkStyle *style); +#ifndef GDK_MULTIHEAD_SAFE GdkFont * gtk_style_get_font (GtkStyle *style); +#endif +GdkFont * gtk_style_get_font_for_display (GdkDisplay *display, + GtkStyle *style); void gtk_style_set_font (GtkStyle *style, GdkFont *font); #endif /* GTK_DISABLE_DEPRECATED */ diff --git a/gtk/gtktext.c b/gtk/gtktext.c index 8a53a24044..f1519173aa 100644 --- a/gtk/gtktext.c +++ b/gtk/gtktext.c @@ -73,7 +73,8 @@ #define MARK_CURRENT_FONT(text, mark) \ ((MARK_CURRENT_PROPERTY(mark)->flags & PROPERTY_FONT) ? \ MARK_CURRENT_PROPERTY(mark)->font->gdk_font : \ - gtk_style_get_font (GTK_WIDGET (text)->style)) + gtk_style_get_font_for_display (gtk_widget_get_display (GTK_WIDGET (text)), \ + GTK_WIDGET (text)->style)) #define MARK_CURRENT_FORE(text, mark) \ ((MARK_CURRENT_PROPERTY(mark)->flags & PROPERTY_FOREGROUND) ? \ &MARK_CURRENT_PROPERTY(mark)->fore_color : \ @@ -995,10 +996,11 @@ gtk_text_insert (GtkText *text, if ((TEXT_LENGTH (text) == 0) && (text->use_wchar == FALSE)) { - GtkWidget *widget; - widget = GTK_WIDGET (text); + GtkWidget *widget = GTK_WIDGET (text); + gtk_widget_ensure_style (widget); - if ((widget->style) && (gtk_style_get_font (widget->style)->type == GDK_FONT_FONTSET)) + if ((widget->style) && + (gtk_style_get_font_for_display (gtk_widget_get_display (widget), widget->style)->type == GDK_FONT_FONTSET)) { text->use_wchar = TRUE; g_free (text->text.ch); @@ -1342,7 +1344,7 @@ gtk_text_realize (GtkWidget *widget) attributes.width = MAX (1, (gint)widget->allocation.width - (gint)attributes.x * 2); attributes.height = MAX (1, (gint)widget->allocation.height - (gint)attributes.y * 2); - attributes.cursor = gdk_cursor_new (GDK_XTERM); + attributes.cursor = gdk_cursor_new_for_screen (gtk_widget_get_screen (widget), GDK_XTERM); attributes_mask |= GDK_WA_CURSOR; text->text_area = gdk_window_new (widget->window, &attributes, attributes_mask); @@ -1405,10 +1407,10 @@ gtk_text_style_set (GtkWidget *widget, recompute_geometry (text); } - + if (text->current_font) text_font_unref (text->current_font); - text->current_font = get_text_font (gtk_style_get_font (widget->style)); + text->current_font = get_text_font (gtk_style_get_font_for_display (gtk_widget_get_display (widget), widget->style)); } static void @@ -1572,7 +1574,8 @@ gtk_text_size_request (GtkWidget *widget, xthickness = widget->style->xthickness + TEXT_BORDER_ROOM; ythickness = widget->style->ythickness + TEXT_BORDER_ROOM; - font = gtk_style_get_font (widget->style); + font = gtk_style_get_font_for_display (gtk_widget_get_display (widget), + widget->style); char_height = MIN_TEXT_HEIGHT_LINES * (font->ascent + font->descent); @@ -1741,6 +1744,8 @@ gtk_text_button_press (GtkWidget *widget, } else { + GdkDisplay *display = gtk_widget_get_display (widget); + gtk_grab_add (widget); undraw_cursor (text, FALSE); @@ -1752,8 +1757,12 @@ gtk_text_button_press (GtkWidget *widget, text->cursor_mark.index); old_editable->has_selection = FALSE; - if (gdk_selection_owner_get (GDK_SELECTION_PRIMARY) == widget->window) - gtk_selection_owner_set (NULL, GDK_SELECTION_PRIMARY, event->time); + if (gdk_selection_owner_get_for_display (display, + GDK_SELECTION_PRIMARY) == widget->window) + gtk_selection_owner_set_for_display (display, + NULL, + GDK_SELECTION_PRIMARY, + event->time); } } @@ -1766,6 +1775,8 @@ gtk_text_button_release (GtkWidget *widget, { GtkText *text; GtkOldEditable *old_editable; + GdkDisplay *display; + g_return_val_if_fail (GTK_IS_TEXT (widget), FALSE); g_return_val_if_fail (event != NULL, FALSE); @@ -1788,15 +1799,17 @@ gtk_text_button_release (GtkWidget *widget, { text = GTK_TEXT (widget); old_editable = GTK_OLD_EDITABLE (widget); + display = gtk_widget_get_display (widget); gtk_grab_remove (widget); old_editable->has_selection = FALSE; if (old_editable->selection_start_pos != old_editable->selection_end_pos) { - if (gtk_selection_owner_set (widget, - GDK_SELECTION_PRIMARY, - event->time)) + if (gtk_selection_owner_set_for_display (display, + widget, + GDK_SELECTION_PRIMARY, + event->time)) old_editable->has_selection = TRUE; else gtk_text_update_text (old_editable, old_editable->selection_start_pos, @@ -1804,8 +1817,12 @@ gtk_text_button_release (GtkWidget *widget, } else { - if (gdk_selection_owner_get (GDK_SELECTION_PRIMARY) == widget->window) - gtk_selection_owner_set (NULL, GDK_SELECTION_PRIMARY, event->time); + if (gdk_selection_owner_get_for_display (display, + GDK_SELECTION_PRIMARY) == widget->window) + gtk_selection_owner_set_for_display (display, + NULL, + GDK_SELECTION_PRIMARY, + event->time); } } else if (event->button == 3) diff --git a/gtk/gtktextbuffer.c b/gtk/gtktextbuffer.c index 554f8315ae..2a66d9e32b 100644 --- a/gtk/gtktextbuffer.c +++ b/gtk/gtktextbuffer.c @@ -2888,7 +2888,8 @@ selection_data_get_buffer (GtkSelectionData *selection_data, GtkTextBuffer *src_buffer = NULL; /* If we can get the owner, the selection is in-process */ - owner = gdk_selection_owner_get (selection_data->selection); + owner = gdk_selection_owner_get_for_display (selection_data->display, + selection_data->selection); if (owner == NULL) return NULL; diff --git a/gtk/gtktextdisplay.c b/gtk/gtktextdisplay.c index 99b8631fce..75b3fc932c 100644 --- a/gtk/gtktextdisplay.c +++ b/gtk/gtktextdisplay.c @@ -143,6 +143,8 @@ static void gtk_text_render_state_update (GtkTextRenderState *state, GtkTextAppearance *new_appearance) { + GdkScreen *screen = gtk_widget_get_screen (state->widget); + if (!state->last_appearance || !gdk_color_equal (&new_appearance->fg_color, &state->last_appearance->fg_color)) gtk_text_render_state_set_color (state, state->fg_gc, &new_appearance->fg_color); @@ -152,8 +154,15 @@ gtk_text_render_state_update (GtkTextRenderState *state, { if (new_appearance->fg_stipple) { - gdk_gc_set_fill (state->fg_gc, GDK_STIPPLED); - gdk_gc_set_stipple (state->fg_gc, new_appearance->fg_stipple); + if (screen == gdk_drawable_get_screen (new_appearance->fg_stipple)) + { + gdk_gc_set_fill (state->fg_gc, GDK_STIPPLED); + gdk_gc_set_stipple (state->fg_gc, new_appearance->fg_stipple); + } + else + g_warning ("gtk_text_render_state_update:\n" + "The foreground stipple bitmap has been created on the wrong screen.\n" + "Ignoring the stipple bitmap information."); } else { @@ -172,8 +181,16 @@ gtk_text_render_state_update (GtkTextRenderState *state, { if (new_appearance->bg_stipple) { - gdk_gc_set_fill (state->bg_gc, GDK_STIPPLED); - gdk_gc_set_stipple (state->bg_gc, new_appearance->bg_stipple); + if (screen == gdk_drawable_get_screen (new_appearance->bg_stipple)) + { + gdk_gc_set_fill (state->bg_gc, GDK_STIPPLED); + gdk_gc_set_stipple (state->bg_gc, new_appearance->bg_stipple); + } + else + g_warning ("gtk_text_render_state_update:\n" + "The background stipple bitmap has been created on the wrong screen.\n" + "Ignoring the stipple bitmap information."); + } else { diff --git a/gtk/gtktextview.c b/gtk/gtktextview.c index 63a34e75fa..5f660b2ab0 100644 --- a/gtk/gtktextview.c +++ b/gtk/gtktextview.c @@ -1094,8 +1094,11 @@ gtk_text_view_set_buffer (GtkTextView *text_view, text_view->dnd_mark = NULL; if (GTK_WIDGET_REALIZED (text_view)) - gtk_text_buffer_remove_selection_clipboard (text_view->buffer, - gtk_clipboard_get (GDK_SELECTION_PRIMARY)); + { + GtkClipboard *clipboard = gtk_widget_get_clipboard (GTK_WIDGET (text_view), + GDK_SELECTION_PRIMARY); + gtk_text_buffer_remove_selection_clipboard (text_view->buffer, clipboard); + } } text_view->buffer = buffer; @@ -1125,8 +1128,11 @@ gtk_text_view_set_buffer (GtkTextView *text_view, G_CALLBACK (gtk_text_view_mark_set_handler), text_view); if (GTK_WIDGET_REALIZED (text_view)) - gtk_text_buffer_add_selection_clipboard (text_view->buffer, - gtk_clipboard_get (GDK_SELECTION_PRIMARY)); + { + GtkClipboard *clipboard = gtk_widget_get_clipboard (GTK_WIDGET (text_view), + GDK_SELECTION_PRIMARY); + gtk_text_buffer_add_selection_clipboard (text_view->buffer, clipboard); + } } if (GTK_WIDGET_VISIBLE (text_view)) @@ -3311,8 +3317,11 @@ gtk_text_view_realize (GtkWidget *widget) gtk_text_view_ensure_layout (text_view); if (text_view->buffer) - gtk_text_buffer_add_selection_clipboard (text_view->buffer, - gtk_clipboard_get (GDK_SELECTION_PRIMARY)); + { + GtkClipboard *clipboard = gtk_widget_get_clipboard (GTK_WIDGET (text_view), + GDK_SELECTION_PRIMARY); + gtk_text_buffer_add_selection_clipboard (text_view->buffer, clipboard); + } tmp_list = text_view->children; while (tmp_list != NULL) @@ -3333,8 +3342,11 @@ gtk_text_view_unrealize (GtkWidget *widget) text_view = GTK_TEXT_VIEW (widget); if (text_view->buffer) - gtk_text_buffer_remove_selection_clipboard (text_view->buffer, - gtk_clipboard_get (GDK_SELECTION_PRIMARY)); + { + GtkClipboard *clipboard = gtk_widget_get_clipboard (GTK_WIDGET (text_view), + GDK_SELECTION_PRIMARY); + gtk_text_buffer_remove_selection_clipboard (text_view->buffer, clipboard); + } gtk_text_view_remove_validate_idles (text_view); @@ -3747,7 +3759,7 @@ gtk_text_view_button_press_event (GtkWidget *widget, GdkEventButton *event) event->y + text_view->yoffset); gtk_text_buffer_paste_clipboard (get_buffer (text_view), - gtk_clipboard_get (GDK_SELECTION_PRIMARY), + gtk_widget_get_clipboard (widget, GDK_SELECTION_PRIMARY), &iter, text_view->editable); return TRUE; @@ -3910,7 +3922,7 @@ gtk_text_view_focus_in_event (GtkWidget *widget, GdkEventFocus *event) gtk_text_view_check_cursor_blink (text_view); } - g_signal_connect (gdk_keymap_get_default (), + g_signal_connect (gdk_keymap_get_for_display (gtk_widget_get_display (widget)), "direction_changed", G_CALLBACK (keymap_direction_changed), text_view); gtk_text_view_check_keymap_direction (text_view); @@ -3936,9 +3948,9 @@ gtk_text_view_focus_out_event (GtkWidget *widget, GdkEventFocus *event) gtk_text_view_check_cursor_blink (text_view); } - g_signal_handlers_disconnect_by_func (gdk_keymap_get_default (), - (gpointer) keymap_direction_changed, - text_view); + g_signal_handlers_disconnect_by_func (gdk_keymap_get_for_display (gtk_widget_get_display (widget)), + (gpointer) keymap_direction_changed, + text_view); text_view->need_im_reset = TRUE; gtk_im_context_focus_out (GTK_TEXT_VIEW (widget)->im_context); @@ -3955,7 +3967,8 @@ gtk_text_view_motion_event (GtkWidget *widget, GdkEventMotion *event) { GdkCursor *cursor; - cursor = gdk_cursor_new (GDK_XTERM); + cursor = gdk_cursor_new_for_screen (gtk_widget_get_screen (widget), + GDK_XTERM); gdk_window_set_cursor (text_view->text_window->bin_window, cursor); gdk_cursor_unref (cursor); text_view->mouse_cursor_obscured = FALSE; @@ -4887,8 +4900,11 @@ gtk_text_view_delete_from_cursor (GtkTextView *text_view, static void gtk_text_view_cut_clipboard (GtkTextView *text_view) { + GtkClipboard *clipboard = gtk_widget_get_clipboard (GTK_WIDGET (text_view), + GDK_SELECTION_CLIPBOARD); + gtk_text_buffer_cut_clipboard (get_buffer (text_view), - gtk_clipboard_get (GDK_SELECTION_CLIPBOARD), + clipboard, text_view->editable); DV(g_print (G_STRLOC": scrolling onscreen\n")); gtk_text_view_scroll_mark_onscreen (text_view, @@ -4899,8 +4915,11 @@ gtk_text_view_cut_clipboard (GtkTextView *text_view) static void gtk_text_view_copy_clipboard (GtkTextView *text_view) { + GtkClipboard *clipboard = gtk_widget_get_clipboard (GTK_WIDGET (text_view), + GDK_SELECTION_CLIPBOARD); + gtk_text_buffer_copy_clipboard (get_buffer (text_view), - gtk_clipboard_get (GDK_SELECTION_CLIPBOARD)); + clipboard); DV(g_print (G_STRLOC": scrolling onscreen\n")); gtk_text_view_scroll_mark_onscreen (text_view, gtk_text_buffer_get_mark (get_buffer (text_view), @@ -4910,8 +4929,11 @@ gtk_text_view_copy_clipboard (GtkTextView *text_view) static void gtk_text_view_paste_clipboard (GtkTextView *text_view) { + GtkClipboard *clipboard = gtk_widget_get_clipboard (GTK_WIDGET (text_view), + GDK_SELECTION_CLIPBOARD); + gtk_text_buffer_paste_clipboard (get_buffer (text_view), - gtk_clipboard_get (GDK_SELECTION_CLIPBOARD), + clipboard, NULL, text_view->editable); DV(g_print (G_STRLOC": scrolling onscreen\n")); @@ -5177,10 +5199,15 @@ gtk_text_view_check_keymap_direction (GtkTextView *text_view) "gtk-split-cursor", &split_cursor, NULL); if (split_cursor) - new_dir = GTK_TEXT_DIR_NONE; + { + new_dir = GTK_TEXT_DIR_NONE; + } else - new_dir = (gdk_keymap_get_direction (gdk_keymap_get_default ()) == PANGO_DIRECTION_LTR) ? - GTK_TEXT_DIR_LTR : GTK_TEXT_DIR_RTL; + { + GdkKeymap *keymap = gdk_keymap_get_for_display (gtk_widget_get_display (GTK_WIDGET (text_view))); + new_dir = (gdk_keymap_get_direction (keymap) == PANGO_DIRECTION_LTR) ? + GTK_TEXT_DIR_LTR : GTK_TEXT_DIR_RTL; + } if (text_view->layout->cursor_direction != new_dir) gtk_text_layout_set_cursor_direction (text_view->layout, new_dir); @@ -6228,11 +6255,14 @@ popup_position_func (GtkMenu *menu, gint root_x, root_y; GtkTextIter iter; GtkRequisition req; + GdkScreen *screen; text_view = GTK_TEXT_VIEW (user_data); widget = GTK_WIDGET (text_view); g_return_if_fail (GTK_WIDGET_REALIZED (text_view)); + + screen = gtk_widget_get_screen (widget); gdk_window_get_origin (widget->window, &root_x, &root_y); @@ -6273,8 +6303,8 @@ popup_position_func (GtkMenu *menu, *x = CLAMP (*x, root_x, (root_x + widget->allocation.width)); *y = CLAMP (*y, root_y, (root_y + widget->allocation.height)); - *x = CLAMP (*x, 0, MAX (0, gdk_screen_width () - req.width)); - *y = CLAMP (*y, 0, MAX (0, gdk_screen_height () - req.height)); + *x = CLAMP (*x, 0, MAX (0, gdk_screen_get_width (screen) - req.width)); + *y = CLAMP (*y, 0, MAX (0, gdk_screen_get_height (screen) - req.height)); } typedef struct @@ -6431,7 +6461,8 @@ gtk_text_view_do_popup (GtkTextView *text_view, info->time = gtk_get_current_event_time (); } - gtk_clipboard_request_contents (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD), + gtk_clipboard_request_contents (gtk_widget_get_clipboard (GTK_WIDGET (text_view), + GDK_SELECTION_CLIPBOARD), gdk_atom_intern ("TARGETS", FALSE), popup_targets_received, info); @@ -6530,7 +6561,8 @@ text_window_realize (GtkTextWindow *win, if (win->type == GTK_TEXT_WINDOW_TEXT) { /* I-beam cursor */ - cursor = gdk_cursor_new (GDK_XTERM); + cursor = gdk_cursor_new_for_screen (gdk_drawable_get_screen (parent), + GDK_XTERM); gdk_window_set_cursor (win->bin_window, cursor); gdk_cursor_unref (cursor); diff --git a/gtk/gtktipsquery.c b/gtk/gtktipsquery.c index c2ee0de0b0..faab09c07b 100644 --- a/gtk/gtktipsquery.c +++ b/gtk/gtktipsquery.c @@ -342,7 +342,8 @@ gtk_tips_query_real_start_query (GtkTipsQuery *tips_query) g_return_if_fail (GTK_IS_TIPS_QUERY (tips_query)); - tips_query->query_cursor = gdk_cursor_new (GDK_QUESTION_ARROW); + tips_query->query_cursor = gdk_cursor_new_for_screen (gtk_widget_get_screen (GTK_WIDGET (tips_query)), + GDK_QUESTION_ARROW); failure = gdk_pointer_grab (GTK_WIDGET (tips_query)->window, TRUE, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | @@ -366,7 +367,8 @@ gtk_tips_query_real_stop_query (GtkTipsQuery *tips_query) gtk_grab_remove (GTK_WIDGET (tips_query)); if (tips_query->query_cursor) { - gdk_pointer_ungrab (GDK_CURRENT_TIME); + gdk_display_pointer_ungrab (gtk_widget_get_display (GTK_WIDGET (tips_query)), + GDK_CURRENT_TIME); gdk_cursor_destroy (tips_query->query_cursor); tips_query->query_cursor = NULL; } diff --git a/gtk/gtktoolbar.c b/gtk/gtktoolbar.c index 222b65daee..3366841b5b 100644 --- a/gtk/gtktoolbar.c +++ b/gtk/gtktoolbar.c @@ -72,7 +72,6 @@ struct _GtkToolbarChildSpace static void gtk_toolbar_class_init (GtkToolbarClass *class); static void gtk_toolbar_init (GtkToolbar *toolbar); -static void gtk_toolbar_finalize (GObject *object); static void gtk_toolbar_set_property (GObject *object, guint prop_id, const GValue *value, @@ -92,6 +91,8 @@ static void gtk_toolbar_style_set (GtkWidget *widget, GtkStyle *prev_style); static gboolean gtk_toolbar_focus (GtkWidget *widget, GtkDirectionType dir); +static void gtk_toolbar_hierarchy_changed (GtkWidget *widget, + GtkWidget *previous_toplevel); static void gtk_toolbar_show_all (GtkWidget *widget); static void gtk_toolbar_add (GtkContainer *container, GtkWidget *widget); @@ -181,8 +182,6 @@ gtk_toolbar_class_init (GtkToolbarClass *class) parent_class = gtk_type_class (gtk_container_get_type ()); - gobject_class->finalize = gtk_toolbar_finalize; - object_class->destroy = gtk_toolbar_destroy; gobject_class->set_property = gtk_toolbar_set_property; gobject_class->get_property = gtk_toolbar_get_property; @@ -193,6 +192,7 @@ gtk_toolbar_class_init (GtkToolbarClass *class) widget_class->style_set = gtk_toolbar_style_set; widget_class->show_all = gtk_toolbar_show_all; widget_class->focus = gtk_toolbar_focus; + widget_class->hierarchy_changed = gtk_toolbar_hierarchy_changed; container_class->add = gtk_toolbar_add; container_class->remove = gtk_toolbar_remove; @@ -296,14 +296,8 @@ gtk_toolbar_class_init (GtkToolbarClass *class) } static void -style_change_notify (GObject *object, - GParamSpec *pspec, - gpointer data) +style_change_notify (GtkToolbar *toolbar) { - GtkToolbar *toolbar; - - toolbar = GTK_TOOLBAR (data); - if (!toolbar->style_set) { /* pretend it was set, then unset, thus reverting to new default */ @@ -313,14 +307,8 @@ style_change_notify (GObject *object, } static void -icon_size_change_notify (GObject *object, - GParamSpec *pspec, - gpointer data) +icon_size_change_notify (GtkToolbar *toolbar) { - GtkToolbar *toolbar; - - toolbar = GTK_TOOLBAR (data); - if (!toolbar->icon_size_set) { /* pretend it was set, then unset, thus reverting to new default */ @@ -330,6 +318,72 @@ icon_size_change_notify (GObject *object, } static void +toolbar_screen_changed (GtkToolbar *toolbar) +{ + GtkSettings *old_settings = g_object_get_data (G_OBJECT (toolbar), "gtk-toolbar-settings"); + GtkSettings *settings; + + if (gtk_widget_has_screen (GTK_WIDGET (toolbar))) + settings = gtk_widget_get_settings (GTK_WIDGET (toolbar)); + else + settings = NULL; + + if (settings == old_settings) + return; + + if (old_settings) + { + g_signal_handler_disconnect (old_settings, toolbar->style_set_connection); + g_signal_handler_disconnect (old_settings, toolbar->icon_size_connection); + + g_object_unref (old_settings); + } + + if (settings) + { + toolbar->style_set_connection = g_signal_connect_swapped (settings, + "notify::gtk-toolbar-style", + G_CALLBACK (style_change_notify), + toolbar); + + toolbar->icon_size_connection = g_signal_connect_swapped (settings, + "notify::gtk-toolbar-icon-size", + G_CALLBACK (icon_size_change_notify), + toolbar); + + + g_object_ref (settings); + g_object_set_data (G_OBJECT (toolbar), "gtk-toolbar-settings", settings); + + style_change_notify (toolbar); + icon_size_change_notify (toolbar); + } + else + g_object_set_data (G_OBJECT (toolbar), "gtk-toolbar-settings", NULL); +} + +static void +gtk_toolbar_hierarchy_changed (GtkWidget *widget, + GtkWidget *previous_toplevel) +{ + GtkWidget *toplevel; + + if (previous_toplevel) + g_signal_handlers_disconnect_by_func (previous_toplevel, + (gpointer) toolbar_screen_changed, + widget); + + toplevel = gtk_widget_get_toplevel (widget); + if (GTK_WIDGET_TOPLEVEL (toplevel)) + g_signal_connect_swapped (toplevel, + "notify::screen", + G_CALLBACK (toolbar_screen_changed), + widget); + + toolbar_screen_changed (GTK_TOOLBAR (widget)); +} + +static void gtk_toolbar_init (GtkToolbar *toolbar) { GTK_WIDGET_SET_FLAGS (toolbar, GTK_NO_WINDOW); @@ -348,39 +402,6 @@ gtk_toolbar_init (GtkToolbar *toolbar) toolbar->style_set = FALSE; toolbar->icon_size_set = FALSE; - g_object_get (gtk_settings_get_default (), - "gtk-toolbar-icon-size", - &toolbar->icon_size, - "gtk-toolbar-style", - &toolbar->style, - NULL); - - toolbar->style_set_connection = - g_signal_connect (G_OBJECT (gtk_settings_get_default ()), - "notify::gtk-toolbar-style", - G_CALLBACK (style_change_notify), - toolbar); - - toolbar->icon_size_connection = - g_signal_connect (G_OBJECT (gtk_settings_get_default ()), - "notify::gtk-toolbar-icon-size", - G_CALLBACK (icon_size_change_notify), - toolbar); -} - -static void -gtk_toolbar_finalize (GObject *object) -{ - GtkToolbar *toolbar; - - toolbar = GTK_TOOLBAR (object); - - g_signal_handler_disconnect (G_OBJECT (gtk_settings_get_default ()), - toolbar->style_set_connection); - g_signal_handler_disconnect (G_OBJECT (gtk_settings_get_default ()), - toolbar->icon_size_connection); - - G_OBJECT_CLASS (parent_class)->finalize (object); } static void @@ -1032,9 +1053,9 @@ gtk_toolbar_unset_icon_size (GtkToolbar *toolbar) if (toolbar->icon_size_set) { - g_object_get (gtk_settings_get_default (), - "gtk-toolbar-icon-size", - &size, NULL); + g_object_get (gtk_widget_get_settings (GTK_WIDGET (toolbar)), + "gtk-toolbar-icon-size", &size, + NULL); if (size != toolbar->icon_size) gtk_toolbar_set_icon_size (toolbar, size); @@ -1528,9 +1549,8 @@ gtk_toolbar_unset_style (GtkToolbar *toolbar) if (toolbar->style_set) { - g_object_get (gtk_settings_get_default (), - "gtk-toolbar-style", - &style, + g_object_get (gtk_widget_get_settings (GTK_WIDGET (toolbar)), + "gtk-toolbar-style", &style, NULL); if (style != toolbar->style) diff --git a/gtk/gtktooltips.c b/gtk/gtktooltips.c index 3ed3d27875..6f37438e92 100644 --- a/gtk/gtktooltips.c +++ b/gtk/gtktooltips.c @@ -174,6 +174,8 @@ gtk_tooltips_force_window (GtkTooltips *tooltips) if (!tooltips->tip_window) { tooltips->tip_window = gtk_window_new (GTK_WINDOW_POPUP); + gtk_window_set_screen (GTK_WINDOW (tooltips->tip_window), + gtk_widget_get_screen (tooltips->active_tips_data->widget)); gtk_widget_set_app_paintable (tooltips->tip_window, TRUE); gtk_window_set_policy (GTK_WINDOW (tooltips->tip_window), FALSE, FALSE, TRUE); gtk_widget_set_name (tooltips->tip_window, "gtk-tooltips"); @@ -323,6 +325,7 @@ gtk_tooltips_draw_tips (GtkTooltips *tooltips) gint x, y, w, h, scr_w, scr_h; GtkTooltipsData *data; gboolean keyboard_mode; + GdkScreen *screen; if (!tooltips->tip_window) gtk_tooltips_force_window (tooltips); @@ -335,9 +338,10 @@ gtk_tooltips_draw_tips (GtkTooltips *tooltips) widget = tooltips->active_tips_data->widget; keyboard_mode = get_keyboard_mode (widget); - - scr_w = gdk_screen_width (); - scr_h = gdk_screen_height (); + + screen = gtk_widget_get_screen (widget); + scr_w = gdk_screen_get_width (screen); + scr_h = gdk_screen_get_height (screen); data = tooltips->active_tips_data; @@ -357,7 +361,8 @@ gtk_tooltips_draw_tips (GtkTooltips *tooltips) x += widget->allocation.width / 2; if (!keyboard_mode) - gdk_window_get_pointer (NULL, &x, NULL, NULL); + gdk_window_get_pointer (gdk_screen_get_root_window (screen), + &x, NULL, NULL); x -= (w / 2 + 4); diff --git a/gtk/gtktreeview.c b/gtk/gtktreeview.c index 5a6042327f..4e6cfd482c 100644 --- a/gtk/gtktreeview.c +++ b/gtk/gtktreeview.c @@ -1989,8 +1989,8 @@ gtk_tree_view_button_release_drag_column (GtkWidget *widget, tree_view = GTK_TREE_VIEW (widget); - gdk_pointer_ungrab (GDK_CURRENT_TIME); - gdk_keyboard_ungrab (GDK_CURRENT_TIME); + gdk_display_pointer_ungrab (gtk_widget_get_display (widget), GDK_CURRENT_TIME); + gdk_display_keyboard_ungrab (gtk_widget_get_display (widget), GDK_CURRENT_TIME); /* Move the button back */ g_object_ref (tree_view->priv->drag_column->button); @@ -2052,8 +2052,8 @@ gtk_tree_view_button_release_column_resize (GtkWidget *widget, GTK_TREE_VIEW_UNSET_FLAG (tree_view, GTK_TREE_VIEW_IN_COLUMN_RESIZE); gtk_widget_get_pointer (widget, &x, NULL); gtk_grab_remove (widget); - gdk_pointer_ungrab (event->time); - + gdk_display_pointer_ungrab (gdk_drawable_get_display (event->window), + event->time); return TRUE; } @@ -2345,7 +2345,8 @@ gtk_tree_view_motion_draw_column_motion_arrow (GtkTreeView *tree_view) attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; attributes.width = width; attributes.height = height; - tree_view->priv->drag_highlight_window = gdk_window_new (NULL, &attributes, attributes_mask); + tree_view->priv->drag_highlight_window = gdk_window_new (gtk_widget_get_root_window (widget), + &attributes, attributes_mask); gdk_window_set_user_data (tree_view->priv->drag_highlight_window, GTK_WIDGET (tree_view)); mask = gdk_pixmap_new (tree_view->priv->drag_highlight_window, width, height, 1); @@ -6639,6 +6640,7 @@ _gtk_tree_view_column_start_drag (GtkTreeView *tree_view, GdkEvent send_event; GtkAllocation allocation; gint x, y, width, height; + GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (tree_view)); g_return_if_fail (tree_view->priv->column_drag_info == NULL); @@ -6665,8 +6667,8 @@ _gtk_tree_view_column_start_drag (GtkTreeView *tree_view, gdk_window_set_user_data (tree_view->priv->drag_window, GTK_WIDGET (tree_view)); } - gdk_pointer_ungrab (GDK_CURRENT_TIME); - gdk_keyboard_ungrab (GDK_CURRENT_TIME); + gdk_display_pointer_ungrab (gdk_screen_get_display (screen), GDK_CURRENT_TIME); + gdk_display_keyboard_ungrab (gdk_screen_get_display (screen), GDK_CURRENT_TIME); gtk_grab_remove (column->button); @@ -6680,7 +6682,7 @@ _gtk_tree_view_column_start_drag (GtkTreeView *tree_view, gtk_propagate_event (column->button, &send_event); send_event.button.type = GDK_BUTTON_RELEASE; - send_event.button.window = GDK_ROOT_PARENT (); + send_event.button.window = gdk_screen_get_root_window (screen); send_event.button.send_event = TRUE; send_event.button.time = GDK_CURRENT_TIME; send_event.button.x = -1; @@ -8800,6 +8802,7 @@ gtk_tree_view_real_collapse_row (GtkTreeView *tree_view, gboolean collapse; gint x, y; GList *list; + GdkScreen *screen; if (node->children == NULL) return FALSE; @@ -8945,7 +8948,8 @@ gtk_tree_view_real_collapse_row (GtkTreeView *tree_view, /* now that we've collapsed all rows, we want to try to set the prelight * again. To do this, we fake a motion event and send it to ourselves. */ - if (gdk_window_at_pointer (&x, &y) == tree_view->priv->bin_window) + screen = gdk_drawable_get_screen (tree_view->priv->bin_window); + if (gdk_screen_get_window_at_pointer (screen, &x, &y) == tree_view->priv->bin_window) { GdkEventMotion event; event.window = tree_view->priv->bin_window; @@ -10194,6 +10198,7 @@ gtk_tree_view_search_position_func (GtkTreeView *tree_view, gint tree_x, tree_y; gint tree_width, tree_height; GdkWindow *tree_window = GTK_WIDGET (tree_view)->window; + GdkScreen *screen = gdk_drawable_get_screen (tree_window); GtkRequisition requisition; gtk_widget_realize (search_dialog); @@ -10204,15 +10209,15 @@ gtk_tree_view_search_position_func (GtkTreeView *tree_view, &tree_height); gtk_widget_size_request (search_dialog, &requisition); - if (tree_x + tree_width - requisition.width > gdk_screen_width ()) - x = gdk_screen_width () - requisition.width; + if (tree_x + tree_width - requisition.width > gdk_screen_get_width (screen)) + x = gdk_screen_get_width (screen) - requisition.width; else if (tree_x + tree_width - requisition.width < 0) x = 0; else x = tree_x + tree_width - requisition.width; - if (tree_y + tree_height > gdk_screen_height ()) - y = gdk_screen_height () - requisition.height; + if (tree_y + tree_height > gdk_screen_get_height (screen)) + y = gdk_screen_get_height (screen) - requisition.height; else if (tree_y + tree_height < 0) /* isn't really possible ... */ y = 0; else diff --git a/gtk/gtktreeviewcolumn.c b/gtk/gtktreeviewcolumn.c index 4063a8c214..eb2cc21a9d 100644 --- a/gtk/gtktreeviewcolumn.c +++ b/gtk/gtktreeviewcolumn.c @@ -971,8 +971,8 @@ _gtk_tree_view_column_realize_button (GtkTreeViewColumn *column) GDK_POINTER_MOTION_HINT_MASK | GDK_KEY_PRESS_MASK); attributes_mask = GDK_WA_CURSOR | GDK_WA_X | GDK_WA_Y; - attr.cursor = gdk_cursor_new (GDK_SB_H_DOUBLE_ARROW); - + attr.cursor = gdk_cursor_new_for_screen (gdk_drawable_get_screen (tree_view->priv->header_window), + GDK_SB_H_DOUBLE_ARROW); attr.y = 0; attr.width = TREE_VIEW_DRAG_WIDTH; attr.height = tree_view->priv->header_height; diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c index ecc4a77a81..7e994a8b51 100644 --- a/gtk/gtkwidget.c +++ b/gtk/gtkwidget.c @@ -29,6 +29,7 @@ #include <locale.h> #include "gtkcontainer.h" #include "gtkaccelmap.h" +#include "gtkclipboard.h" #include "gtkiconfactory.h" #include "gtkintl.h" #include "gtkmain.h" @@ -50,6 +51,7 @@ #include "gtkintl.h" #include "gtkaccessible.h" #include "gtktooltips.h" +#include "gtkinvisible.h" #define WIDGET_CLASS(w) GTK_WIDGET_GET_CLASS (w) #define INIT_PATH_SIZE (512) @@ -218,7 +220,6 @@ static void gtk_widget_invalidate_widget_windows (GtkWidget static gpointer parent_class = NULL; static guint widget_signals[LAST_SIGNAL] = { 0 }; static GMemChunk *aux_info_mem_chunk = NULL; -static GdkColormap *default_colormap = NULL; static GtkStyle *gtk_default_style = NULL; static GSList *colormap_stack = NULL; static guint composite_child_stack = 0; @@ -2872,7 +2873,7 @@ gtk_widget_real_mnemonic_activate (GtkWidget *widget, { g_warning ("widget `%s' isn't suitable for mnemonic activation", G_OBJECT_TYPE_NAME (widget)); - gdk_beep (); + gdk_display_beep (gtk_widget_get_display (widget)); } return TRUE; } @@ -3884,7 +3885,7 @@ gtk_widget_ensure_style (GtkWidget *widget) static void gtk_widget_reset_rc_style (GtkWidget *widget) { - GtkStyle *new_style; + GtkStyle *new_style = NULL; gboolean initial_emission; g_return_if_fail (GTK_IS_WIDGET (widget)); @@ -3893,8 +3894,9 @@ gtk_widget_reset_rc_style (GtkWidget *widget) GTK_PRIVATE_UNSET_FLAG (widget, GTK_USER_STYLE); GTK_WIDGET_SET_FLAGS (widget, GTK_RC_STYLE); - - new_style = gtk_rc_get_style (widget); + + if (gtk_widget_has_screen (widget)) + new_style = gtk_rc_get_style (widget); if (!new_style) new_style = gtk_widget_get_default_style (); @@ -4360,10 +4362,18 @@ PangoContext * gtk_widget_get_pango_context (GtkWidget *widget) { PangoContext *context; + GdkScreen *screen; g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL); context = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_pango_context); + if (context) + { + screen = g_object_get_data (G_OBJECT (context), "gdk-pango-screen"); + if (screen && (screen != gtk_widget_get_screen (widget))) + context = NULL; + } + if (!context) { context = gtk_widget_create_pango_context (GTK_WIDGET (widget)); @@ -4391,7 +4401,7 @@ gtk_widget_create_pango_context (GtkWidget *widget) g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL); - context = gdk_pango_context_get (); + context = gdk_pango_context_get_for_screen (gtk_widget_get_screen (widget)); gdk_pango_context_set_colormap (context, gtk_widget_get_colormap (widget)); pango_context_set_base_dir (context, @@ -4581,6 +4591,128 @@ gtk_widget_get_child_visible (GtkWidget *widget) return GTK_WIDGET_CHILD_VISIBLE (widget); } +static GdkScreen * +gtk_widget_get_screen_unchecked (GtkWidget *widget) +{ + GtkWidget *toplevel; + + toplevel = gtk_widget_get_toplevel (widget); + + if (GTK_WIDGET_TOPLEVEL (toplevel)) + { + if (GTK_IS_WINDOW (toplevel)) + return GTK_WINDOW (toplevel)->screen; + else if (GTK_IS_INVISIBLE (toplevel)) + return GTK_INVISIBLE (widget)->screen; + } + + return NULL; +} + +/** + * gtk_widget_get_screen: + * @widget: a #GtkWidget + * + * Get the #GdkScreen from the toplevel window associated with + * this widget. This function can only be called after the widget + * has been added to a widget heirarchy with a #GtkWindow + * at the top. + * + * In general, you should only create screen specific + * resources when a widget has been realized, and you should + * free those resources when the widget is unrealized. + * + * Return value: the #GdkScreen for the toplevel for this widget. + **/ +GdkScreen* +gtk_widget_get_screen (GtkWidget *widget) +{ + GdkScreen *screen; + + g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL); + + screen = gtk_widget_get_screen_unchecked (widget); + + if (screen) + return screen; + else + { +#if 0 + g_warning (G_STRLOC ": Can't get associated screen" + " for a widget unless it is inside a toplevel GtkWindow\n" + " widget type is %s associated top level type is %s", + g_type_name (G_OBJECT_TYPE(G_OBJECT (widget))), + g_type_name (G_OBJECT_TYPE(G_OBJECT (toplevel)))); +#endif + return gdk_get_default_screen (); + } +} + +/** + * gtk_widget_has_screen: + * @widget: a #GtkWidget + * + * Checks whether there is a #GdkScreen is associated with + * this widget. All toplevel widgets have an associated + * screen, and all widgets added into a heirarchy with a toplevel + * window at the top. + * + * Return value: %TRUE if there is a #GdkScreen assoicated + * with the widget. + **/ +gboolean +gtk_widget_has_screen (GtkWidget *widget) +{ + g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE); + + return (gtk_widget_get_screen_unchecked (widget) != NULL); +} + +/** + * gtk_widget_get_display: + * @widget: a #GtkWidget + * + * Get the #GdkDisplay for the toplevel window associated with + * this widget. This function can only be called after the widget + * has been added to a widget hierarchy with a #GtkWindow at the top. + * + * In general, you should only create display specific + * resources when a widget has been realized, and you should + * free those resources when the widget is unrealized. + * + * Return value: the #GdkDisplay for the toplevel for this widget. + **/ +GdkDisplay* +gtk_widget_get_display (GtkWidget *widget) +{ + g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL); + + return gdk_screen_get_display (gtk_widget_get_screen (widget)); +} + +/** + * gtk_widget_get_root_window: + * @widget: a #GtkWidget + * + * Get the root window where this widget is located. This function can + * only be called after the widget has been added to a widget + * heirarchy with #GtkWindow at the top. + * + * The root window is useful for such purposes as creating a popup + * #GdkWindow associated with the window. In general, you should only + * create display specific resources when a widget has been realized, + * and you should free those resources when the widget is unrealized. + * + * Return value: the #GdkWindow root window for the toplevel for this widget. + **/ +GdkWindow* +gtk_widget_get_root_window (GtkWidget *widget) +{ + g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL); + + return gdk_screen_get_root_window (gtk_widget_get_screen (widget)); +} + /** * gtk_widget_get_parent_window: * @widget: a #GtkWidget. @@ -5097,6 +5229,7 @@ GdkColormap* gtk_widget_get_colormap (GtkWidget *widget) { GdkColormap *colormap; + GtkWidget *tmp_widget; g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL); @@ -5108,16 +5241,17 @@ gtk_widget_get_colormap (GtkWidget *widget) return colormap; } - while (widget) + tmp_widget = widget; + while (tmp_widget) { - colormap = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_colormap); + colormap = gtk_object_get_data_by_id (GTK_OBJECT (tmp_widget), quark_colormap); if (colormap) return colormap; - widget = widget->parent; + tmp_widget= tmp_widget->parent; } - return gtk_widget_get_default_colormap (); + return gdk_screen_get_default_colormap (gtk_widget_get_screen (widget)); } /** @@ -5142,13 +5276,19 @@ gtk_widget_get_visual (GtkWidget *widget) * * Gets the settings object holding the settings (global property * settings, RC file information, etc) used for this widget. + * + * Note that this function can only be called when the #GtkWidget + * is attached to a toplevel, since the settings object is specific + * to a particular #GdkScreen. * * Return value: the relevant #GtkSettings object **/ GtkSettings* gtk_widget_get_settings (GtkWidget *widget) { - return gtk_settings_get_default (); + g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL); + + return gtk_settings_get_for_screen (gtk_widget_get_screen (widget)); } /** @@ -5425,14 +5565,7 @@ gtk_widget_set_default_colormap (GdkColormap *colormap) { g_return_if_fail (GDK_IS_COLORMAP (colormap)); - if (default_colormap != colormap) - { - if (default_colormap) - gdk_colormap_unref (default_colormap); - default_colormap = colormap; - if (default_colormap) - gdk_colormap_ref (default_colormap); - } + gdk_screen_set_default_colormap (colormap->screen, colormap); } /** @@ -5445,10 +5578,7 @@ gtk_widget_set_default_colormap (GdkColormap *colormap) GdkColormap* gtk_widget_get_default_colormap (void) { - if (!default_colormap) - gtk_widget_set_default_colormap (gdk_rgb_get_colormap ()); - - return default_colormap; + return gdk_screen_get_default_colormap (gdk_get_default_screen ()); } /** @@ -6487,3 +6617,32 @@ gtk_widget_ref_accessible (AtkImplementor *implementor) g_object_ref (G_OBJECT (accessible)); return accessible; } + +/** + * gtk_widget_get_clipboard: + * @widget: a #GtkWidget + * @selection: a #GdkAtom which identifies the clipboard + * to use. %GDK_SELECTION_CLIPBOARD gives the + * default clipboard. Another common value + * is %GDK_SELECTION_PRIMARY, which gives + * the primary X selection. + * + * Returns the clipboard object for the given selection to + * be used with @widget. @widget must have a #GdkDisplay + * associated with it, so must be attached to a toplevel + * window. + * + * Return value: the appropriate clipboard object. If no + * clipboard already exists, a new one will + * be created. Once a clipboard object has + * been created, it is persistent for all time. + **/ +GtkClipboard * +gtk_widget_get_clipboard (GtkWidget *widget, GdkAtom selection) +{ + g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL); + g_return_val_if_fail (gtk_widget_has_screen (widget), NULL); + + return gtk_clipboard_get_for_display (gtk_widget_get_display (widget), + selection); +} diff --git a/gtk/gtkwidget.h b/gtk/gtkwidget.h index 00c0261670..57d409e8a3 100644 --- a/gtk/gtkwidget.h +++ b/gtk/gtkwidget.h @@ -141,6 +141,7 @@ typedef struct _GtkSelectionData GtkSelectionData; typedef struct _GtkWidgetClass GtkWidgetClass; typedef struct _GtkWidgetAuxInfo GtkWidgetAuxInfo; typedef struct _GtkWidgetShapeInfo GtkWidgetShapeInfo; +typedef struct _GtkClipboard GtkClipboard; typedef void (*GtkCallback) (GtkWidget *widget, gpointer data); @@ -551,6 +552,7 @@ gboolean gtk_widget_get_child_visible (GtkWidget *widget); GtkWidget *gtk_widget_get_parent (GtkWidget *widget); GdkWindow *gtk_widget_get_parent_window (GtkWidget *widget); + gboolean gtk_widget_child_focus (GtkWidget *widget, GtkDirectionType direction); @@ -583,7 +585,13 @@ GtkWidget* gtk_widget_get_ancestor (GtkWidget *widget, GdkColormap* gtk_widget_get_colormap (GtkWidget *widget); GdkVisual* gtk_widget_get_visual (GtkWidget *widget); -GtkSettings* gtk_widget_get_settings (GtkWidget *widget); +GdkScreen * gtk_widget_get_screen (GtkWidget *widget); +gboolean gtk_widget_has_screen (GtkWidget *widget); +GdkDisplay * gtk_widget_get_display (GtkWidget *widget); +GdkWindow * gtk_widget_get_root_window (GtkWidget *widget); +GtkSettings* gtk_widget_get_settings (GtkWidget *widget); +GtkClipboard *gtk_widget_get_clipboard (GtkWidget *widget, + GdkAtom selection); #ifndef GTK_DISABLE_DEPRECATED #define gtk_widget_set_visual(widget,visual) ((void) 0) @@ -704,8 +712,10 @@ void gtk_widget_style_get (GtkWidget *widget, */ void gtk_widget_set_default_colormap (GdkColormap *colormap); GtkStyle* gtk_widget_get_default_style (void); +#ifndef GDK_MULTIHEAD_SAFE GdkColormap* gtk_widget_get_default_colormap (void); GdkVisual* gtk_widget_get_default_visual (void); +#endif /* Functions for setting directionality for widgets */ @@ -755,6 +765,7 @@ void _gtk_widget_propagate_hierarchy_changed (GtkWidget *widget, GdkColormap* _gtk_widget_peek_colormap (void); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c index 0c2e3e4992..e61211c237 100644 --- a/gtk/gtkwindow.c +++ b/gtk/gtkwindow.c @@ -68,6 +68,7 @@ enum { PROP_DEFAULT_HEIGHT, PROP_DESTROY_WITH_PARENT, PROP_ICON, + PROP_SCREEN, LAST_ARG }; @@ -241,9 +242,7 @@ static GHashTable *mnemonic_hash_table = NULL; static GtkBinClass *parent_class = NULL; static guint window_signals[LAST_SIGNAL] = { 0 }; static GList *default_icon_list = NULL; -/* FIXME need to be per-screen */ -static GdkPixmap *default_icon_pixmap = NULL; -static GdkPixmap *default_icon_mask = NULL; +static guint default_icon_serial = 0; static void gtk_window_set_property (GObject *object, guint prop_id, @@ -496,6 +495,14 @@ gtk_window_class_init (GtkWindowClass *klass) GDK_TYPE_PIXBUF, G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, + PROP_SCREEN, + g_param_spec_object ("screen", + _("Screen"), + _("The screen where this window will be displayed."), + GDK_TYPE_SCREEN, + G_PARAM_READWRITE)); + window_signals[SET_FOCUS] = g_signal_new ("set_focus", G_TYPE_FROM_CLASS (object_class), @@ -623,6 +630,7 @@ gtk_window_init (GtkWindow *window) window->gravity = GDK_GRAVITY_NORTH_WEST; window->decorated = TRUE; window->mnemonic_modifier = GDK_MOD1_MASK; + window->screen = gdk_get_default_screen (); colormap = _gtk_widget_peek_colormap (); if (colormap) @@ -696,7 +704,9 @@ gtk_window_set_property (GObject *object, gtk_window_set_icon (window, g_value_get_object (value)); break; - + case PROP_SCREEN: + gtk_window_set_screen (window, g_value_get_object (value)); + break; default: break; } @@ -756,6 +766,9 @@ gtk_window_get_property (GObject *object, case PROP_ICON: g_value_set_object (value, gtk_window_get_icon (window)); break; + case PROP_SCREEN: + g_value_set_object (value, window->screen); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1665,6 +1678,8 @@ gtk_window_set_transient_for (GtkWindow *window, gtk_signal_connect (GTK_OBJECT (parent), "unrealize", GTK_SIGNAL_FUNC (gtk_window_transient_parent_unrealized), window); + + window->screen = parent->screen; if (window->destroy_with_parent) connect_parent_destroyed (window); @@ -1950,33 +1965,72 @@ ensure_icon_info (GtkWindow *window) return info; } +typedef struct { + guint serial; + GdkPixmap *pixmap; + GdkPixmap *mask; +} ScreenIconInfo; + +ScreenIconInfo * +get_screen_icon_info (GdkScreen *screen) +{ + ScreenIconInfo *info = g_object_get_data (G_OBJECT (screen), + "gtk-window-default-icon-pixmap"); + if (!info) + { + info = g_new0 (ScreenIconInfo, 1); + g_object_set_data (G_OBJECT (screen), "gtk-window-default-icon-pixmap", info); + } + + if (info->serial != default_icon_serial) + { + if (info->pixmap) + { + g_object_remove_weak_pointer (G_OBJECT (info->pixmap), (gpointer*)&info->pixmap); + info->pixmap = NULL; + } + + if (info->mask) + { + g_object_remove_weak_pointer (G_OBJECT (info->mask), (gpointer*)&info->mask); + info->mask = NULL; + } + + info->serial = default_icon_serial; + } + + return info; +} + static void -get_pixmap_and_mask (GtkWindowIconInfo *parent_info, +get_pixmap_and_mask (GdkWindow *window, + GtkWindowIconInfo *parent_info, gboolean is_default_list, GList *icon_list, GdkPixmap **pmap_return, GdkBitmap **mask_return) { + GdkScreen *screen = gdk_drawable_get_screen (window); + ScreenIconInfo *default_icon_info = get_screen_icon_info (screen); GdkPixbuf *best_icon; GList *tmp_list; int best_size; - + *pmap_return = NULL; *mask_return = NULL; if (is_default_list && - default_icon_pixmap != NULL) + default_icon_info->pixmap != NULL) { - /* Use shared icon pixmap (eventually will be stored on the - * GdkScreen) + /* Use shared icon pixmap for all windows on this screen. */ - if (default_icon_pixmap) - g_object_ref (G_OBJECT (default_icon_pixmap)); - if (default_icon_mask) - g_object_ref (G_OBJECT (default_icon_mask)); - - *pmap_return = default_icon_pixmap; - *mask_return = default_icon_mask; + if (default_icon_info->pixmap) + g_object_ref (G_OBJECT (default_icon_info->pixmap)); + if (default_icon_info->mask) + g_object_ref (G_OBJECT (default_icon_info->mask)); + + *pmap_return = default_icon_info->pixmap; + *mask_return = default_icon_info->mask; } else if (parent_info && parent_info->icon_pixmap) { @@ -2030,7 +2084,7 @@ get_pixmap_and_mask (GtkWindowIconInfo *parent_info, if (best_icon) gdk_pixbuf_render_pixmap_and_mask_for_colormap (best_icon, - gdk_colormap_get_system (), + gdk_screen_get_system_colormap (screen), pmap_return, mask_return, 128); @@ -2048,15 +2102,15 @@ get_pixmap_and_mask (GtkWindowIconInfo *parent_info, } else if (is_default_list) { - default_icon_pixmap = *pmap_return; - default_icon_mask = *mask_return; - - if (default_icon_pixmap) - g_object_add_weak_pointer (G_OBJECT (default_icon_pixmap), - (gpointer*)&default_icon_pixmap); - if (default_icon_mask) - g_object_add_weak_pointer (G_OBJECT (default_icon_mask), - (gpointer*)&default_icon_mask); + default_icon_info->pixmap = *pmap_return; + default_icon_info->mask = *mask_return; + + if (default_icon_info->pixmap) + g_object_add_weak_pointer (G_OBJECT (default_icon_info->pixmap), + (gpointer*)&default_icon_info->pixmap); + if (default_icon_info->mask) + g_object_add_weak_pointer (G_OBJECT (default_icon_info->mask), + (gpointer*)&default_icon_info->mask); } } } @@ -2109,8 +2163,8 @@ gtk_window_realize_icon (GtkWindow *window) gdk_window_set_icon_list (widget->window, icon_list); - get_pixmap_and_mask (info->using_parent_icon ? - ensure_icon_info (window->transient_parent) : NULL, + get_pixmap_and_mask (widget->window, + info->using_parent_icon ? ensure_icon_info (window->transient_parent) : NULL, info->using_default_icon, icon_list, &info->icon_pixmap, @@ -2329,13 +2383,9 @@ gtk_window_set_default_icon_list (GList *list) if (list == default_icon_list) return; - if (default_icon_pixmap) - g_object_unref (G_OBJECT (default_icon_pixmap)); - if (default_icon_mask) - g_object_unref (G_OBJECT (default_icon_mask)); - - default_icon_pixmap = NULL; - default_icon_mask = NULL; + /* Update serial so we don't used cached pixmaps/masks + */ + default_icon_serial++; g_list_foreach (default_icon_list, (GFunc) g_object_unref, NULL); @@ -3250,7 +3300,9 @@ gtk_window_realize (GtkWidget *widget) attributes_mask = GDK_WA_VISUAL | GDK_WA_COLORMAP; - window->frame = gdk_window_new (NULL, &attributes, attributes_mask); + window->frame = gdk_window_new (gtk_widget_get_root_window (widget), + &attributes, attributes_mask); + gdk_window_set_user_data (window->frame, widget); attributes.window_type = GDK_WINDOW_CHILD; @@ -3264,7 +3316,7 @@ gtk_window_realize (GtkWidget *widget) else { attributes_mask = 0; - parent_window = NULL; + parent_window = gtk_widget_get_root_window (widget); } attributes.width = widget->allocation.width; @@ -3281,7 +3333,9 @@ gtk_window_realize (GtkWidget *widget) attributes_mask |= GDK_WA_VISUAL | GDK_WA_COLORMAP; attributes_mask |= (window->title ? GDK_WA_TITLE : 0); attributes_mask |= (window->wmclass_name ? GDK_WA_WMCLASS : 0); + widget->window = gdk_window_new (parent_window, &attributes, attributes_mask); + gdk_window_set_user_data (widget->window, window); widget->style = gtk_style_attach (widget->style, widget->window); @@ -3759,12 +3813,12 @@ gtk_window_read_rcfiles (GtkWidget *widget, while (embedded_windows) { guint xid = GPOINTER_TO_UINT (embedded_windows->data); - gdk_event_send_client_message ((GdkEvent *) &sev, xid); + gdk_event_send_client_message_for_display (gtk_widget_get_display (widget), (GdkEvent *) &sev, xid); embedded_windows = embedded_windows->next; } } - gtk_rc_reparse_all (); + gtk_rc_reparse_all_for_settings (gtk_widget_get_settings (widget), FALSE); } static gint @@ -4039,11 +4093,20 @@ gtk_window_compute_configure_request (GtkWindow *window, case GTK_WIN_POS_CENTER_ALWAYS: case GTK_WIN_POS_CENTER: { - gint screen_width = gdk_screen_width (); - gint screen_height = gdk_screen_height (); - - x = (screen_width - w) / 2; - y = (screen_height - h) / 2; + gint px, py, monitor_num; + GdkRectangle *monitor; + + gdk_window_get_pointer (gdk_screen_get_root_window (window->screen), + &px, &py, NULL); + + monitor_num = gdk_screen_get_monitor_at_point (window->screen, px, py); + if (monitor_num == -1) + monitor_num = 0; + + monitor = gdk_screen_get_monitor_geometry (window->screen, monitor_num); + + x = (monitor->width - w) / 2 + monitor->x; + y = (monitor->height - h) / 2 + monitor->y; } break; @@ -4063,8 +4126,8 @@ gtk_window_compute_configure_request (GtkWindow *window, case GTK_WIN_POS_MOUSE: { - gint screen_width = gdk_screen_width (); - gint screen_height = gdk_screen_height (); + gint screen_width = gdk_screen_get_width (window->screen); + gint screen_height = gdk_screen_get_height (window->screen); int px, py; gdk_window_get_pointer (NULL, &px, &py, NULL); @@ -4112,8 +4175,8 @@ gtk_window_constrain_position (GtkWindow *window, if (window->position == GTK_WIN_POS_CENTER_ALWAYS) { gint center_x, center_y; - gint screen_width = gdk_screen_width (); - gint screen_height = gdk_screen_height (); + gint screen_width = gdk_screen_get_width (window->screen); + gint screen_height = gdk_screen_get_height (window->screen); center_x = (screen_width - new_width) / 2; center_y = (screen_height - new_height) / 2; @@ -4344,7 +4407,7 @@ gtk_window_move_resize (GtkWindow *window) gdk_window_set_geometry_hints (widget->window, &new_geometry, new_flags); - + /* handle resizing/moving and widget tree allocation */ if (window->configure_notify_received) @@ -4437,13 +4500,14 @@ gtk_window_move_resize (GtkWindow *window) new_request.y - window->frame_top, new_request.width + window->frame_left + window->frame_right, new_request.height + window->frame_top + window->frame_bottom); - gdk_window_resize (GTK_WIDGET (window)->window, + gdk_window_resize (widget->window, new_request.width, new_request.height); } else - gdk_window_move_resize (widget->window, - new_request.x, new_request.y, - new_request.width, new_request.height); + if (widget->window) + gdk_window_move_resize (widget->window, + new_request.x, new_request.y, + new_request.width, new_request.height); } else /* only size changed */ { @@ -4451,8 +4515,9 @@ gtk_window_move_resize (GtkWindow *window) gdk_window_resize (window->frame, new_request.width + window->frame_left + window->frame_right, new_request.height + window->frame_top + window->frame_bottom); - gdk_window_resize (widget->window, - new_request.width, new_request.height); + if (widget->window) + gdk_window_resize (widget->window, + new_request.width, new_request.height); } /* Increment the number of have-not-yet-received-notify requests */ @@ -5316,6 +5381,47 @@ gtk_window_begin_move_drag (GtkWindow *window, timestamp); } +/** + * gtk_window_set_screen: + * @window: a #GtkWindow. + * @screen: a #GtkScreen. + * + * Sets the #GdkScreen where the @window will be displayed. + * This function has to be called before the @window + * object is realized otherwise it will fail. + */ +void +gtk_window_set_screen (GtkWindow *window, + GdkScreen *screen) +{ + g_return_if_fail (GTK_IS_WINDOW (window)); + g_return_if_fail (GDK_IS_SCREEN (screen)); + + if (GTK_WIDGET_REALIZED (window)) + { + g_warning ("Trying to change the window's screen while widget is visible"); + return; + } + + gtk_window_free_key_hash (window); + window->screen = screen; +} +/** + * gtk_window_get_screen: + * @window: a #GtkWindow. + * + * Returns the #GdkScreen associated with @window. + * + * Return value: a #GdkScreen. + */ +GdkScreen* +gtk_window_get_screen (GtkWindow *window) +{ + g_return_val_if_fail (GTK_IS_WINDOW (window), NULL); + + return window->screen; +} + static void gtk_window_group_class_init (GtkWindowGroupClass *klass) @@ -5710,11 +5816,11 @@ gtk_window_parse_geometry (GtkWindow *window, if (grav == GDK_GRAVITY_SOUTH_WEST || grav == GDK_GRAVITY_SOUTH_EAST) - y = gdk_screen_height () - h + y; + y = gdk_screen_get_height (window->screen) - h + y; if (grav == GDK_GRAVITY_SOUTH_EAST || grav == GDK_GRAVITY_NORTH_EAST) - x = gdk_screen_width () - w + x; + x = gdk_screen_get_width (window->screen) - w + x; /* we don't let you put a window offscreen; maybe some people would * prefer to be able to, but it's kind of a bogus thing to do. @@ -5857,7 +5963,8 @@ gtk_window_get_key_hash (GtkWindow *window) if (key_hash) return key_hash; - key_hash = _gtk_key_hash_new (gdk_keymap_get_default(), (GDestroyNotify)g_free); + key_hash = _gtk_key_hash_new (gdk_keymap_get_for_display (gdk_screen_get_display (window->screen)), + (GDestroyNotify)g_free); _gtk_window_keys_foreach (window, add_to_key_hash, key_hash); g_object_set_data (G_OBJECT (window), "gtk-window-key-hash", key_hash); diff --git a/gtk/gtkwindow.h b/gtk/gtkwindow.h index c8e79474b4..0251131be3 100644 --- a/gtk/gtkwindow.h +++ b/gtk/gtkwindow.h @@ -108,7 +108,7 @@ struct _GtkWindow guint keys_changed_handler; GdkModifierType mnemonic_modifier; - gpointer gtk_reserved1; /* For future GdkScreen * */ + GdkScreen *screen; }; struct _GtkWindowClass @@ -210,6 +210,10 @@ void gtk_window_set_geometry_hints (GtkWindow *window, GdkGeometry *geometry, GdkWindowHints geom_mask); +void gtk_window_set_screen (GtkWindow *window, + GdkScreen *screen); +GdkScreen* gtk_window_get_screen (GtkWindow *window); + /* gtk_window_set_has_frame () must be called before realizing the window_*/ void gtk_window_set_has_frame (GtkWindow *window, gboolean setting); |