fix(xworkspaces): Crash if number of desktops too small

Fixes #2660
This commit is contained in:
patrick96 2022-03-23 14:07:51 +01:00 committed by Patrick Ziegler
parent f2ce3a45c5
commit abfc6b7f91

View File

@ -171,7 +171,7 @@ namespace modules {
void xworkspaces_module::rebuild_urgent_hints() { void xworkspaces_module::rebuild_urgent_hints() {
m_urgent_desktops.assign(m_desktop_names.size(), false); m_urgent_desktops.assign(m_desktop_names.size(), false);
for (auto&& client : ewmh_util::get_client_list()) { for (auto&& client : ewmh_util::get_client_list()) {
auto desk = ewmh_util::get_desktop_from_window(client); uint32_t desk = ewmh_util::get_desktop_from_window(client);
/* /*
* EWMH allows for 0xFFFFFFFF to be returned here, which means the window * EWMH allows for 0xFFFFFFFF to be returned here, which means the window
* should appear on all desktops. * should appear on all desktops.
@ -198,8 +198,8 @@ namespace modules {
* *
* For WMs that don't support that hint, we store an empty vector * For WMs that don't support that hint, we store an empty vector
* *
* If the length of the vector is less than _NET_NUMBER_OF_DESKTOPS * The vector will be padded/reduced to _NET_NUMBER_OF_DESKTOPS.
* all desktops which aren't explicitly assigned a postion will be * All desktops which aren't explicitly assigned a postion will be
* assigned (0, 0) * assigned (0, 0)
* *
* We use this to map workspaces to viewports, desktop i is at position * We use this to map workspaces to viewports, desktop i is at position
@ -207,16 +207,31 @@ namespace modules {
*/ */
vector<position> ws_positions = ewmh_util::get_desktop_viewports(); vector<position> ws_positions = ewmh_util::get_desktop_viewports();
auto num_desktops = m_desktop_names.size();
/* /*
* Not all desktops were assigned a viewport, add (0, 0) for all missing * Not all desktops were assigned a viewport, add (0, 0) for all missing
* desktops. * desktops.
*/ */
if (ws_positions.size() < m_desktop_names.size()) { if (ws_positions.size() < num_desktops) {
auto num_insert = m_desktop_names.size() - ws_positions.size(); auto num_insert = num_desktops - ws_positions.size();
ws_positions.reserve(num_insert); ws_positions.reserve(num_desktops);
std::fill_n(std::back_inserter(ws_positions), num_insert, position{0, 0}); std::fill_n(std::back_inserter(ws_positions), num_insert, position{0, 0});
} }
/*
* If there are too many workspace positions, trim to fit the number of desktops.
*/
if (ws_positions.size() > num_desktops) {
ws_positions.erase(ws_positions.begin() + num_desktops, ws_positions.end());
}
/*
* There must be as many workspace positions as desktops because the indices
* into ws_positions are also used to index into m_desktop_names.
*/
assert(ws_positions.size() == num_desktops);
/* /*
* The list of viewports is the set of unique positions in ws_positions * The list of viewports is the set of unique positions in ws_positions
* Using a set automatically removes duplicates. * Using a set automatically removes duplicates.
@ -252,6 +267,10 @@ namespace modules {
return label; return label;
}(); }();
/*
* Search for all desktops on this viewport and store them in the
* desktop list of the viewport.
*/
for (size_t i = 0; i < ws_positions.size(); i++) { for (size_t i = 0; i < ws_positions.size(); i++) {
auto&& ws_pos = ws_positions[i]; auto&& ws_pos = ws_positions[i];
if (ws_pos == viewport_pos) { if (ws_pos == viewport_pos) {