kranewm

An ICCCM & EWMH compliant X11 reparenting, dynamic window manager, written in C++
git clone git clone git://git.deurzen.net/kranewm.git
Log | Files | Refs | LICENSE

commit fa9057d4431d4be2272de4c5d5d5aa66fb87eb46
parent dcc2372750b452850ab7c5e126e1b78d0987a661
Author: deurzen <m.deurzen@tum.de>
Date:   Fri, 30 Jul 2021 17:10:06 +0200

fixes double destroy bug

Diffstat:
M.gitignore | 2++
Msrc/core/model.cc | 16+++++++++-------
Msrc/winsys/xdata/xconnection.cc | 56+++++++++++++++++++++++++++++++-------------------------
3 files changed, 42 insertions(+), 32 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -6,3 +6,5 @@ /test /spdlog /TODO +/.ccls +/.ccls-cache diff --git a/src/core/model.cc b/src/core/model.cc @@ -172,7 +172,7 @@ Model::Model(Connection& conn) }, { { Key::B, { Main, Ctrl } }, CALL(jump_client({ - JumpSelector::SelectionCriterium::ByClassEquals, + JumpSelector::SelectionCriterium::ByClassContains, "Chromium" })) }, @@ -560,6 +560,9 @@ Model::Model(Connection& conn) { { Key::O, { Main, Shift } }, CALL_EXTERNAL($HOME/bin/dmenunotify) }, + { { Key::G, { Main, Shift } }, + CALL_EXTERNAL($HOME/bin/grabcolor) + }, { { Key::PrintScreen, { Main } }, CALL_EXTERNAL($HOME/bin/screenshot -s) }, @@ -996,10 +999,10 @@ void Model::map_client(Client_ptr client) { if (!client->mapped) { + client->mapped = true; m_conn.map_window(client->window); m_conn.map_window(client->frame); render_decoration(client); - client->mapped = true; } } @@ -1007,9 +1010,9 @@ void Model::unmap_client(Client_ptr client) { if (client->mapped) { - m_conn.unmap_window(client->frame); - client->expect_unmap(); client->mapped = false; + client->expect_unmap(); + m_conn.unmap_window(client->frame); } } @@ -1547,7 +1550,7 @@ Model::manage(const Window window, const bool ignore) if (!m_move_buffer.is_occupied() && !m_resize_buffer.is_occupied() - && !producer + && !(producer && producer->producing) ) { focus_client(client); } @@ -1576,7 +1579,7 @@ Model::unmanage(Client_ptr client) if (client->consume_unmap_if_expecting()) return; - for (auto& consumer : client->consumers) + for (Client_ptr consumer : client->consumers) check_unconsume_client(consumer); check_unconsume_client(client); @@ -1588,7 +1591,6 @@ Model::unmanage(Client_ptr client) m_conn.unparent_window(client->window, client->active_region.pos); m_conn.cleanup_window(client->window); - m_conn.destroy_window(client->window); m_conn.destroy_window(client->frame); workspace->remove_client(client); diff --git a/src/winsys/xdata/xconnection.cc b/src/winsys/xdata/xconnection.cc @@ -459,41 +459,47 @@ XConnection::destroy_window(winsys::Window window) bool XConnection::close_window(winsys::Window window) { - XEvent event; - event.type = ClientMessage; - event.xclient.window = window; - event.xclient.message_type = get_atom("WM_PROTOCOLS"); - event.xclient.format = 32; - event.xclient.data.l[0] = get_atom("WM_DELETE_WINDOW"); - event.xclient.data.l[1] = CurrentTime; - - return XSendEvent(mp_dpy, window, False, NoEventMask, &event) != 0; -} - -bool -XConnection::kill_window(winsys::Window window) -{ - int n; Atom* protocols; + int n = 0; + + Atom delete_atom = get_atom("WM_DELETE_WINDOW"); bool found = false; if (XGetWMProtocols(mp_dpy, window, &protocols, &n)) { while (!found && n--) - found = get_atom("WM_DELETE_WINDOW") == protocols[n]; + found = delete_atom == protocols[n]; XFree(protocols); } - if (found) - return close_window(window); + if (found) { + XEvent event; + event.type = ClientMessage; + event.xclient.window = window; + event.xclient.message_type = get_atom("WM_PROTOCOLS"); + event.xclient.format = 32; + event.xclient.data.l[0] = get_atom("WM_DELETE_WINDOW"); + event.xclient.data.l[1] = CurrentTime; + XSendEvent(mp_dpy, window, False, NoEventMask, &event); - XGrabServer(mp_dpy); - XSetErrorHandler(s_passthrough_error_handler); - XSetCloseDownMode(mp_dpy, DestroyAll); - XKillClient(mp_dpy, window); - XSync(mp_dpy, False); - XSetErrorHandler(s_default_error_handler); - XUngrabServer(mp_dpy); + return true; + } + + return false; +} + +bool +XConnection::kill_window(winsys::Window window) +{ + if (!close_window(window)) { + XGrabServer(mp_dpy); + XSetErrorHandler(s_passthrough_error_handler); + XSetCloseDownMode(mp_dpy, DestroyAll); + XKillClient(mp_dpy, window); + XSync(mp_dpy, False); + XSetErrorHandler(s_default_error_handler); + XUngrabServer(mp_dpy); + } return true; }