Skip to content

Commit

Permalink
panel: QMenu positioning workaround for multihead/multipanel setup
Browse files Browse the repository at this point in the history
In multihead & multipanel setup the QMenu::popup/exec sometimes places the window
wrongly (it seems that this bug is somehow connected to misinterpretation
of QDesktopWidget::availableGeometry)

see lxqt/lxqt#613
  • Loading branch information
palinek committed Aug 6, 2015
1 parent 3da78ed commit 29b96a3
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 46 deletions.
1 change: 1 addition & 0 deletions panel/ilxqtpanel.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ class LXQT_PANEL_API ILxQtPanel
Helper functions for calculating global screen position of some popup window with windowSize size.
If you need to show some popup window, you can use it, to get global screen position for the new window.
**/
virtual QRect calculatePopupWindowPos(const QPoint &absolutePos, const QSize &windowSize) const = 0;
virtual QRect calculatePopupWindowPos(const ILxQtPanelPlugin *plugin, const QSize &windowSize) const = 0;
};

Expand Down
58 changes: 33 additions & 25 deletions panel/lxqtpanel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -908,10 +908,10 @@ void LxQtPanel::showEvent(QShowEvent *event)
************************************************/
void LxQtPanel::showPopupMenu(Plugin *plugin)
{
QList<QMenu*> pluginsMenus;
PopupMenu menu(tr("Panel"));
PopupMenu * menu = new PopupMenu(tr("Panel"), this);
menu->setAttribute(Qt::WA_DeleteOnClose);

menu.setIcon(XdgIcon::fromTheme("configure-toolbars"));
menu->setIcon(XdgIcon::fromTheme("configure-toolbars"));

// Plugin Menu ..............................
if (plugin)
Expand All @@ -920,47 +920,51 @@ void LxQtPanel::showPopupMenu(Plugin *plugin)

if (m)
{
menu.addTitle(plugin->windowTitle());
menu.addActions(m->actions());
pluginsMenus << m;
menu->addTitle(plugin->windowTitle());
menu->addActions(m->actions());
qobject_cast<QObject*>(m)->setParent(menu);
}
}

// Panel menu ...............................

menu.addTitle(QIcon(), tr("Panel"));
menu->addTitle(QIcon(), tr("Panel"));

menu.addAction(XdgIcon::fromTheme(QStringLiteral("configure")),
menu->addAction(XdgIcon::fromTheme(QStringLiteral("configure")),
tr("Configure Panel"),
this, SLOT(showConfigDialog())
);

menu.addAction(XdgIcon::fromTheme("preferences-plugin"),
menu->addAction(XdgIcon::fromTheme("preferences-plugin"),
tr("Manage Widgets"),
this, SLOT(showAddPluginDialog())
);

LxQtPanelApplication *a = reinterpret_cast<LxQtPanelApplication*>(qApp);
menu.addAction(XdgIcon::fromTheme(QLatin1String("list-add")),
menu->addAction(XdgIcon::fromTheme(QLatin1String("list-add")),
tr("Add Panel"),
a, SLOT(addNewPanel())
);

if (a->count() > 1)
{
menu.addAction(XdgIcon::fromTheme(QStringLiteral("list-remove")),
menu->addAction(XdgIcon::fromTheme(QStringLiteral("list-remove")),
tr("Remove Panel"),
this, SLOT(userRequestForDeletion())
);
}

#ifdef DEBUG
menu.addSeparator();
menu.addAction("Exit (debug only)", qApp, SLOT(quit()));
menu->addSeparator();
menu->addAction("Exit (debug only)", qApp, SLOT(quit()));
#endif

menu.exec(QCursor::pos());
qDeleteAll(pluginsMenus);
/* Note: in multihead & multipanel setup the QMenu::popup/exec places the window
* sometimes wrongly (it seems that this bug is somehow connected to misinterpretation
* of QDesktopWidget::availableGeometry)
*/
menu->setGeometry(calculatePopupWindowPos(QCursor::pos(), menu->sizeHint()));
menu->show();
}

Plugin* LxQtPanel::findPlugin(const ILxQtPanelPlugin* iPlugin) const
Expand All @@ -975,34 +979,26 @@ Plugin* LxQtPanel::findPlugin(const ILxQtPanelPlugin* iPlugin) const
/************************************************
************************************************/
QRect LxQtPanel::calculatePopupWindowPos(const ILxQtPanelPlugin *plugin, const QSize &windowSize) const
QRect LxQtPanel::calculatePopupWindowPos(QPoint const & absolutePos, QSize const & windowSize) const
{
Plugin *panel_plugin = findPlugin(plugin);
if (nullptr == panel_plugin)
return QRect();

int x=0, y=0;
int x = absolutePos.x(), y = absolutePos.y();

switch (position())
{
case ILxQtPanel::PositionTop:
x = panel_plugin->mapToGlobal(QPoint(0, 0)).x();
y = globalGometry().bottom();
break;

case ILxQtPanel::PositionBottom:
x = panel_plugin->mapToGlobal(QPoint(0, 0)).x();
y = globalGometry().top() - windowSize.height();
break;

case ILxQtPanel::PositionLeft:
x = globalGometry().right();
y = panel_plugin->mapToGlobal(QPoint(0, 0)).y();
break;

case ILxQtPanel::PositionRight:
x = globalGometry().left() - windowSize.width();
y = panel_plugin->mapToGlobal(QPoint(0, 0)).y();
break;
}

Expand All @@ -1028,6 +1024,18 @@ QRect LxQtPanel::calculatePopupWindowPos(const ILxQtPanelPlugin *plugin, const Q
return res;
}

/************************************************
************************************************/
QRect LxQtPanel::calculatePopupWindowPos(const ILxQtPanelPlugin *plugin, const QSize &windowSize) const
{
Plugin *panel_plugin = findPlugin(plugin);
if (nullptr == panel_plugin)
return QRect();

return calculatePopupWindowPos(panel_plugin->mapToGlobal(QPoint(0, 0)), windowSize);
}


/************************************************
Expand Down
1 change: 1 addition & 0 deletions panel/lxqtpanel.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ class LXQT_PANEL_API LxQtPanel : public QFrame, public ILxQtPanel
ILxQtPanel::Position position() const { return mPosition; }
QRect globalGometry() const;
Plugin *findPlugin(const ILxQtPanelPlugin *iPlugin) const;
QRect calculatePopupWindowPos(QPoint const & absolutePos, QSize const & windowSize) const;
QRect calculatePopupWindowPos(const ILxQtPanelPlugin *plugin, const QSize &windowSize) const;

// For QSS properties ..................
Expand Down
2 changes: 1 addition & 1 deletion plugin-taskbar/lxqttaskbar.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@

class LxQtTaskButton;
class ElidedButtonStyle;
class ILxQtPanelPlugin;

namespace LxQt {
class GridLayout;
Expand All @@ -76,6 +75,7 @@ class LxQtTaskBar : public QFrame
bool isAutoRotate() const { return mAutoRotate; }
bool isGroupingEnabled() const { return mGroupingEnabled; }
bool isShowGroupOnHover() const { return mShowGroupOnHover; }
ILxQtPanel * panel() const { return mPlugin->panel(); }

public slots:
void settingsChanged();
Expand Down
34 changes: 18 additions & 16 deletions plugin-taskbar/lxqttaskbutton.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,8 @@ void LxQtTaskButton::contextMenuEvent(QContextMenuEvent* event)
KWindowInfo info(mWindow, 0, NET::WM2AllowedActions);
unsigned long state = KWindowInfo(mWindow, NET::WMState).state();

QMenu menu(tr("Application"));
QMenu * menu = new QMenu(tr("Application"));
menu->setAttribute(Qt::WA_DeleteOnClose);
QAction* a;

/* KDE menu *******
Expand Down Expand Up @@ -474,7 +475,7 @@ void LxQtTaskButton::contextMenuEvent(QContextMenuEvent* event)
if (deskNum > 1)
{
int winDesk = KWindowInfo(mWindow, NET::WMDesktop).desktop();
QMenu* deskMenu = menu.addMenu(tr("To &Desktop"));
QMenu* deskMenu = menu->addMenu(tr("To &Desktop"));

a = deskMenu->addAction(tr("&All Desktops"));
a->setData(NET::OnAllDesktops);
Expand All @@ -491,58 +492,58 @@ void LxQtTaskButton::contextMenuEvent(QContextMenuEvent* event)
}

int curDesk = KWindowSystem::currentDesktop();
a = menu.addAction(tr("&To Current Desktop"));
a = menu->addAction(tr("&To Current Desktop"));
a->setData(curDesk);
a->setEnabled(curDesk != winDesk);
connect(a, SIGNAL(triggered(bool)), this, SLOT(moveApplicationToDesktop()));
}

/********** State menu **********/
menu.addSeparator();
menu->addSeparator();

a = menu.addAction(tr("Ma&ximize"));
a = menu->addAction(tr("Ma&ximize"));
a->setEnabled(info.actionSupported(NET::ActionMax) && (!(state & NET::Max) || (state & NET::Hidden)));
a->setData(NET::Max);
connect(a, SIGNAL(triggered(bool)), this, SLOT(maximizeApplication()));

if (event->modifiers() & Qt::ShiftModifier)
{
a = menu.addAction(tr("Maximize vertically"));
a = menu->addAction(tr("Maximize vertically"));
a->setEnabled(info.actionSupported(NET::ActionMaxVert) && !((state & NET::MaxVert) || (state & NET::Hidden)));
a->setData(NET::MaxVert);
connect(a, SIGNAL(triggered(bool)), this, SLOT(maximizeApplication()));

a = menu.addAction(tr("Maximize horizontally"));
a = menu->addAction(tr("Maximize horizontally"));
a->setEnabled(info.actionSupported(NET::ActionMaxHoriz) && !((state & NET::MaxHoriz) || (state & NET::Hidden)));
a->setData(NET::MaxHoriz);
connect(a, SIGNAL(triggered(bool)), this, SLOT(maximizeApplication()));
}

a = menu.addAction(tr("&Restore"));
a = menu->addAction(tr("&Restore"));
a->setEnabled((state & NET::Hidden) || (state & NET::Max) || (state & NET::MaxHoriz) || (state & NET::MaxVert));
connect(a, SIGNAL(triggered(bool)), this, SLOT(deMaximizeApplication()));

a = menu.addAction(tr("Mi&nimize"));
a = menu->addAction(tr("Mi&nimize"));
a->setEnabled(info.actionSupported(NET::ActionMinimize) && !(state & NET::Hidden));
connect(a, SIGNAL(triggered(bool)), this, SLOT(minimizeApplication()));

if (state & NET::Shaded)
{
a = menu.addAction(tr("Roll down"));
a = menu->addAction(tr("Roll down"));
a->setEnabled(info.actionSupported(NET::ActionShade) && !(state & NET::Hidden));
connect(a, SIGNAL(triggered(bool)), this, SLOT(unShadeApplication()));
}
else
{
a = menu.addAction(tr("Roll up"));
a = menu->addAction(tr("Roll up"));
a->setEnabled(info.actionSupported(NET::ActionShade) && !(state & NET::Hidden));
connect(a, SIGNAL(triggered(bool)), this, SLOT(shadeApplication()));
}

/********** Layer menu **********/
menu.addSeparator();
menu->addSeparator();

QMenu* layerMenu = menu.addMenu(tr("&Layer"));
QMenu* layerMenu = menu->addMenu(tr("&Layer"));

a = layerMenu->addAction(tr("Always on &top"));
// FIXME: There is no info.actionSupported(NET::ActionKeepAbove)
Expand All @@ -563,10 +564,11 @@ void LxQtTaskButton::contextMenuEvent(QContextMenuEvent* event)
connect(a, SIGNAL(triggered(bool)), this, SLOT(setApplicationLayer()));

/********** Kill menu **********/
menu.addSeparator();
a = menu.addAction(XdgIcon::fromTheme("process-stop"), tr("&Close"));
menu->addSeparator();
a = menu->addAction(XdgIcon::fromTheme("process-stop"), tr("&Close"));
connect(a, SIGNAL(triggered(bool)), this, SLOT(closeApplication()));
menu.exec(mapToGlobal(event->pos()));
menu->setGeometry(mParentTaskBar->panel()->calculatePopupWindowPos(mapToGlobal(event->pos()), menu->sizeHint()));
menu->show();
}

/************************************************
Expand Down
12 changes: 8 additions & 4 deletions plugin-taskbar/lxqttaskgroup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,15 @@ void LxQtTaskGroup::contextMenuEvent(QContextMenuEvent *event)
return;
}

QMenu menu(tr("Group"));
QAction *a = menu.addAction(XdgIcon::fromTheme("process-stop"), tr("Close group"));
QMenu * menu = new QMenu(tr("Group"));
menu->setAttribute(Qt::WA_DeleteOnClose);
QAction *a = menu->addAction(XdgIcon::fromTheme("process-stop"), tr("Close group"));
connect(a, SIGNAL(triggered()), this, SLOT(closeGroup()));
menu.exec(mapToGlobal(event->pos()));
mPreventPopup = false;
connect(menu, &QMenu::aboutToHide, [this] {
mPreventPopup = false;
});
menu->setGeometry(mPlugin->panel()->calculatePopupWindowPos(mapToGlobal(event->pos()), menu->sizeHint()));
menu->show();
}

/************************************************
Expand Down

0 comments on commit 29b96a3

Please sign in to comment.