can_change_screen property for GtkWindow
- From: Owen Taylor <otaylor redhat com>
- To: gtk-devel-list gnome org
- Subject: can_change_screen property for GtkWindow
- Date: Tue, 1 Oct 2002 15:02:58 -0400 (EDT)
[ Continuing the "simple bug turns into thousand line patch" saga... ]
It appears that we need a way to know whether or not it is
safe for GTK+ to move a widget between screens.
Use cases for this:
A) For drag-and-drop, GTK+ needs to know whether the icon set using
gtk_drag_set_icon_window() can be used across multiple screens.
B) We eventually want the ability for window managers to migrate
windows across screens, and for users to migrate applications
between different displays. GTK+ needs a way to know whether it
should advertise support for such capabilities.
The attached patch adds the GtkWindow API:
void gtk_window_set_can_change_screen (GtkWindow *window,
gboolean can_change_screen);
void gtk_window_unset_can_change_screen (GtkWindow *window);
gboolean gtk_window_get_can_change_screen (GtkWindow *window);
void gtk_window_set_default_can_change_screen (gboolean can_change_screen);
gboolean gtk_window_get_default_can_change_screen (GtkWindow *window);
And properties "can_change_screen" and "can_change_screen_set".
Regards,
Owen
Thought:
Though I did the API on GtkWindow, perhaps it should
be on GtkWidget instead. The primary reason for this is
GtkMenu, which isn't a toplevel window, but which needs
to propagate ability-to-change screen to the toplevels
it creates.
(A secondary use would be GtkHandlebox - is it OK for
GtkHandleBox to allow the torn off contents to be
dragged between screens.)
Another formulation would be a GtkMigratable interface
that GtkInvisible, GtkWindow, and GtkMenu - all the
widgets that currently have _set_screen() functions -
implement. That would be a lot of code churn at this
point in the process.
(And doesn't solve the GtkHandleBox situation, if we
think that that matters)
Sort of a mess...
Index: gtk/gtkwindow.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkwindow.c,v
retrieving revision 1.218
diff -u -p -r1.218 gtkwindow.c
--- gtk/gtkwindow.c 30 Sep 2002 18:58:27 -0000 1.218
+++ gtk/gtkwindow.c 1 Oct 2002 18:50:13 -0000
@@ -73,6 +73,8 @@ enum {
PROP_TYPE_HINT,
PROP_SKIP_TASKBAR_HINT,
PROP_SKIP_PAGER_HINT,
+ PROP_CAN_CHANGE_SCREEN,
+ PROP_CAN_CHANGE_SCREEN_SET,
/* Readonly properties */
PROP_IS_ACTIVE,
@@ -153,6 +155,8 @@ struct _GtkWindowPrivate
guint fullscreen_initially : 1;
guint skips_taskbar : 1;
guint skips_pager : 1;
+ guint can_change_screen : 1;
+ guint can_change_screen_set : 1;
};
static void gtk_window_class_init (GtkWindowClass *klass);
@@ -263,6 +267,8 @@ static guint window_signals[LAST_
static GList *default_icon_list = NULL;
static guint default_icon_serial = 0;
+static gboolean default_can_change_screen = FALSE;
+
static void gtk_window_set_property (GObject *object,
guint prop_id,
const GValue *value,
@@ -590,6 +596,22 @@ gtk_window_class_init (GtkWindowClass *k
FALSE,
G_PARAM_READWRITE));
+ g_object_class_install_property (gobject_class,
+ PROP_CAN_CHANGE_SCREEN,
+ g_param_spec_boolean ("can_change_screen",
+ _("Can change screen"),
+ _("TRUE if it is safe to move the window between screens and displays"),
+ FALSE,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class,
+ PROP_CAN_CHANGE_SCREEN_SET,
+ g_param_spec_boolean ("can_change_screen_set",
+ _("Can change screen set"),
+ _("Whether to use the value from \"can_change_screen\" or the default value"),
+ FALSE,
+ G_PARAM_READWRITE));
+
window_signals[SET_FOCUS] =
g_signal_new ("set_focus",
G_TYPE_FROM_CLASS (object_class),
@@ -806,7 +828,15 @@ gtk_window_set_property (GObject *o
gtk_window_set_skip_pager_hint (window,
g_value_get_boolean (value));
break;
-
+
+ case PROP_CAN_CHANGE_SCREEN:
+ gtk_window_set_can_change_screen (window,
+ g_value_get_boolean (value));
+ break;
+ case PROP_CAN_CHANGE_SCREEN_SET:
+ if (!g_value_get_boolean (value))
+ gtk_window_unset_can_change_screen (window);
+ break;
default:
break;
}
@@ -887,6 +917,20 @@ gtk_window_get_property (GObject *o
g_value_set_boolean (value,
gtk_window_get_skip_pager_hint (window));
break;
+ case PROP_CAN_CHANGE_SCREEN:
+ {
+ GtkWindowPrivate *priv = gtk_window_get_private (window);
+ g_value_set_boolean (value,
+ priv->can_change_screen);
+ }
+ break;
+ case PROP_CAN_CHANGE_SCREEN_SET:
+ {
+ GtkWindowPrivate *priv = gtk_window_get_private (window);
+ g_value_set_boolean (value,
+ priv->can_change_screen_set);
+ }
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -5614,8 +5658,8 @@ gtk_window_unfullscreen (GtkWindow *wind
g_return_if_fail (GTK_IS_WINDOW (window));
widget = GTK_WIDGET (window);
- priv = gtk_window_get_private (window);
-
+ priv = gtk_window_get_private (window);
+
priv->fullscreen_initially = FALSE;
if (window->frame)
@@ -6583,4 +6627,137 @@ _gtk_window_set_has_toplevel_focus (GtkW
g_object_notify (G_OBJECT (window), "has_toplevel_focus");
}
+}
+
+/**
+ * gtk_window_set_can_change_screen:
+ * @window: a #GtkWindow
+ * @can_change_screen: %TRUE if changing the screen
+ * of the window is safe.
+ *
+ * Sets a flag as to whether it is safe to move this window
+ * between displays and screens with gtk_window_set_screen().
+ * In general, a window created using only non-deprecated
+ * features of GTK+ will be safe to move between screens without any
+ * additional intervention by the application programmer.
+ *
+ * If there are screen-specific resources associated with the
+ * window such as GdkPixmap or GdkGC objects, then special
+ * handling is required to make it safe to move the window
+ * between screens. You need create these resources in response
+ * to the ::realize signal on the window and destroy them in
+ * response to the ::unrealize signal rather than keeping them
+ * around permanently.
+ **/
+void
+gtk_window_set_can_change_screen (GtkWindow *window,
+ gboolean can_change_screen)
+{
+ GtkWindowPrivate *priv;
+ GObject *object;
+
+ g_return_if_fail (GTK_IS_WINDOW (window));
+
+ priv = gtk_window_get_private (window);
+ object = G_OBJECT (window);
+
+ can_change_screen = can_change_screen != FALSE;
+
+ priv->can_change_screen_set = TRUE;
+ priv->can_change_screen = can_change_screen;
+
+ g_object_freeze_notify (object);
+ g_object_notify (object, "can_change_screen");
+ g_object_notify (object, "can_change_screen_set");
+ g_object_thaw_notify (object);
+}
+
+/**
+ * gtk_window_unset_can_change_screen:
+ * @window: a #GtkWindow
+ *
+ * Unset a value previously set with
+ * gtk_window_set_can_change_screen() so that the
+ * window uses the default value from
+ * gtk_window_set_default_can_change_screen again.
+ **/
+void
+gtk_window_unset_can_change_screen (GtkWindow *window)
+{
+ GtkWindowPrivate *priv;
+ GObject *object;
+
+ g_return_if_fail (GTK_IS_WINDOW (window));
+
+ priv = gtk_window_get_private (window);
+ object = G_OBJECT (window);
+
+ priv->can_change_screen_set = FALSE;
+
+ g_object_freeze_notify (object);
+ g_object_notify (object, "can_change_screen");
+ g_object_notify (object, "can_change_screen_set");
+ g_object_thaw_notify (object);
+}
+
+/**
+ * gtk_window_get_can_change_screen:
+ * @window: a #GtKWindow
+ *
+ * Determines whether it is safe to move a window between
+ * different screens and displays.
+ *
+ * Return value: %TRUE if it is safe to move the window
+ * between screens and displays.
+ **/
+gboolean
+gtk_window_get_can_change_screen (GtkWindow *window)
+{
+ GtkWindowPrivate *priv;
+
+ g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
+
+ priv = gtk_window_get_private (window);
+
+ if (priv->can_change_screen_set)
+ return priv->can_change_screen;
+ else
+ return default_can_change_screen;
+}
+
+/**
+ * gtk_window_set_default_can_change_screen:
+ * @can_change_screen: %TRUE if changing the screen
+ * of windows in this application is safe.
+ *
+ * Sets the default value for gtk_window_get_can_change_screen().
+ * All windows that GTK+ creates itself will be safe to move
+ * between screens, so if you know that this is also true of
+ * your application and any other libraries your application
+ * might use, you can turn this flag on to avoid having
+ * to call gtk_window_set_can_change_screen() on each window
+ * individually.
+ **/
+void
+gtk_window_set_default_can_change_screen (gboolean can_change_screen)
+{
+ can_change_screen = can_change_screen != FALSE;
+
+ default_can_change_screen = can_change_screen;
+}
+
+
+/**
+ * gtk_window_set_default_can_change_screen:
+ * @window: a #GtkWindow
+ *
+ * Gets the value set by gtk_window_set_default_can_change_screen()
+ *
+ * Return value: %TRUE if changing the screen
+ * of windows in this application is safe.
+ **/
+gboolean
+gtk_window_get_default_can_change_screen (GtkWindow *window)
+{
+ return default_can_change_screen;
}
Index: gtk/gtkwindow.h
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkwindow.h,v
retrieving revision 1.65
diff -u -p -r1.65 gtkwindow.h
--- gtk/gtkwindow.h 30 Sep 2002 18:58:27 -0000 1.65
+++ gtk/gtkwindow.h 1 Oct 2002 18:50:13 -0000
@@ -255,6 +255,12 @@ GList* gtk_window_get_default_icon_l
gboolean gtk_window_set_default_icon_from_file (const gchar *filename,
GError **err);
+void gtk_window_set_can_change_screen (GtkWindow *window,
+ gboolean can_change_screen);
+void gtk_window_unset_can_change_screen (GtkWindow *window);
+gboolean gtk_window_get_can_change_screen (GtkWindow *window);
+void gtk_window_set_default_can_change_screen (gboolean can_change_screen);
+gboolean gtk_window_get_default_can_change_screen (GtkWindow *window);
/* If window is set modal, input will be grabbed when show and released when hide */
void gtk_window_set_modal (GtkWindow *window,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]