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