Save/restore window position in GTK
I would like to save/restore window posit开发者_Go百科ion between program launches. The window could be maximized. This should be saved also. The problem is to save window position when it is maximized (zoomed).
So the details (I don't care about saving, it is quite simple task). I need the way to obtain x,y,width,height of window normal state and flag whether window is maximized. Unfortunately gdk_window_get_size/gdk_window_get_position returns actual window placement.
This issue could be easily solved under Windows using GetWindowPlacement and rcNormalPosition. But I need a solution for Mac OS X Cocoa (at least) or something in pure GTK.
for that, what I do is use the signal that emits Gtk.Window when you resize it, through gsettings I save values and restore it to start the app in the same way. Here's an example in vala + GTK+:
using Gtk;
using GLib;
public class Prueba : Window {
public void on_resize (Window win)
{
int width;
int height;
win.get_size (out width, out height);
/* GSETTINGS CONFIG */
string settings_dir = Path.get_dirname (".");
SettingsSchemaSource sss = new SettingsSchemaSource.from_directory (settings_dir, null, false);
SettingsSchema schema = sss.lookup ("apps.test-gs", false);
if (sss.lookup == null)
{
stdout.printf ("GLIB.GIO.SCHEMA: ID not found.");
}
GLib.Settings config = new GLib.Settings.full (schema, null, null);
/* GSETTINGS FIN */
stdout.printf ("RESOLUTION: %dx%d\n", width, height);
config.set_int ("width", width);
config.set_int ("height", height);
}
public void on_destroy (Window ventana)
{
stderr.printf ("APPLICATION EXIT!\n");
Gtk.main_quit ();
}
public Prueba ()
{
this.title = "Prueba GTK+";
string settings_dir = Path.get_dirname (".");
SettingsSchemaSource sss = new SettingsSchemaSource.from_directory (settings_dir, null, false);
SettingsSchema schema = sss.lookup ("apps.test-gs", false);
if (sss.lookup == null)
{
stdout.printf ("GLIB.GIO.SCHEMA: ID not found.");
}
GLib.Settings settings = new GLib.Settings.full (schema, null, null);
this.set_default_size (settings.get_int("width"), settings.get_int("height"));
this.border_width = 10;
this.window_position = WindowPosition.CENTER;
Button b = new Button.with_label ("SALIR");
b.clicked.connect (()=>{
this.on_destroy (this);
});
this.add (b);
this.show_all ();
}
public static int main (string[] args)
{
Gtk.init (ref args);
Prueba app = new Prueba ();
app.destroy.connect (()=> {
app.on_destroy (app);
});
app.size_allocate.connect (()=>{
app.on_resize (app);
});
Gtk.main ();
return 0;
}
}
And the schema for this:
<?xml version="1.0" encoding="UTF-8"?>
<schemalist>
<schema id="apps.test-gs" path="/apps/test-gs/">
<key type="b" name="check-test">
<default>false</default>
<summary>Check de mi app TEST</summary>
<description>Es un ejemplo de BOOLEANO de mi APP TEST</description>
</key>
<key type="i" name="width">
<default>300</default>
<summary>Pixels del Ancho</summary>
<description>Valor del Ancho del Programa TEST</description>
</key>
<key type="i" name="height">
<default>100</default>
<summary>Pixels del Alto</summary>
<description>Valor del Alto del Programa TEST</description>
</key>
</schema>
</schemalist>
Good Luck!
The Cocoa* solution is described in Saving Window Position in the Window Programming Guide. Have your application delegate do:
[window setFrameAutosaveName:@"MyWindowFrame"];
to make the window save its frame into User Defaults automatically whenever the frame changes. Then on next launch,
[window setFrameUsingName:@"MyWindowFrame"];
The window knows if it is "zoomed" (maximized):
[window isZoomed];
so you can get this flag whenever you like, along with the frame:
// Gives you an NSRect in screen coordinates
[window frame];
According to the docs, isZoomed
and zoom
check with the window's delegate through windowWillUseStandardFrame:defaultFrame:
. I'm not sure how deep into Cocoa you want to go here, but that looks like an option for the situation you mention in your comment. I think a window delegate object can provide a sensible default value for the frame via this method, if the window was created with the zoomed frame.
*and Obj-C, because I don't know C++.
I've just implemented such a thing using pygobject
; it's not C++ but it could still be useful.
You can find the code here.
I've used GNOME Builder's default template for a python GNOME application, so it should be super-easy to replicate if you set your project with it.
精彩评论