mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-10 19:00:08 +00:00
GtkWindow: new API to store state in GSettings
https://bugzilla.gnome.org/show_bug.cgi?id=667438
This commit is contained in:
parent
d47c3ac9e4
commit
730765de91
@ -5322,6 +5322,7 @@ gtk_window_fullscreen
|
||||
gtk_window_unfullscreen
|
||||
gtk_window_set_keep_above
|
||||
gtk_window_set_keep_below
|
||||
gtk_window_setup_persistent_state
|
||||
gtk_window_begin_resize_drag
|
||||
gtk_window_begin_move_drag
|
||||
gtk_window_set_decorated
|
||||
|
@ -1508,10 +1508,12 @@ EXTRA_DIST += \
|
||||
gtktypebuiltins.h.template \
|
||||
gtkprivatetypebuiltins.c.template \
|
||||
gtkprivatetypebuiltins.h.template \
|
||||
org.gtk.Settings.FileChooser.gschema.xml
|
||||
org.gtk.Settings.FileChooser.gschema.xml \
|
||||
org.gtk.WindowState.gschema.xml
|
||||
|
||||
gsettings_SCHEMAS = \
|
||||
org.gtk.Settings.FileChooser.gschema.xml
|
||||
org.gtk.Settings.FileChooser.gschema.xml \
|
||||
org.gtk.WindowState.gschema.xml
|
||||
|
||||
@GSETTINGS_RULES@
|
||||
|
||||
|
@ -3876,6 +3876,7 @@ gtk_window_set_transient_for
|
||||
gtk_window_set_type_hint
|
||||
gtk_window_set_urgency_hint
|
||||
gtk_window_set_wmclass
|
||||
gtk_window_setup_persistent_state
|
||||
gtk_window_stick
|
||||
gtk_window_type_get_type
|
||||
gtk_window_unfullscreen
|
||||
|
128
gtk/gtkwindow.c
128
gtk/gtkwindow.c
@ -132,6 +132,9 @@ struct _GtkWindowPrivate
|
||||
|
||||
guint16 configure_request_count;
|
||||
|
||||
GSettings *state_settings;
|
||||
guint state_save_id;
|
||||
|
||||
/* The following flags are initially TRUE (before a window is mapped).
|
||||
* They cause us to compute a configure request that involves
|
||||
* default-only parameters. Once mapped, we set them to FALSE.
|
||||
@ -4590,6 +4593,40 @@ gtk_window_reshow_with_initial_size (GtkWindow *window)
|
||||
gtk_widget_show (widget);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_window_persistent_state_flush (gpointer user_data)
|
||||
{
|
||||
GtkWindow *window = user_data;
|
||||
GtkWidget *widget = user_data;
|
||||
gboolean was_maximized;
|
||||
gboolean is_maximized;
|
||||
|
||||
was_maximized = g_settings_get_boolean (window->priv->state_settings, "is-maximized");
|
||||
is_maximized = gdk_window_get_state (gtk_widget_get_window (widget)) & GDK_WINDOW_STATE_MAXIMIZED;
|
||||
|
||||
if (is_maximized != was_maximized)
|
||||
g_settings_set_boolean (window->priv->state_settings, "is-maximized", is_maximized);
|
||||
|
||||
if (!is_maximized)
|
||||
{
|
||||
gint old_width, old_height;
|
||||
GtkAllocation size;
|
||||
|
||||
G_STATIC_ASSERT (sizeof (size.width) == sizeof (int));
|
||||
|
||||
g_settings_get (window->priv->state_settings, "size", "(ii)", &old_width, &old_height);
|
||||
gtk_widget_get_allocation (widget, &size);
|
||||
|
||||
if (size.width != old_width || size.height != old_height)
|
||||
g_settings_set (window->priv->state_settings, "size", "(ii)", size.width, size.height);
|
||||
}
|
||||
|
||||
g_source_remove (window->priv->state_save_id);
|
||||
window->priv->state_save_id = 0;
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_window_destroy (GtkWidget *widget)
|
||||
{
|
||||
@ -5231,6 +5268,9 @@ gtk_window_unrealize (GtkWidget *widget)
|
||||
GtkWindowPrivate *priv = window->priv;
|
||||
GtkWindowGeometryInfo *info;
|
||||
|
||||
if (window->priv->state_save_id)
|
||||
gtk_window_persistent_state_flush (window);
|
||||
|
||||
/* On unrealize, we reset the size of the window such
|
||||
* that we will re-apply the default sizing stuff
|
||||
* next time we show the window.
|
||||
@ -5426,6 +5466,14 @@ gtk_window_size_allocate (GtkWidget *widget,
|
||||
GtkWidget *child;
|
||||
guint border_width;
|
||||
|
||||
if (window->priv->state_settings)
|
||||
{
|
||||
if (window->priv->state_save_id)
|
||||
g_source_remove (window->priv->state_save_id);
|
||||
|
||||
window->priv->state_save_id = g_timeout_add (1000, gtk_window_persistent_state_flush, window);
|
||||
}
|
||||
|
||||
gtk_widget_set_allocation (widget, allocation);
|
||||
|
||||
if (gtk_widget_get_realized (widget))
|
||||
@ -9721,3 +9769,83 @@ ensure_state_flag_window_unfocused (GtkWidget *widget)
|
||||
|
||||
gtk_widget_queue_draw (widget);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_window_setup_persistent_state:
|
||||
* @window: a #GtkWindow
|
||||
* @settings: a #GSettings object
|
||||
* @child_name: the name of a child on @settings with schema
|
||||
* 'org.gtk.WindowState'
|
||||
*
|
||||
* Sets up persistent window state using #GSettings.
|
||||
*
|
||||
* The size of the window and its maximized state is saved.
|
||||
*
|
||||
* At the time of the call, the values are read out of GSettings and
|
||||
* applied to the window as the default size and maximized state. This
|
||||
* must be done before the window is shown.
|
||||
*
|
||||
* When the size or maximized state of the window is changed, the
|
||||
* updated values are stored back into GSettings (with an unspecified
|
||||
* delay to prevent trashing).
|
||||
*
|
||||
* @child_name must be the name of a child of @settings (ie:
|
||||
* g_settings_get_child() must succeed). The resulting #GSettings
|
||||
* object must have the schema 'org.gtk.WindowState', which is installed
|
||||
* by Gtk.
|
||||
*
|
||||
* Your application's schema should look something like this:
|
||||
*
|
||||
* |[<![CDATA[
|
||||
* <schema id='org.example.awesome' path='/org/example/awesome/'>
|
||||
* ... keys ...
|
||||
*
|
||||
* <child name='main-window-state' schema='org.gtk.WindowState'/>
|
||||
* </schema>
|
||||
* ]]>]|
|
||||
*
|
||||
* Then you should call this function like this:
|
||||
*
|
||||
* |[
|
||||
* GSettings *settings;
|
||||
*
|
||||
* settings = g_settings_new ("org.example.awesome");
|
||||
* gtk_window_setup_persistent_state (window, settings, "main-window-state");
|
||||
* ]|
|
||||
*
|
||||
* You may only call this function once per window.
|
||||
*
|
||||
* Since: 3.4
|
||||
**/
|
||||
void
|
||||
gtk_window_setup_persistent_state (GtkWindow *window,
|
||||
GSettings *settings,
|
||||
const gchar *child_name)
|
||||
{
|
||||
gint width, height;
|
||||
GSList *node;
|
||||
|
||||
g_return_if_fail (GTK_IS_WINDOW (window));
|
||||
g_return_if_fail (G_IS_SETTINGS (settings));
|
||||
g_return_if_fail (child_name != NULL);
|
||||
g_return_if_fail (window->priv->state_settings == NULL);
|
||||
|
||||
/* Force other windows to flush their state first. We may be sharing
|
||||
* the same settings as they are and we want to see them up to date...
|
||||
*/
|
||||
for (node = toplevel_list; node; node = node->next)
|
||||
{
|
||||
GtkWindow *w = node->data;
|
||||
|
||||
if (w->priv->state_save_id)
|
||||
gtk_window_persistent_state_flush (w);
|
||||
g_assert (w->priv->state_save_id == 0);
|
||||
}
|
||||
|
||||
window->priv->state_settings = g_settings_get_child (settings, child_name);
|
||||
window->priv->maximize_initially = g_settings_get_boolean (window->priv->state_settings, "is-maximized");
|
||||
|
||||
g_settings_get (window->priv->state_settings, "size", "(ii)", &width, &height);
|
||||
if (width > 0 && height > 0)
|
||||
gtk_window_set_default_size (window, width, height);
|
||||
}
|
||||
|
@ -338,6 +338,10 @@ gboolean gtk_window_get_has_resize_grip (GtkWindow *window);
|
||||
gboolean gtk_window_resize_grip_is_visible (GtkWindow *window);
|
||||
gboolean gtk_window_get_resize_grip_area (GtkWindow *window,
|
||||
GdkRectangle *rect);
|
||||
void gtk_window_setup_persistent_state (GtkWindow *window,
|
||||
GSettings *settings,
|
||||
const gchar *child_name);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
10
gtk/org.gtk.WindowState.gschema.xml
Normal file
10
gtk/org.gtk.WindowState.gschema.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<schemalist>
|
||||
<schema id='org.gtk.WindowState'>
|
||||
<key name='size' type='(ii)'>
|
||||
<default>(-1, -1)</default>
|
||||
</key>
|
||||
<key name='is-maximized' type='b'>
|
||||
<default>false</default>
|
||||
</key>
|
||||
</schema>
|
||||
</schemalist>
|
Loading…
Reference in New Issue
Block a user