Commit a7520b36 authored by David Edmundson's avatar David Edmundson
Browse files

Fix activity swtiching through UserActions menu

On wayland the code to keep windows on the current activity whilst the
window was broken was completely broken in porting. We only held the
block for the duration of the method even though the popup remained open
for longer.

On X11, when removing the window from the current activity it would not
update correctly and remain visible. The code path was as follows:
 - the menu is shown an event loop is started
 - we change the activities
- as we close the menu focus changes and workspace calls
UserActionsMenu::close this unsets m_window
- We then never call the blockActivityUpdates(false) at the end of
UserActionsMenu::show

This patch addresses both at once.

We get rid of the nested event loop as that was always evil. This means
slotWindowOperation no longer needs to be queued.

We perform cleanup of m_window and the activity blocker when the menu
closes which should be safer.

BUG: 456873
parent 7b24df24
Pipeline #209550 passed with stage
in 23 minutes and 6 seconds
......@@ -108,7 +108,6 @@ void UserActionsMenu::close()
return;
}
m_menu->close();
m_window.clear();
}
bool UserActionsMenu::isMenuWindow(const Window *window) const
......@@ -136,15 +135,7 @@ void UserActionsMenu::show(const QRect &pos, Window *window)
}
m_window = windowPtr;
init();
m_window->blockActivityUpdates(true);
if (kwinApp()->shouldUseWaylandForCompositing()) {
m_menu->popup(pos.bottomLeft());
} else {
m_menu->exec(pos.bottomLeft());
}
if (m_window) {
m_window->blockActivityUpdates(false);
}
m_menu->popup(pos.bottomLeft());
}
void UserActionsMenu::grabInput()
......@@ -222,7 +213,10 @@ void UserActionsMenu::init()
}
m_menu = new QMenu;
connect(m_menu, &QMenu::aboutToShow, this, &UserActionsMenu::menuAboutToShow);
connect(m_menu, &QMenu::triggered, this, &UserActionsMenu::slotWindowOperation, Qt::QueuedConnection);
// the toplevel menu gets closed before a submenu's action is invoked
connect(m_menu, &QMenu::aboutToHide, this, &UserActionsMenu::menuAboutToHide, Qt::QueuedConnection);
connect(m_menu, &QMenu::triggered, this, &UserActionsMenu::slotWindowOperation);
QMenu *advancedMenu = new QMenu(m_menu);
connect(advancedMenu, &QMenu::aboutToShow, this, [this, advancedMenu]() {
......@@ -361,6 +355,8 @@ void UserActionsMenu::menuAboutToShow()
return;
}
m_window->blockActivityUpdates(true);
if (VirtualDesktopManager::self()->count() == 1) {
delete m_desktopMenu;
m_desktopMenu = nullptr;
......@@ -415,6 +411,14 @@ void UserActionsMenu::menuAboutToShow()
showHideActivityMenu();
}
void UserActionsMenu::menuAboutToHide()
{
if (m_window) {
m_window->blockActivityUpdates(false);
m_window.clear();
}
}
void UserActionsMenu::showHideActivityMenu()
{
#if KWIN_BUILD_ACTIVITIES
......
......@@ -108,6 +108,14 @@ private Q_SLOTS:
* Adjust the items according to the respective Window.
*/
void menuAboutToShow();
/**
* The menu is about to close, all actions have been handled
*
* Perform cleanup
*/
void menuAboutToHide();
/**
* Adjusts the desktop popup to the current values and the location of
* the Window.
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment