What event is used for Maximizing/Minimizing?
Asked Answered
P

1

5

Currently I am in charge of developing a (C++) window class for a little project; the goal is to keep dependencies at a bare minimum. The implementation for Win32/WinAPI works as supposed, however, I am struggling when it comes to Linux/XCB.

I am aware, that I am able to check the "_NET_WM_STATE" property, however, the documentation doesn't specify any event, which would occur when the window is being maximized or minimized. The Extended Window Manager Hints specification doesn't seem to define a event either.

So, how would one intercept the Maximize/Minimize event?

EDIT: My code looks basically like that, but doesn't work: (By doesn't work, I mean the if-condition below is never met.)

// 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;

I have also checked the atoms the event provides me. They differ from the atom provided by 'wmStateMinimized', altough the atom for 'wmStateMinimized' is provided by the window manager.

EDIT 2: Ok, the xcb_property_notify_event_t supplies the atom that has been change, not the value it self. So the if should look like this then:

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

Gotta figure out, how to retrieve the value properly.

Peal answered 1/6, 2016 at 12:4 Comment(5)
There is no specific event for maximize/minimize. To watch for property changes you need to subscribe to PropertyNotify events. This is controlled by the PropertyChangeMask.Curren
Thanks, just figured it out as well, by printing the event codes my application would get.Peal
AFAIK, in X11 the maximizing-minimizing has been handled by the window manager. In a few X11 apps I wrote, I've never handled it explicitly. Yet, this SO post might be of interest for you to read.Sizzle
Looks like I don't understand the specs: "Implementation note: if an Application asks to toggle _NET_WM_STATE_HIDDEN the Window Manager should probably just ignore the request, since _NET_WM_STATE_HIDDEN is a function of some other aspect of the window such as minimization, rather than an independent state." - What does it mean?Peal
@Sizzle This means that _NET_WM_STATE_HIDDEN doesn't control the hidden state, it only reflects it.Curren
P
7

So, after 3 hours I finally figured it out. This solution snippet assumes, that you already have queried the atoms:

  • _NET_WM_STATE
  • _NET_WM_STATE_HIDDEN
  • _NET_WM_STATE_MAXIMIZED_VERT
  • _NET_WM_STATE_MAXIMIZED_HORZ

They are being stored in the following atoms:

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

This snippet does as well assume, that you have specified

XCB_EVENT_MASK_PROPERTY_CHANGE

for the window, in order to actually get notified about property changes.

So, let's pretend we're in the Event Loop now:

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;

The auxiliary function 'internal::getAtomValue' works as following:

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))};

I hope that this solution concept proof and correct. May it serve as an reference for everyone, who needs to work with XCB.

P.S.: These Snippets were stripped down from my original source. It might contain Typos.

Peal answered 1/6, 2016 at 16:18 Comment(1)
Please, be so kind to double-check against typos. Both your question and reply are important. Someone else will find your research and sharing this helpful. Thanks.Sizzle

© 2022 - 2024 — McMap. All rights reserved.