【问题标题】:How I can get space on top for my window?我怎样才能为我的窗户腾出空间?
【发布时间】:2020-01-04 13:03:43
【问题描述】:

我有 sfml 窗口。我需要为我的窗口在屏幕的顶部(或底部)保留空间。像这样做polybar,lemonbar等。我该怎么做?

在这一步,我只有一个简单的 sfml 窗口:

#include <SFML/Graphics.hpp>

using namespace sf;
int main()
{
    unsigned int bar_x = 1920, bar_y = 20;
    RenderWindow window(VideoMode(bar_x, bar_y), "bar", Style::None);

    Vector2u bar_size(bar_x, bar_y);
    Vector2i bar_position(0,0);

    while (window.isOpen())
    {
        Event event;
        while (window.pollEvent(event))
        {
            // Here should be blocking position function...
            if (event.type == Event::Closed)
                window.close();

            if (event.type == Event::Resized)
                window.setSize(bar_size);

            if (event.type == Event::Resized)
                window.setPosition(Vector2i(0,0));
        }

        window.clear();
        // window.draw(shape);
        window.display();
    }

    return 0;
}

【问题讨论】:

    标签: c++ linux sfml xorg


    【解决方案1】:

    我认为没有办法强制 WM 保留空间,但许多 WM 支持并尊重 _NET_WM_STRUT_PARTIAL EWMH property 在屏幕边缘保留空间。这也是柠檬棒和多棒棒的作用。

    来自EWMH Spec

    _NET_WM_STRUT_PARTIAL

    _NET_WM_STRUT_PARTIAL, left, right, top, bottom, left_start_y, left_end_y, right_start_y, right_end_y, top_start_x, top_end_x, bottom_start_x, bottom_end_x,CARDINAL[12]/32

    如果窗口要在屏幕边缘保留空间,则必须由客户端设置此属性。该属性包含 4 个基数,指定屏幕每个边框处保留区域的宽度,另外还有 8 个基数指定对应于四个支柱中的每一个的开始和结束。值的顺序是左、右、上、下、left_start_y、left_end_y、right_start_y、right_end_y、top_start_x、top_end_x、bottom_start_x、bottom_end_x。所有坐标都是根窗口坐标。客户端可以随时更改此属性,因此如果窗口管理器使用此属性为窗口分配特殊语义,则窗口管理器必须监视属性通知事件。

    [...]

    例如,对于出现在屏幕底部、50 像素高、占用屏幕边缘左侧 200-600 像素空间的面板样式客户端,将设置底部支柱 50,并设置bottom_start_x 到 200,bottom_end_x 到 600。[...]


    更新: 在深入研究了 SFML 文档之后,我不确定如何通过 SFML 设置 EMWH 属性,或者是否有可能。您需要自己弄清楚这一点。如果不可能,一种方法是以某种方式从 SFML 获取窗口句柄 (xcb_window_t) 并使用类似 xcb_change_property 的东西从 libxcb 设置 _NET_WM_STRUT_PARTIAL 属性。参考lemonbar source


    更新 2: 我对 Xlib 不是很熟悉,但我经常查看 stalonetray 源代码以供参考。例如src/wmh.c文件中的ewmh_set_window_strut函数显示了如何设置_NET_WM_STRUT_PARTIAL属性:

    /* Set data for _NET_WM_STRUT{,_PARTIAL} hints */
    int ewmh_set_window_strut(Display *dpy, Window wnd, wm_strut_t wm_strut)
    {
        Atom prop_strut;
        Atom prop_strut_partial;
        prop_strut = XInternAtom(dpy, _NET_WM_STRUT, False);
        prop_strut_partial = XInternAtom(dpy, _NET_WM_STRUT_PARTIAL, False);
        XChangeProperty(dpy, wnd, prop_strut, XA_CARDINAL, 32, PropModeReplace,
                (unsigned char *)wm_strut, _NET_WM_STRUT_SZ);
        XChangeProperty(dpy, wnd, prop_strut_partial, XA_CARDINAL, 32, PropModeReplace,
                (unsigned char *)wm_strut, _NET_WM_STRUT_PARTIAL_SZ);
        return x11_ok();
    }
    

    【讨论】:

    • 你能提供 xlib 的例子吗?我没有找到如何使用 XChangeProperty
    • 我从 stalonetray 添加了一个使用 XChangeProperty 的代码 sn-p
    猜你喜欢
    • 1970-01-01
    • 2020-09-06
    • 1970-01-01
    • 2016-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多