【问题标题】:What event is used for Maximizing/Minimizing?什么事件用于最大化/最小化?
【发布时间】:2016-09-30 18:58:52
【问题描述】:

目前我负责为一个小项目开发一个(C++)窗口类;目标是将依赖关系保持在最低限度。 Win32/WinAPI 的实现按预期工作,但是,当涉及到 Linux/XCB 时,我正在苦苦挣扎。

我知道,我可以检查“_NET_WM_STATE”属性,但是,文档没有指定任何事件,这会在窗口最大化或最小化时发生。 Extended Window Manager Hints 规范似乎也没有定义事件。

那么,如何拦截最大化/最小化事件?

编辑: 我的代码看起来基本上是这样的,但不起作用: (by 不起作用,我的意思是永远不会满足下面的 if 条件。)

// xcb_generic_event_t* msg;
// xcb_intern_atom_reply_t*    wmStateMinimized;   

case XCB_PROPERTY_NOTIFY: {
    xcb_property_notify_event_t* data{reinterpret_cast<xcb_property_notify_event_t*>(msg)};
    if(data->atom == wmStateMinimized->atom)
        eventQueue.emplace(Event::Minimized);

} break;

我还检查了事件提供给我的原子。它们与“wmStateMinimized”提供的原子不同,尽管“wmStateMinimized”的原子由窗口管理器提供。

编辑 2: 好的,xcb_property_notify_event_t 提供已更改的原子,而不是它自身的值。 所以 if 应该是这样的:

if(data->atom == wmState->atom)

必须弄清楚如何正确检索值。

【问题讨论】:

  • 没有最大化/最小化的特定事件。要查看属性更改,您需要订阅 PropertyNotify 事件。这由 PropertyChangeMask 控制。
  • 谢谢,我也想通了,通过打印我的应用程序将获得的事件代码。
  • AFAIK,在 X11 中,最大化-最小化已由窗口管理器处理。在我编写的一些 X11 应用程序中,我从未明确处理过它。然而,您可能会对这个SO post 感兴趣。
  • 看起来我不理解规范:“实施说明:如果应用程序要求切换 _NET_WM_STATE_HIDDEN,则窗口管理器可能应该忽略该请求,因为 _NET_WM_STATE_HIDDEN 是窗口最小化,而不是一个独立的状态。” - 这是什么意思?
  • @user3078414 这意味着 _NET_WM_STATE_HIDDEN 不控制隐藏状态,它只是反映它。

标签: c++ x11 xlib xcb


【解决方案1】:

所以,3 个小时后,我终于弄明白了。 这个解决方案 sn-p 假设您已经查询了原子:

  • _NET_WM_STATE
  • _NET_WM_STATE_HIDDEN
  • _NET_WM_STATE_MAXIMIZED_VERT
  • _NET_WM_STATE_MAXIMIZED_HORZ

它们被存储在以下原子中:

xcb_atom_t wmState;
xcb_atom_t wmStateHidden;
xcb_atom_t wmStateMaxVert;
xcb_atom_t wmStateMaxHorz;

这个 sn-p 也假设你已经指定了

XCB_EVENT_MASK_PROPERTY_CHANGE

对于窗口,以便实际获得有关属性更改的通知。

所以,让我们假设我们现在处于事件循环中:

case XCB_PROPERTY_NOTIFY: {
    xcb_property_notify_event_t* data{reinterpret_cast<xcb_property_notify_event_t*>(msg)};
    if(data->atom == wmState){ // the WM_STATE property was changed.
        // Now we need the value.
        // Therefore I implemented an auxiliary function.
        if(internal::getAtomValue(connection, window, wmState) == wmStateHidden)
            // Handle Events here:
            eventQueue.emplace(Event::Minimized);
        else{
            xcb_atom_t value{internal::getAtomValue(connection, window, wmState)};
            if((value == wmStateMaxVert) || (value == wmStateMaxHorz))
            // Handle Event here
            eventQueue.emplace(Event::Maximized);
        }
    }

} break;

辅助函数'internal::getAtomValue'的工作原理如下:

xcb_get_property_cookie_t    cookie{xcb_get_property(connection, false, window, atom, XCB_ATOM_ATOM, 0, 32)};
xcb_generic_error_t*         err{nullptr};
xcb_get_property_reply_t     reply{xcb_get_property_reply(connection, cookie, &err);
xcb_atom_t*                  value{reinterpret_cast<xcb_atom_t*>(xcb_get_property_value(reply))};

我希望这个解决方案的概念得到证明和正确。愿它作为每个需要与 XCB 合作的人的参考。

P.S.:这些片段是从我的原始来源中删除的。它可能包含错别字。

【讨论】:

  • 请仔细检查错别字。你的问题和回答都很重要。其他人会发现您的研究和分享这很有帮助。谢谢。
猜你喜欢
  • 1970-01-01
  • 2010-09-22
  • 2021-11-13
  • 1970-01-01
  • 1970-01-01
  • 2021-09-23
  • 2013-05-04
  • 2014-07-10
  • 1970-01-01
相关资源
最近更新 更多