在 GTK 中保存/恢复窗口位置

发布于 2024-11-04 13:22:59 字数 302 浏览 0 评论 0原文

我想在程序启动之间保存/恢复窗口位置。 窗口可以最大化。这也应该保存。 问题是在最大化(缩放)时保存窗口位置。

所以细节(我不关心保存,这是相当简单的任务)。 我需要获取窗口正常状态的x,y,宽度,高度并标记窗口是否最大化的方法。 不幸的是 gdk_window_get_size/gdk_window_get_position 返回实际的窗口位置。

在 Windows 下使用 GetWindowPlacement 和 rcNormalPosition 可以轻松解决此问题。 但我需要一个针对 Mac OS X Cocoa(至少)或纯 GTK 的解决方案。

I would like to save/restore window position 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

梦魇绽荼蘼 2024-11-11 13:22:59

为此,我所做的是使用在调整大小时发出 Gtk.Window 的信号,通过 gsettings 我保存值并恢复它以以相同的方式启动应用程序。这是 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;
    }

}

以及其架构:

<?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>

祝你好运!

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!

勿忘初心 2024-11-11 13:22:59

Cocoa* 解决方案在 保存窗口位置。让您的应用程序委托执行以下操作:

[window setFrameAutosaveName:@"MyWindowFrame"];

使窗口在框架更改时自动将其框架保存到用户默认值中。然后在下次启动时,

[window setFrameUsingName:@"MyWindowFrame"];

窗口知道它是否 已“缩放”<​​/a>(最大化):

[window isZoomed];

因此您可以随时获取此标志就像,连同框架:

// Gives you an NSRect in screen coordinates
[window frame];

根据文档, isZoomedzoom 通过 windowWillUseStandardFrame:defaultFrame:。我不确定你想在这里深入了解可可,但这看起来像是你在评论中提到的情况的一个选择。我认为,如果窗口是使用缩放框架创建的,则窗口委托对象可以通过此方法为框架提供合理的默认值。


*和 Obj-C,因为我不懂 C++。

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++.

忆伤 2024-11-11 13:22:59

我刚刚使用 pygobject 实现了这样的事情;它不是 C++,但仍然有用。

您可以在此处找到代码。

我已经将 GNOME Builder 的默认模板用于 python GNOME 应用程序,因此如果您使用它设置项目,复制应该非常容易。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文