use QWidgetAction for activity setting in alt+f3

not that i really like using QWidgetAction, but it'll
prevent the popup from autoclosing.
Introduce activityUpdateBlocking to prevent users from
removing the popup under their fingertips

BUG: 283309
FIXED-IN: 4.10.2
REVIEW: 107762
This commit is contained in:
Thomas Lübking 2013-03-24 21:57:26 +01:00
parent c43c6f39cf
commit f6bad91b17
3 changed files with 46 additions and 9 deletions

View file

@ -97,6 +97,8 @@ Client::Client(Workspace* ws)
, wrapper(None) , wrapper(None)
, decoration(NULL) , decoration(NULL)
, bridge(new Bridge(this)) , bridge(new Bridge(this))
, m_activityUpdatesBlocked(false)
, m_blockedActivityUpdatesRequireTransients(false)
, move_resize_grab_window(None) , move_resize_grab_window(None)
, move_resize_has_keyboard_grab(false) , move_resize_has_keyboard_grab(false)
, m_managed(false) , m_managed(false)
@ -1548,15 +1550,28 @@ void Client::setOnActivities(QStringList newActivitiesList)
updateActivities(false); updateActivities(false);
} }
void Client::blockActivityUpdates(bool b)
{
if (b) {
++m_activityUpdatesBlocked;
} else {
Q_ASSERT(m_activityUpdatesBlocked);
--m_activityUpdatesBlocked;
if (!m_activityUpdatesBlocked)
updateActivities(m_blockedActivityUpdatesRequireTransients);
}
}
/** /**
* update after activities changed * update after activities changed
*/ */
void Client::updateActivities(bool includeTransients) void Client::updateActivities(bool includeTransients)
{ {
/* FIXME do I need this? if (m_activityUpdatesBlocked) {
if ( decoration != NULL ) m_blockedActivityUpdatesRequireTransients |= includeTransients;
decoration->desktopChange(); return;
*/ }
m_blockedActivityUpdatesRequireTransients = false; // reset
if (includeTransients) if (includeTransients)
workspace()->updateOnAllActivitiesOfTransients(this); workspace()->updateOnAllActivitiesOfTransients(this);
workspace()->updateFocusChains(this, Workspace::FocusChainMakeFirst); workspace()->updateFocusChains(this, Workspace::FocusChainMakeFirst);

View file

@ -363,6 +363,7 @@ public:
void setOnAllActivities(bool set); void setOnAllActivities(bool set);
void setOnActivities(QStringList newActivitiesList); void setOnActivities(QStringList newActivitiesList);
void updateActivities(bool includeTransients); void updateActivities(bool includeTransients);
void blockActivityUpdates(bool b = true);
/// Is not minimized and not hidden. I.e. normally visible on some virtual desktop. /// Is not minimized and not hidden. I.e. normally visible on some virtual desktop.
bool isShown(bool shaded_is_shown) const; bool isShown(bool shaded_is_shown) const;
@ -842,6 +843,8 @@ private:
Bridge* bridge; Bridge* bridge;
int desk; int desk;
QStringList activityList; QStringList activityList;
int m_activityUpdatesBlocked;
bool m_blockedActivityUpdatesRequireTransients;
bool buttonDown; bool buttonDown;
bool moveResizeMode; bool moveResizeMode;
Window move_resize_grab_window; Window move_resize_grab_window;

View file

@ -52,8 +52,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <X11/extensions/xf86vmode.h> #include <X11/extensions/xf86vmode.h>
#endif #endif
#include <fixx11h.h> #include <fixx11h.h>
#include <QCheckBox>
#include <QPushButton> #include <QPushButton>
#include <QSlider>
#include <kglobalsettings.h> #include <kglobalsettings.h>
#include <kiconloader.h> #include <kiconloader.h>
@ -164,9 +164,14 @@ void UserActionsMenu::show(const QRect &pos, const QWeakPointer<Client> &cl)
Workspace *ws = Workspace::self(); Workspace *ws = Workspace::self();
int x = pos.left(); int x = pos.left();
int y = pos.bottom(); int y = pos.bottom();
if (y == pos.top()) if (y == pos.top()) {
m_client.data()->blockActivityUpdates(true);
m_menu->exec(QPoint(x, y)); m_menu->exec(QPoint(x, y));
if (!m_client.isNull())
m_client.data()->blockActivityUpdates(false);
}
else { else {
m_client.data()->blockActivityUpdates(true);
QRect area = ws->clientArea(ScreenArea, QPoint(x, y), ws->currentDesktop()); QRect area = ws->clientArea(ScreenArea, QPoint(x, y), ws->currentDesktop());
menuAboutToShow(); // needed for sizeHint() to be correct :-/ menuAboutToShow(); // needed for sizeHint() to be correct :-/
int popupHeight = m_menu->sizeHint().height(); int popupHeight = m_menu->sizeHint().height();
@ -174,6 +179,8 @@ void UserActionsMenu::show(const QRect &pos, const QWeakPointer<Client> &cl)
m_menu->exec(QPoint(x, y)); m_menu->exec(QPoint(x, y));
else else
m_menu->exec(QPoint(x, pos.top() - popupHeight)); m_menu->exec(QPoint(x, pos.top() - popupHeight));
if (!m_client.isNull())
m_client.data()->blockActivityUpdates(true);
} }
} }
@ -718,13 +725,22 @@ void UserActionsMenu::activityPopupAboutToShow()
KActivities::Info activity(id); KActivities::Info activity(id);
QString name = activity.name(); QString name = activity.name();
name.replace('&', "&&"); name.replace('&', "&&");
action = m_activityMenu->addAction(KIcon(activity.icon()), name); QWidgetAction *action = new QWidgetAction(m_activityMenu);
QCheckBox *box = new QCheckBox(name, m_activityMenu);
action->setDefaultWidget(box);
const QString icon = activity.icon();
if (!icon.isEmpty())
box->setIcon(KIcon(icon));
box->setBackgroundRole(m_activityMenu->backgroundRole());
box->setForegroundRole(m_activityMenu->foregroundRole());
box->setPalette(m_activityMenu->palette());
connect (box, SIGNAL(clicked(bool)), action, SIGNAL(triggered(bool)));
m_activityMenu->addAction(action);
action->setData(id); action->setData(id);
action->setCheckable(true);
if (!m_client.isNull() && if (!m_client.isNull() &&
!m_client.data()->isOnAllActivities() && m_client.data()->isOnActivity(id)) !m_client.data()->isOnAllActivities() && m_client.data()->isOnActivity(id))
action->setChecked(true); box->setChecked(true);
} }
#endif #endif
} }
@ -799,6 +815,9 @@ void UserActionsMenu::slotToggleOnActivity(QAction *action)
} }
Workspace::self()->toggleClientOnActivity(m_client.data(), activity, false); Workspace::self()->toggleClientOnActivity(m_client.data(), activity, false);
if (m_activityMenu && m_activityMenu->isVisible() && m_activityMenu->actions().count()) {
m_activityMenu->actions().at(0)->setChecked(m_client.data()->isOnAllActivities());
}
} }
//**************************************** //****************************************