Merge lp:~donadigo/granite/saved-state-in-appclass into lp:~elementary-pantheon/granite/granite

Proposed by Adam Bieńkowski
Status: Rejected
Rejected by: Danielle Foré
Proposed branch: lp:~donadigo/granite/saved-state-in-appclass
Merge into: lp:~elementary-pantheon/granite/granite
Diff against target: 175 lines (+128/-2)
1 file modified
lib/Application.vala (+128/-2)
To merge this branch: bzr merge lp:~donadigo/granite/saved-state-in-appclass
Reviewer Review Type Date Requested Status
elementary Pantheon team Pending
Review via email: mp+290085@code.launchpad.net

Commit message

Fixes bug #1475825: Window states are saved inconsistently.

Description of the change

Fixes bug #1475825: Window states are saved inconsistently.

Saving state is implemented directly in Application class. To make window saving it's state simply set the GSettings schema path "settings_schema_id" to where you store your app settings and call add_window () in the application.

Much of the code was taken from the saved-state branch:
https://code.launchpad.net/~elementary-apps/granite/saved-state.

Process of porting apps:
* Remove old, separate saved-state code from the application.
* Add "saved-state" key to schema .xml file.
* Set settings_schema_id to where are the app settings stored.
* Call add_window () in the activate () method.

Example:
public class App : Granite.Application {
   ...

   public App () {
       ...
       settings_schema_id = "org.app";
       ...
   }

   public override void activate () {
       ...
       var window = new Gtk.Window ();
       add_window (window);

       window.show_all ();
       ...
   }
}

To post a comment you must log in.
Revision history for this message
Rico Tzschichholz (ricotz) wrote :

Breaks ABI

Revision history for this message
Rico Tzschichholz (ricotz) wrote :

Public fields are a pain while it is hard enough to try keeping ABI-compatibility with vala.

Revision history for this message
Zisu Andrei (matzipan) wrote :

Hey Rico, can you advise on what one needs to do to avoid breaking ABI compatibility?

934. By Adam Bieńkowski

Implement saved state in Application class

Revision history for this message
Adam Bieńkowski (donadigo) wrote :

@ricotz: is there anyway I can prevent a breakage in the ABI compatibility, and get this branch merged?

Revision history for this message
Corentin Noël (tintou) wrote :

Is this necessary ?

Revision history for this message
Danielle Foré (danrabbit) wrote :

Since this hasn't seen any movement in a few months, I'm going to mark it as "rejected". You can open a new PR on GitHub :)

Unmerged revisions

934. By Adam Bieńkowski

Implement saved state in Application class

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/Application.vala'
2--- lib/Application.vala 2016-06-09 01:28:31 +0000
3+++ lib/Application.vala 2016-07-18 12:15:21 +0000
4@@ -35,6 +35,14 @@
5 * to create a great deal of an app's functionality.
6 */
7 public abstract class Application : Gtk.Application {
8+ private const string SETTINGS_KEY_NAME = "saved-state";
9+
10+ private enum WindowState {
11+ NORMAL = 0,
12+ MAXIMIZED = 1,
13+ FULLSCREEN = 2,
14+ MAXIMIZED_FULLSCREEN = 3
15+ }
16
17 public string build_data_dir;
18 public string build_pkg_data_dir;
19@@ -139,6 +147,33 @@
20 public string about_license;
21 public License about_license_type;
22
23+
24+ /**
25+ * GSettings schema path to save added Gtk.Window state settings.
26+ * This is where "saved-state" key will be created and stored
27+ * for added Gtk.Window's: position and their state.
28+ * You also need a proper saved-state key in your schema .xml file with the name "saved-state"
29+ * with the type '(iiiiu)'
30+ * where the types represent in the order of listing:
31+ * x-coordinate of the window (the value -1 means centered window),
32+ * y-coordinate of the window (the value -1 means centered window),
33+ * width of the window,
34+ * height of the window,
35+ * state of the window (0 = Normal, 1 = Maximized, 2 = Fullscreen, 3 = Maximized and Fullscreen).
36+ *
37+ * This is an example:
38+ * <key name="saved-state" type="(iiiiu)">
39+ * <default>(-1,-1,700,500,0)</default>
40+ * <summary>The saved state of the window.</summary>
41+ * <description>The saved width of the window. The values represent in the respective order:
42+ * x-coordinate of the window (the value -1 means centered window),y-coordinate of the window (the value -1 means centered window),
43+ * width of the window, height of the window, state of the window (0 = Normal, 1 = Maximized, 2 = Fullscreen).</description>
44+ * </key>
45+ */
46+ public string settings_schema_id;
47+
48+ private HashTable<Gtk.Window, ulong> window_handlers = new HashTable<Gtk.Window, ulong> (null, null);
49+
50 /**
51 * This creates a new Application class
52 */
53@@ -161,6 +196,9 @@
54
55 add_actions ();
56
57+ window_added.connect (on_window_added);
58+ window_removed.connect (on_window_removed);
59+
60 // Deprecated
61 Granite.app = this;
62 }
63@@ -205,6 +243,56 @@
64 return base.run (args);
65 }
66
67+ private void on_window_added (Gtk.Window window) {
68+ if (SettingsSchemaSource.get_default ().lookup (settings_schema_id, true) == null) {
69+ return;
70+ }
71+
72+ var settings = new GLib.Settings (settings_schema_id);
73+ var tuple = settings.get_value (SETTINGS_KEY_NAME);
74+
75+ int x, y, width, height;
76+ uint state;
77+ tuple.@get ("(iiiiu)",
78+ out x,
79+ out y,
80+ out width,
81+ out height,
82+ out state);
83+
84+ if (x != -1 && y != -1) {
85+ window.move (x, y);
86+ }
87+
88+ window.set_default_size (width, height);
89+ switch ((WindowState)state) {
90+ case WindowState.MAXIMIZED:
91+ window.maximize ();
92+ break;
93+ case WindowState.FULLSCREEN:
94+ window.fullscreen ();
95+ break;
96+ case WindowState.MAXIMIZED_FULLSCREEN:
97+ window.maximize ();
98+ window.fullscreen ();
99+ break;
100+ default:
101+ window.unfullscreen ();
102+ window.unmaximize ();
103+ break;
104+ }
105+
106+ window_handlers.insert (window, window.delete_event.connect (on_window_delete_event));
107+ }
108+
109+ private void on_window_removed (Gtk.Window window) {
110+ if (!window_handlers.contains (window)) {
111+ return;
112+ }
113+
114+ window.disconnect (window_handlers.@get (window));
115+ }
116+
117 protected static bool DEBUG = false;
118 protected static bool ABOUT = false;
119
120@@ -215,9 +303,9 @@
121 };
122
123 protected virtual void set_options () {
124-
125- if (DEBUG)
126+ if (DEBUG) {
127 Logger.DisplayLevel = LogLevel.DEBUG;
128+ }
129 }
130
131 /**
132@@ -333,5 +421,43 @@
133 Gtk.main ();
134 }
135 }
136+
137+ private WindowState get_window_state (Gtk.Widget widget) {
138+ var window = widget.get_window ();
139+ if ((window.get_state () & Gdk.WindowState.MAXIMIZED) != 0) {
140+ if ((window.get_state () & Gdk.WindowState.FULLSCREEN) != 0) {
141+ return WindowState.MAXIMIZED_FULLSCREEN;
142+ } else {
143+ return WindowState.MAXIMIZED;
144+ }
145+ } else if ((window.get_state () & Gdk.WindowState.FULLSCREEN) != 0) {
146+ return WindowState.FULLSCREEN;
147+ }
148+
149+ return WindowState.NORMAL;
150+ }
151+
152+ private bool on_window_delete_event (Gtk.Widget widget, Gdk.EventAny event) {
153+ if (SettingsSchemaSource.get_default ().lookup (settings_schema_id, true) == null
154+ || !(widget is Gtk.Window)) {
155+ return false;
156+ }
157+
158+ int x, y, width, height;
159+
160+ ((Gtk.Window)widget).get_size (out width, out height);
161+ ((Gtk.Window)widget).get_position (out x, out y);
162+
163+ var settings = new GLib.Settings (settings_schema_id);
164+ var v_x = new GLib.Variant.int32 (x);
165+ var v_y = new GLib.Variant.int32 (y);
166+ var v_width = new GLib.Variant.int32 (width);
167+ var v_height = new GLib.Variant.int32 (height);
168+ var v_state = new GLib.Variant.uint32 ((uint32)get_window_state (widget));
169+
170+ var tuple = new GLib.Variant.tuple ({ v_x, v_y, v_width, v_height, v_state });
171+ settings.set_value (SETTINGS_KEY_NAME, tuple);
172+ return false;
173+ }
174 }
175 }

Subscribers

People subscribed via source and target branches