Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Programmatically minimise window with XCB

I’m currently writing the linux-side windowing for my game engine, and I wanted to have an option to programmatically minimise/restore the window.

I decided to use XCB and not Xlib, and since I have wrote almost the entire thing now, I don’t want to back. What I tried (based on the successful maximising implementation) is to send a client event with _NET_WM_STATE set to _NET_WM_STATE_HIDDEN. The code looks like so:

xcb_intern_atom_reply_t* _net_wm_state = xcb_intern_atom_reply(connection, xcb_intern_atom(connection, true, strlen("_NET_WM_STATE"), "_NET_WM_STATE"), nullptr);
xcb_intern_atom_reply_t* _net_wm_state_hidden = xcb_intern_atom_reply(connection, xcb_intern_atom(connection, true, strlen("_NET_WM_STATE_HIDDEN"), "_NET_WM_STATE_HIDDEN"), nullptr);

// Some code here...

xcb_client_message_data_t data{};
data.data32[0] = true; // yes, I want to minimise the window
data.data32[1] = _net_wm_state_hidden->atom;

xcb_client_message_event_t event{};
event.response_type = XCB_CLIENT_MESSAGE;
event.format = 32;
event.window = windowHandle;
event.type = _net_wm_state;
event.data = data;

xcb_send_event(connection, true, windowHandle, XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (char*)&event);
xcb_flush(connection);

For maximising and entering/exiting fullscreen I used basically the same code just with different atoms. Those work, but this does not.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

In X11, minimizing a window has nothing to do with _NET_WM_STATE_HIDDEN.
Instead, you need to send XCB_ICCCM_WM_STATE_ICONIC.

It should be something like this:

xcb_intern_atom_reply_t* wm_change_state = xcb_intern_atom_reply(connection, xcb_intern_atom(connection, true, strlen("WM_CHANGE_STATE"), "WM_CHANGE_STATE"), nullptr);

xcb_client_message_data_t data{};
data.data32[0] = XCB_ICCCM_WM_STATE_ICONIC;

xcb_client_message_event_t event{};
event.response_type = XCB_CLIENT_MESSAGE;
event.format = 32;
event.window = windowHandle;
event.type = wm_change_state->atom;
event.data = data;

xcb_send_event(connection, false, windowHandle, XCB_EVENT_MASK_STRUCTURE_NOTIFY, (char*)&event);
xcb_flush(connection);

free(wm_change_state);
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading