Commit b9d1a034 authored by Søren Sandmann's avatar Søren Sandmann Committed by Søren Sandmann Pedersen

Create 'composited' label.

Tue Apr 25 10:25:28 2006  Søren Sandmann  <sandmann@redhat.com>

	* tests/testgtk.c (create_alpha_window): Create 'composited' label.

	* tests/testgtk.c (on_composited_changed): New function, change
	the label to say whether the screen is composited or not.

	* gtk/gtkwindow.c (gtk_window_on_composited_changed): When
	composited status change, invalidate the window and propagate the signal;.

	* gtk/gtkwindow.c (gtk_window_map): Set the appropriate type hint
	if reset_type_hint is TRUE.

	* gtk/gtkwindow.c (gtk_window_set_type_hint): If hint is one of
	the old hints, store a shadow copy in the public window->type_hint
	bitfield, otherwise set this field to normal. Set the private
	field to the type hint.

	* gtk/gtkwindow.c (gtk_window_init): Initialize priv->type_hint.

	* gtk/gtkwindow.c (struct _GtkWindowPrivate): New field
	"reset_type_hint" indicating whether the type hint needs to be
	reset. New field type_hint containing a GdkWindowTypeHint.

	* gtk/gtkwidget.c (propagate_composited_changed): New function to
	propagate changes in composited status.
	(gtk_widget_class_init): Add composited_changed signal.

	* gtk/gtkwidget.h (struct _GtkWidgetClass): New signal composited-changed.

	* gtk/gtkwidget.c (gtk_widget_is_composited): New function.

	* gtk/gtktooltips.c (gtk_tooltips_draw_tips): Set transient for.

	* gtk/gtktooltips.c (gtk_tooltips_force_window): Set the type hint

	* gtk/gtkmenuitem.c (gtk_menu_item_position_menu): Compute whether
	the item belongs to a menubar. Set the type_hint appropriately
	depending on the outcome.

	* gtk/gtkmenu.c (gtk_menu_position): Set the default type hint here.

	* gtk/gtkmenu.c (gtk_menu_attach_to_widget): connect to hierarchy
	changed on the attach widget.

	* gtk/gtkmenu.c (attach_widget_hierarchy_changed): New function to
	set the transient_for property for menus.

	* gtk/gtkdnd.c (set_icon_stock_pixbuf): Set the appropriate type hint.

	* gtk/gtkcombo.c (gtk_combo_popup_list): Make the popup window
	transient for the toplevel.

	* gtk/gtkcombobox.c (gtk_combo_box_set_popup_widget): Set
	transient-for, for the popup window.

	* gdk/x11/gdkwindow-x11.c (gdk_window_get_type_hint): Support for
	new window types.

	* gdk/x11/gdkwindow-x11.c (gdk_window_set_type_hint): Add support
	for new window types.

	* gdk/x11/gdkscreen-x11.c (_gdk_x11_screen_process_owner_change):
	New function called whenever the compositing manager comes and goes.

	* gdk/x11/gdkscreen-x11.c (gdk_screen_is_composited): New function.

	* gdk/x11/gdkscreen-x11.c
	(_gdk_x11_screen_request_cm_notification, make_cm_atom,
	check_is_composited): New functions

	* gdk/x11/gdkevents-x11.c (gdk_event_translate): Call
	_gdk_x11_screen_process_owner_change when an
	XFixesSelectionNotifyEvent is received.

	* gdk/x11/gdkdisplay-x11.c (gdk_display_open): Call
	_gdk_x11_screen_request_cm_notification() on all screens.

	* gdk/quartz/gdkscreen-quartz.c (gdk_screen_is_composited): Dummy
	implementation.

	* gdk/gdkscreen.c (gdk_screen_class_init): New signal,
	'composited-changed'.

	* gdk/gdkwindow.h: Add new EWMH window types.

	* gdk/win32/gdkscreen-win32.c (gdk_screen_is_composited)
parent 33a8d113
Tue Apr 25 10:25:28 2006 Søren Sandmann <sandmann@redhat.com>
* tests/testgtk.c (create_alpha_window): Create 'composited' label.
* tests/testgtk.c (on_composited_changed): New function, change
the label to say whether the screen is composited or not.
* gtk/gtkwindow.c (gtk_window_on_composited_changed): When
composited status change, invalidate the window and propagate the signal;.
* gtk/gtkwindow.c (gtk_window_map): Set the appropriate type hint
if reset_type_hint is TRUE.
* gtk/gtkwindow.c (gtk_window_set_type_hint): If hint is one of
the old hints, store a shadow copy in the public window->type_hint
bitfield, otherwise set this field to normal. Set the private
field to the type hint.
* gtk/gtkwindow.c (gtk_window_init): Initialize priv->type_hint.
* gtk/gtkwindow.c (struct _GtkWindowPrivate): New field
"reset_type_hint" indicating whether the type hint needs to be
reset. New field type_hint containing a GdkWindowTypeHint.
* gtk/gtkwidget.c (propagate_composited_changed): New function to
propagate changes in composited status.
(gtk_widget_class_init): Add composited_changed signal.
* gtk/gtkwidget.h (struct _GtkWidgetClass): New signal composited-changed.
* gtk/gtkwidget.c (gtk_widget_is_composited): New function.
* gtk/gtktooltips.c (gtk_tooltips_draw_tips): Set transient for.
* gtk/gtktooltips.c (gtk_tooltips_force_window): Set the type hint
* gtk/gtkmenuitem.c (gtk_menu_item_position_menu): Compute whether
the item belongs to a menubar. Set the type_hint appropriately
depending on the outcome.
* gtk/gtkmenu.c (gtk_menu_position): Set the default type hint here.
* gtk/gtkmenu.c (gtk_menu_attach_to_widget): connect to hierarchy
changed on the attach widget.
* gtk/gtkmenu.c (attach_widget_hierarchy_changed): New function to
set the transient_for property for menus.
* gtk/gtkdnd.c (set_icon_stock_pixbuf): Set the appropriate type hint.
* gtk/gtkcombo.c (gtk_combo_popup_list): Make the popup window
transient for the toplevel.
* gtk/gtkcombobox.c (gtk_combo_box_set_popup_widget): Set
transient-for, for the popup window.
* gdk/x11/gdkwindow-x11.c (gdk_window_get_type_hint): Support for
new window types.
* gdk/x11/gdkwindow-x11.c (gdk_window_set_type_hint): Add support
for new window types.
* gdk/x11/gdkscreen-x11.c (_gdk_x11_screen_process_owner_change):
New function called whenever the compositing manager comes and goes.
* gdk/x11/gdkscreen-x11.c (gdk_screen_is_composited): New function.
* gdk/x11/gdkscreen-x11.c
(_gdk_x11_screen_request_cm_notification, make_cm_atom,
check_is_composited): New functions
* gdk/x11/gdkevents-x11.c (gdk_event_translate): Call
_gdk_x11_screen_process_owner_change when an
XFixesSelectionNotifyEvent is received.
* gdk/x11/gdkdisplay-x11.c (gdk_display_open): Call
_gdk_x11_screen_request_cm_notification() on all screens.
* gdk/quartz/gdkscreen-quartz.c (gdk_screen_is_composited): Dummy
implementation.
* gdk/gdkscreen.c (gdk_screen_class_init): New signal,
'composited-changed'.
* gdk/gdkwindow.h: Add new EWMH window types.
* gdk/win32/gdkscreen-win32.c (gdk_screen_is_composited)
2006-04-25 Matthias Clasen <mclasen@redhat.com>
* modules/printbackends/cups/gtkprintbackendcups.c:
......@@ -40,6 +128,7 @@
* gtk/gtkprinter.c:
Don't ref the backend since the backend owns the printer.
>>>>>>> 1.7779
2006-04-24 Alexander Larsson <alexl@redhat.com>
* gtk/gtkpagesetupunixdialog.c (update_combo_sensitivity_from_printers):
......
Tue Apr 25 10:25:28 2006 Søren Sandmann <sandmann@redhat.com>
* tests/testgtk.c (create_alpha_window): Create 'composited' label.
* tests/testgtk.c (on_composited_changed): New function, change
the label to say whether the screen is composited or not.
* gtk/gtkwindow.c (gtk_window_on_composited_changed): When
composited status change, invalidate the window and propagate the signal;.
* gtk/gtkwindow.c (gtk_window_map): Set the appropriate type hint
if reset_type_hint is TRUE.
* gtk/gtkwindow.c (gtk_window_set_type_hint): If hint is one of
the old hints, store a shadow copy in the public window->type_hint
bitfield, otherwise set this field to normal. Set the private
field to the type hint.
* gtk/gtkwindow.c (gtk_window_init): Initialize priv->type_hint.
* gtk/gtkwindow.c (struct _GtkWindowPrivate): New field
"reset_type_hint" indicating whether the type hint needs to be
reset. New field type_hint containing a GdkWindowTypeHint.
* gtk/gtkwidget.c (propagate_composited_changed): New function to
propagate changes in composited status.
(gtk_widget_class_init): Add composited_changed signal.
* gtk/gtkwidget.h (struct _GtkWidgetClass): New signal composited-changed.
* gtk/gtkwidget.c (gtk_widget_is_composited): New function.
* gtk/gtktooltips.c (gtk_tooltips_draw_tips): Set transient for.
* gtk/gtktooltips.c (gtk_tooltips_force_window): Set the type hint
* gtk/gtkmenuitem.c (gtk_menu_item_position_menu): Compute whether
the item belongs to a menubar. Set the type_hint appropriately
depending on the outcome.
* gtk/gtkmenu.c (gtk_menu_position): Set the default type hint here.
* gtk/gtkmenu.c (gtk_menu_attach_to_widget): connect to hierarchy
changed on the attach widget.
* gtk/gtkmenu.c (attach_widget_hierarchy_changed): New function to
set the transient_for property for menus.
* gtk/gtkdnd.c (set_icon_stock_pixbuf): Set the appropriate type hint.
* gtk/gtkcombo.c (gtk_combo_popup_list): Make the popup window
transient for the toplevel.
* gtk/gtkcombobox.c (gtk_combo_box_set_popup_widget): Set
transient-for, for the popup window.
* gdk/x11/gdkwindow-x11.c (gdk_window_get_type_hint): Support for
new window types.
* gdk/x11/gdkwindow-x11.c (gdk_window_set_type_hint): Add support
for new window types.
* gdk/x11/gdkscreen-x11.c (_gdk_x11_screen_process_owner_change):
New function called whenever the compositing manager comes and goes.
* gdk/x11/gdkscreen-x11.c (gdk_screen_is_composited): New function.
* gdk/x11/gdkscreen-x11.c
(_gdk_x11_screen_request_cm_notification, make_cm_atom,
check_is_composited): New functions
* gdk/x11/gdkevents-x11.c (gdk_event_translate): Call
_gdk_x11_screen_process_owner_change when an
XFixesSelectionNotifyEvent is received.
* gdk/x11/gdkdisplay-x11.c (gdk_display_open): Call
_gdk_x11_screen_request_cm_notification() on all screens.
* gdk/quartz/gdkscreen-quartz.c (gdk_screen_is_composited): Dummy
implementation.
* gdk/gdkscreen.c (gdk_screen_class_init): New signal,
'composited-changed'.
* gdk/gdkwindow.h: Add new EWMH window types.
* gdk/win32/gdkscreen-win32.c (gdk_screen_is_composited)
2006-04-25 Matthias Clasen <mclasen@redhat.com>
* modules/printbackends/cups/gtkprintbackendcups.c:
......@@ -40,6 +128,7 @@
* gtk/gtkprinter.c:
Don't ref the backend since the backend owns the printer.
>>>>>>> 1.7779
2006-04-24 Alexander Larsson <alexl@redhat.com>
* gtk/gtkpagesetupunixdialog.c (update_combo_sensitivity_from_printers):
......
......@@ -50,6 +50,7 @@ enum
enum
{
SIZE_CHANGED,
COMPOSITED_CHANGED,
LAST_SIGNAL
};
......@@ -104,6 +105,25 @@ gdk_screen_class_init (GdkScreenClass *klass)
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE,
0);
/**
* GdkScreen::composited-changed:
* @screen: the object on which the signal is emitted
*
* The ::composited_changed signal is emitted when the composited
* status of the screen changes
*
* Since: 2.10
*/
signals[COMPOSITED_CHANGED] =
g_signal_new (g_intern_static_string ("composited_changed"),
G_OBJECT_CLASS_TYPE (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GdkScreenClass, composited_changed),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE,
0);
}
static void
......
......@@ -57,6 +57,7 @@ struct _GdkScreenClass
GObjectClass parent_class;
void (*size_changed) (GdkScreen *screen);
void (*composited_changed) (GdkScreen *screen);
};
GType gdk_screen_get_type (void) G_GNUC_CONST;
......@@ -69,7 +70,7 @@ GdkColormap *gdk_screen_get_rgb_colormap (GdkScreen *screen);
GdkVisual * gdk_screen_get_rgb_visual (GdkScreen *screen);
GdkColormap *gdk_screen_get_rgba_colormap (GdkScreen *screen);
GdkVisual * gdk_screen_get_rgba_visual (GdkScreen *screen);
gboolean gdk_screen_is_composited (GdkScreen *screen);
GdkWindow * gdk_screen_get_root_window (GdkScreen *screen);
GdkDisplay * gdk_screen_get_display (GdkScreen *screen);
......
......@@ -127,15 +127,20 @@ typedef enum
{
GDK_WINDOW_TYPE_HINT_NORMAL,
GDK_WINDOW_TYPE_HINT_DIALOG,
GDK_WINDOW_TYPE_HINT_MENU,
GDK_WINDOW_TYPE_HINT_MENU, /* Torn off menu */
GDK_WINDOW_TYPE_HINT_TOOLBAR,
GDK_WINDOW_TYPE_HINT_SPLASHSCREEN,
GDK_WINDOW_TYPE_HINT_UTILITY,
GDK_WINDOW_TYPE_HINT_DOCK,
GDK_WINDOW_TYPE_HINT_DESKTOP
GDK_WINDOW_TYPE_HINT_DESKTOP,
GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU, /* A drop down menu (from a menubar) */
GDK_WINDOW_TYPE_HINT_POPUP_MENU, /* A popup menu (from right-click) */
GDK_WINDOW_TYPE_HINT_TOOLTIP,
GDK_WINDOW_TYPE_HINT_NOTIFICATION,
GDK_WINDOW_TYPE_HINT_COMBO,
GDK_WINDOW_TYPE_HINT_DND
} GdkWindowTypeHint;
/* The next two enumeration values current match the
* Motif constants. If this is changed, the implementation
* of gdk_window_set_decorations/gdk_window_set_functions
......
......@@ -255,3 +255,11 @@ gdk_screen_get_window_stack (GdkScreen *screen)
return NULL;
}
gboolean
gdk_screen_is_composited (GdkScreen *screen)
{
g_return_val_if_fail (GDK_IS_SCREEN (screen), FALSE);
return TRUE;
}
......@@ -133,3 +133,11 @@ gdk_screen_get_window_stack (GdkScreen *screen)
return NULL;
}
gboolean
gdk_screen_is_composited (GdkScreen *screen)
{
g_return_val_if_fail (GDK_IS_SCREEN (screen), FALSE);
return FALSE;
}
......@@ -77,6 +77,7 @@ static const char *const precache_atoms[] = {
"WM_LOCALE_NAME",
"WM_PROTOCOLS",
"WM_TAKE_FOCUS",
"_NET_WM_CM_S0",
"_NET_WM_DESKTOP",
"_NET_WM_ICON",
"_NET_WM_ICON_NAME",
......@@ -311,6 +312,9 @@ gdk_display_open (const gchar *display_name)
_gdk_input_init (display);
_gdk_dnd_init (display);
for (i = 0; i < ScreenCount (display_x11->xdisplay); i++)
_gdk_x11_screen_request_cm_notification (display_x11->screens[i]);
g_signal_emit_by_name (gdk_display_manager_get(),
"display_opened", display);
......@@ -1102,8 +1106,9 @@ gdk_display_supports_selection_notification (GdkDisplay *display)
*
* Since: 2.6
**/
gboolean gdk_display_request_selection_notification (GdkDisplay *display,
GdkAtom selection)
gboolean
gdk_display_request_selection_notification (GdkDisplay *display,
GdkAtom selection)
{
#ifdef HAVE_XFIXES
......
......@@ -2077,6 +2077,9 @@ gdk_event_translate (GdkDisplay *display,
if (xevent->type - display_x11->xfixes_event_base == XFixesSelectionNotify)
{
XFixesSelectionNotifyEvent *selection_notify = (XFixesSelectionNotifyEvent *)xevent;
_gdk_x11_screen_process_owner_change (screen, xevent);
event->owner_change.type = GDK_OWNER_CHANGE;
event->owner_change.window = window;
event->owner_change.owner = selection_notify->owner;
......@@ -2086,7 +2089,7 @@ gdk_event_translate (GdkDisplay *display,
selection_notify->selection);
event->owner_change.time = selection_notify->timestamp;
event->owner_change.selection_time = selection_notify->selection_timestamp;
return_val = TRUE;
}
else
......
......@@ -47,6 +47,10 @@
#include <X11/extensions/Xrandr.h>
#endif
#ifdef HAVE_XFIXES
#include <X11/extensions/Xfixes.h>
#endif
static void gdk_screen_x11_dispose (GObject *object);
static void gdk_screen_x11_finalize (GObject *object);
static void init_xinerama_support (GdkScreen *screen);
......@@ -460,6 +464,27 @@ gdk_x11_screen_get_screen_number (GdkScreen *screen)
return GDK_SCREEN_X11 (screen)->screen_num;
}
static gboolean
check_is_composited (GdkDisplay *display,
GdkScreenX11 *screen_x11)
{
Atom xselection = gdk_x11_atom_to_xatom_for_display (display, screen_x11->cm_selection_atom);
Window xwindow;
xwindow = XGetSelectionOwner (GDK_DISPLAY_XDISPLAY (display), xselection);
return xwindow != None;
}
static GdkAtom
make_cm_atom (int screen_number)
{
gchar *name = g_strdup_printf ("_NET_WM_CM_S%d", screen_number);
GdkAtom atom = gdk_atom_intern (name, FALSE);
g_free (name);
return atom;
}
GdkScreen *
_gdk_x11_screen_new (GdkDisplay *display,
gint screen_number)
......@@ -479,16 +504,52 @@ _gdk_x11_screen_new (GdkDisplay *display,
screen_x11->wmspec_check_window = None;
/* we want this to be always non-null */
screen_x11->window_manager_name = g_strdup ("unknown");
screen_x11->cm_selection_atom = make_cm_atom (screen_number);
screen_x11->is_composited = check_is_composited (display, screen_x11);
init_xinerama_support (screen);
init_randr_support (screen);
_gdk_visual_init (screen);
_gdk_windowing_window_init (screen);
return screen;
}
void
_gdk_x11_screen_request_cm_notification (GdkScreenX11 *screen_x11)
{
gdk_display_request_selection_notification (screen_x11->display, screen_x11->cm_selection_atom);
}
/**
* gdk_screen_is_composited:
* @screen: a #GdkScreen
*
* Returns whether windows with an RGBA visual can reasonably
* be expected to have their alpha channel drawn correctly on
* the screen.
*
* On X11 this function returns whether a compositing manager is
* compositing @screen.
*
* Return value: Whether windows with RGBA visuals can reasonably be
* expected to have their alpha channels drawn correctly on the screen.
*
* Since: 2.10
**/
gboolean
gdk_screen_is_composited (GdkScreen *screen)
{
GdkScreenX11 *screen_x11;
g_return_val_if_fail (GDK_IS_SCREEN (screen), FALSE);
screen_x11 = GDK_SCREEN_X11 (screen);
return screen_x11->is_composited;
}
#ifdef HAVE_XINERAMA
static gboolean
check_solaris_xinerama (GdkScreen *screen)
......@@ -705,6 +766,28 @@ _gdk_x11_screen_window_manager_changed (GdkScreen *screen)
g_signal_emit (screen, signals[WINDOW_MANAGER_CHANGED], 0);
}
void
_gdk_x11_screen_process_owner_change (GdkScreen *screen,
XEvent *event)
{
XFixesSelectionNotifyEvent *selection_event = (XFixesSelectionNotifyEvent *)event;
GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
Atom xcm_selection_atom = gdk_x11_atom_to_xatom_for_display (screen_x11->display,
screen_x11->cm_selection_atom);
if (selection_event->selection == xcm_selection_atom)
{
gboolean composited = selection_event->owner != None;
if (composited != screen_x11->is_composited)
{
screen_x11->is_composited = composited;
g_signal_emit_by_name (screen, "composited_changed");
}
}
}
/**
* _gdk_windowing_substitute_screen_number:
* @display_name : The name of a display, in the form used by
......
......@@ -103,6 +103,9 @@ struct _GdkScreenX11
gint xft_hintstyle;
gint xft_rgba;
gint xft_dpi;
GdkAtom cm_selection_atom;
gboolean is_composited;
};
struct _GdkScreenX11Class
......@@ -119,6 +122,8 @@ GdkScreen * _gdk_x11_screen_new (GdkDisplay *display,
void _gdk_x11_screen_window_manager_changed (GdkScreen *screen);
void _gdk_x11_screen_size_changed (GdkScreen *screen,
XEvent *event);
void _gdk_x11_screen_process_owner_change (GdkScreen *screen,
XEvent *event);
G_END_DECLS
......
......@@ -2226,6 +2226,24 @@ gdk_window_set_type_hint (GdkWindow *window,
case GDK_WINDOW_TYPE_HINT_DESKTOP:
atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DESKTOP");
break;
case GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU:
atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU");
break;
case GDK_WINDOW_TYPE_HINT_POPUP_MENU:
atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_POPUP_MENU");
break;
case GDK_WINDOW_TYPE_HINT_TOOLTIP:
atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_TOOLTIP");
break;
case GDK_WINDOW_TYPE_HINT_NOTIFICATION:
atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_NOTIFICATION");
break;
case GDK_WINDOW_TYPE_HINT_COMBO:
atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_COMBO");
break;
case GDK_WINDOW_TYPE_HINT_DND:
atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DND");
break;
default:
g_warning ("Unknown hint %d passed to gdk_window_set_type_hint", hint);
/* Fall thru */
......@@ -2295,6 +2313,18 @@ gdk_window_get_type_hint (GdkWindow *window)
type = GDK_WINDOW_TYPE_HINT_DOCK;
else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DESKTOP"))
type = GDK_WINDOW_TYPE_HINT_DESKTOP;
else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU"))
type = GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU;
else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_POPUP_MENU"))
type = GDK_WINDOW_TYPE_HINT_POPUP_MENU;
else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_TOOLTIP"))
type = GDK_WINDOW_TYPE_HINT_TOOLTIP;
else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_NOTIFICATION"))
type = GDK_WINDOW_TYPE_HINT_NOTIFICATION;
else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_COMBO"))
type = GDK_WINDOW_TYPE_HINT_COMBO;
else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DND"))
type = GDK_WINDOW_TYPE_HINT_DND;
}
if (type_return != None && data != NULL)
......
......@@ -564,6 +564,7 @@ gtk_combo_popup_list (GtkCombo *combo)
{
gtk_window_group_add_window (gtk_window_get_group (GTK_WINDOW (toplevel)),
GTK_WINDOW (combo->popwin));
gtk_window_set_transient_for (combo->popwin, GTK_WINDOW (toplevel));
}
gtk_widget_set_size_request (combo->popwin, width, height);
......@@ -941,6 +942,7 @@ gtk_combo_init (GtkCombo * combo)
G_CALLBACK (gtk_combo_popup_button_leave), combo);
combo->popwin = gtk_window_new (GTK_WINDOW_POPUP);
gtk_window_set_type_hint (GTK_WINDOW (combo->popwin), GDK_WINDOW_TYPE_HINT_COMBO);
g_object_ref (combo->popwin);
gtk_window_set_resizable (GTK_WINDOW (combo->popwin), FALSE);
......
......@@ -1220,6 +1220,9 @@ gtk_combo_box_set_popup_widget (GtkComboBox *combo_box,
combo_box->priv->popup_window = gtk_window_new (GTK_WINDOW_POPUP);
gtk_window_set_type_hint (GTK_WINDOW (combo_box->priv->popup_window),
GDK_WINDOW_TYPE_HINT_COMBO);
g_signal_connect (GTK_WINDOW(combo_box->priv->popup_window),"show",
G_CALLBACK (gtk_combo_box_child_show),
combo_box);
......@@ -1229,8 +1232,12 @@ gtk_combo_box_set_popup_widget (GtkComboBox *combo_box,
toplevel = gtk_widget_get_toplevel (GTK_WIDGET (combo_box));
if (GTK_IS_WINDOW (toplevel))
gtk_window_group_add_window (gtk_window_get_group (GTK_WINDOW (toplevel)),
GTK_WINDOW (combo_box->priv->popup_window));
{
gtk_window_group_add_window (gtk_window_get_group (GTK_WINDOW (toplevel)),
GTK_WINDOW (combo_box->priv->popup_window));
gtk_window_set_transient_for (GTK_WINDOW (combo_box->priv->popup_window),
GTK_WINDOW (toplevel));
}
gtk_window_set_resizable (GTK_WINDOW (combo_box->priv->popup_window), FALSE);
gtk_window_set_screen (GTK_WINDOW (combo_box->priv->popup_window),
......
......@@ -2938,6 +2938,7 @@ set_icon_stock_pixbuf (GdkDragContext *context,
/* Push a NULL colormap to guard against gtk_widget_push_colormap() */
gtk_widget_push_colormap (NULL);
window = gtk_window_new (GTK_WINDOW_POPUP);
gtk_window_set_type_hint (GTK_WINDOW (window), GDK_WINDOW_TYPE_HINT_DND);
gtk_window_set_screen (GTK_WINDOW (window), screen);
set_can_change_screen (window, TRUE);
gtk_widget_pop_colormap ();
......@@ -3083,6 +3084,7 @@ gtk_drag_set_icon_pixmap (GdkDragContext *context,
gtk_widget_push_colormap (colormap);
window = gtk_window_new (GTK_WINDOW_POPUP);
gtk_window_set_type_hint (window, GDK_WINDOW_TYPE_HINT_DND);
gtk_window_set_screen (GTK_WINDOW (window), screen);
set_can_change_screen (window, FALSE);
gtk_widget_set_events (window, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
......
......@@ -1036,6 +1036,33 @@ attach_widget_screen_changed (GtkWidget *attach_widget,
}
}
static void
attach_widget_hierarchy_changed (GtkWidget *attach_widget,
GtkWidget *previous_toplevel,
gpointer data)
{
GtkMenu *menu = GTK_MENU (data);
GtkWidget *new_toplevel = gtk_widget_get_toplevel (attach_widget);
if (g_object_get_data (G_OBJECT (menu), "gtk-menu-explicit-screen"))
{
/* If there is an explicit screen set, then don't set WM_TRANSIENT_FOR.
* Because, what would happen if the attach widget moved to a different
* screen on a different display? The menu wouldn't move along with it,
* so we just make it the responsibility of whoever set the screen to
* also set WM_TRANSIENT_FOR.
*/
return;
}
if (menu->toplevel && !g_object_get_data (G_OBJECT (menu), "gtk-menu-explicit-screen") &&
(!new_toplevel || GTK_IS_WINDOW (new_toplevel)))
{
gtk_window_set_transient_for (GTK_WINDOW (menu->toplevel),
GTK_WINDOW (new_toplevel));
}
}
void
gtk_menu_attach_to_widget (GtkMenu *menu,
GtkWidget *attach_widget,
......@@ -1067,6 +1094,10 @@ gtk_menu_attach_to_widget (GtkMenu *menu,
G_CALLBACK (attach_widget_screen_changed), menu);
attach_widget_screen_changed (attach_widget, NULL, menu);
g_signal_connect (attach_widget, "hierarchy_changed",
G_CALLBACK (attach_widget_hierarchy_changed), menu);
attach_widget_hierarchy_changed (attach_widget, NULL, menu);
data->detacher = detacher;
g_object_set_data (G_OBJECT (menu), I_(attach_data_key), data);
list = g_object_steal_data (G_OBJECT (attach_widget), ATTACHED_MENUS);
......@@ -1121,6 +1152,10 @@ gtk_menu_detach (GtkMenu *menu)
g_signal_handlers_disconnect_by_func (data->attach_widget,
(gpointer) attach_widget_screen_changed,
menu);
g_signal_handlers_disconnect_by_func (data->attach_widget,
(gpointer) attach_widget_hierarchy_changed,
menu);
attach_widget_hierarchy_changed (data->attach_widget, NULL, menu);
if (data->detacher)
data->detacher (data->attach_widget, menu);
......@@ -1836,7 +1871,6 @@ gtk_menu_set_tearoff_state (GtkMenu *menu,
"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);
......@@ -3765,6 +3799,10 @@ gtk_menu_position (GtkMenu *menu)
private->monitor_num = gdk_screen_get_monitor_at_point (screen, x, y);
private->initially_pushed_in = FALSE;
/* Set the type hint here to allow custom position functions to set a different hint */
if (!GTK_WIDGET_VISIBLE (menu->toplevel))
gtk_window_set_type_hint (GTK_WINDOW (menu->toplevel), GDK_WINDOW_TYPE_HINT_POPUP_MENU);
if (menu->position_func)
{
......
......@@ -1122,7 +1122,7 @@ gtk_menu_item_position_menu (GtkMenu *menu,
{
GtkMenuItem *menu_item;
GtkWidget *widget;
GtkWidget *parent_menu_item;
GtkMenuItem *parent_menu_item;
GdkScreen *screen;
gint twidth, theight;
gint tx, ty;
......@@ -1164,6 +1164,22 @@ gtk_menu_item_position_menu (GtkMenu *menu,
ty += widget->allocation.y;
get_offsets (menu, &horizontal_offset, &vertical_offset);
if (GTK_IS_MENU_BAR (widget->parent))
{
menu_item->from_menubar = TRUE;
}
else if (GTK_IS_MENU (widget->parent))
{
if (GTK_MENU (widget->parent)->parent_menu_item)
menu_item->from_menubar = GTK_MENU_ITEM (GTK_MENU (widget->parent)->parent_menu_item)->from_menubar;
else
menu_item->from_menubar = FALSE;
}
else
{
menu_item->from_menubar = FALSE;
}
switch (menu_item->submenu_placement)
{
......@@ -1175,7 +1191,6 @@ gtk_menu_item_position_menu (GtkMenu *menu,
menu_item->submenu_direction = GTK_DIRECTION_LEFT;
tx += widget->allocation.width - twidth;
}
if ((ty + widget->allocation.height + theight) <= monitor.y + monitor.height)
ty += widget->allocation.height;
else if ((ty - theight) >= monitor.y)
......@@ -1188,16 +1203,23 @@ gtk_menu_item_position_menu (GtkMenu *menu,
case GTK_LEFT_RIGHT:
if (GTK_IS_MENU (widget->parent))
parent_menu_item = GTK_MENU (widget->parent)->parent_menu_item;
parent_menu_item = GTK_MENU_ITEM (GTK_MENU (widget->parent)->parent_menu_item);
else
parent_menu_item = NULL;
parent_xthickness = widget->parent->style->xthickness;
if (parent_menu_item && !GTK_MENU (widget->parent)->torn_off)
menu_item->submenu_direction = GTK_MENU_ITEM (parent_menu_item)->submenu_direction;
else if (direction == GTK_TEXT_DIR_LTR)
menu_item->submenu_direction = GTK_DIRECTION_RIGHT;
{
menu_item->submenu_direction = parent_menu_item->submenu_direction;
}
else
menu_item->submenu_direction = GTK_DIRECTION_LEFT;
{
if (direction == GTK_TEXT_DIR_LTR)
menu_item->submenu_direction = GTK_DIRECTION_RIGHT;
else
menu_item->submenu_direction = GTK_DIRECTION_LEFT;
}
switch (menu_item->submenu_direction)
{
......@@ -1236,6 +1258,12 @@ gtk_menu_item_position_menu (GtkMenu *menu,
*y = ty;
gtk_menu_set_monitor (menu, monitor_num);
if (!GTK_WIDGET_VISIBLE (menu->toplevel))
{
gtk_window_set_type_hint (GTK_WINDOW (menu->toplevel), menu_item->from_menubar?
GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU : GDK_WINDOW_TYPE_HINT_POPUP_MENU);
}
}
/**
......
......@@ -61,6 +61,7 @@ struct _GtkMenuItem
guint submenu_direction : 1;
guint right_justify: 1;
guint timer_from_keypress : 1;
guint from_menubar : 1;
guint timer;