kde-workspace/plasma/applets/windowlist/WindowList.cpp
Ivailo Monev 22bb32d80c generic: replace obsolete Qt::MidButton with Qt::MiddleButton
Signed-off-by: Ivailo Monev <xakepa10@laimg.moc>
2019-05-07 17:23:33 +00:00

313 lines
10 KiB
C++

/***********************************************************************************
* Window List: Plasmoid to show list of opened windows.
* Copyright (C) 2009 Michal Dutkiewicz aka Emdek <emdeck@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
***********************************************************************************/
#include "WindowList.h"
#include <QApplication>
#include <KIcon>
#include <KMenu>
#include <KLocale>
#include <KIconLoader>
#include <KWindowSystem>
#include <Plasma/IconWidget>
#include <Plasma/ToolTipManager>
#include <taskmanager/taskitem.h>
#include <taskmanager/taskactions.h>
#include <taskmanager/taskmanager.h>
#include <taskmanager/groupmanager.h>
K_EXPORT_PLASMA_APPLET(windowlist, WindowList)
WindowList::WindowList(QObject *parent, const QVariantList &args) : Plasma::Applet(parent, args)
{
setAspectRatioMode(Plasma::ConstrainedSquare);
const int iconSize = IconSize(KIconLoader::Desktop);
resize((iconSize * 2), (iconSize * 2));
}
WindowList::~WindowList()
{
qDeleteAll(m_listMenu->actions());
delete m_listMenu;
}
void WindowList::init()
{
Plasma::IconWidget *icon = new Plasma::IconWidget(KIcon("preferences-system-windows"), QString(), this);
m_listMenu = new KWindowListMenu;
m_listMenu->installEventFilter(this);
registerAsDragHandle(icon);
QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(this);
layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(0);
layout->addItem(icon);
Plasma::ToolTipManager::self()->setContent(this, Plasma::ToolTipContent(i18n("Window list"), i18n("Show list of opened windows"), KIcon("preferences-system-windows").pixmap(IconSize(KIconLoader::Desktop))));
connect(this, SIGNAL(activate()), this, SLOT(showMenu()));
connect(this, SIGNAL(destroyed()), m_listMenu, SLOT(deleteLater()));
connect(icon, SIGNAL(clicked()), this, SLOT(showMenu()));
connect(m_listMenu, SIGNAL(triggered(QAction*)), this, SLOT(triggered(QAction*)));
}
void WindowList::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
Applet::mousePressEvent(event);
if (event->button() == Qt::MiddleButton) {
event->accept();
}
}
void WindowList::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
Applet::mouseReleaseEvent(event);
if (event->button() == Qt::MiddleButton) {
showMenu(true);
}
}
void WindowList::wheelEvent(QGraphicsSceneWheelEvent *event)
{
QList<WId> windows = KWindowSystem::windows();
if (windows.count() < 2) {
return;
}
int position = windows.indexOf(KWindowSystem::activeWindow());
if (event->delta() > 0) {
++position;
if (position >= windows.count()) {
position = 0;
}
} else {
--position;
if (position < 0) {
position = (windows.count() - 1);
}
}
KWindowSystem::activateWindow(windows.at(position));
}
bool WindowList::eventFilter(QObject *object, QEvent *event)
{
if (event->type() == QEvent::ContextMenu) {
KMenu *menu = qobject_cast<KMenu*>(object);
if (menu && menu->activeAction() && menu->activeAction()->data().type() == QVariant::ULongLong) {
QContextMenuEvent *cmEvent = static_cast<QContextMenuEvent *>(event);
QList<QAction*> actionList;
TaskManager::TaskItem item(this, TaskManager::TaskManager::self()->findTask((WId)menu->activeAction()->data().toULongLong()));
TaskManager::GroupManager groupManager(this);
TaskManager::BasicMenu taskMenu(NULL, &item, &groupManager, actionList);
if (taskMenu.exec(cmEvent->globalPos())) {
m_listMenu->hide();
}
return true;
}
} else if (event->type() == QEvent::MouseButtonPress) {
QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
if (mouseEvent->button() != Qt::LeftButton) {
return false;
}
KMenu *menu = static_cast<KMenu*>(object);
if (menu && menu->activeAction() && menu->activeAction()->data().type() == QVariant::ULongLong) {
m_dragStartPosition = mouseEvent->pos();
}
} else if (event->type() == QEvent::MouseMove) {
QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
if (!(mouseEvent->buttons() & Qt::LeftButton) || (mouseEvent->pos() - m_dragStartPosition).manhattanLength() < QApplication::startDragDistance()) {
return false;
}
KMenu *menu = static_cast<KMenu*>(object);
if (menu && menu->activeAction() && menu->activeAction()->data().type() == QVariant::ULongLong) {
QDrag *drag = new QDrag(menu);
QMimeData *mimeData = new QMimeData;
QByteArray data;
WId window = (WId)menu->activeAction()->data().toULongLong();
data.resize(sizeof(WId));
memcpy(data.data(), &window, sizeof(WId));
mimeData->setData("windowsystem/winid", data);
drag->setMimeData(mimeData);
drag->setPixmap(menu->activeAction()->icon().pixmap(32, 32));
m_listMenu->hide();
drag->exec();
return true;
}
}
return QObject::eventFilter(object, event);
}
void WindowList::showMenu(bool onlyCurrentDesktop)
{
QList<WId> windows = KWindowSystem::windows();
QList<QAction*> actionList;
QList< QList<QAction*> > windowList;
int amount = 0;
int number = 0;
qDeleteAll(m_listMenu->actions());
//m_listMenu->clear();
if (!onlyCurrentDesktop) {
m_listMenu->addTitle(i18n("Actions"));
QAction *unclutterAction = m_listMenu->addAction(i18n("Unclutter Windows"));
QAction *cascadeAction = m_listMenu->addAction(i18n("Cascade Windows"));
connect(unclutterAction, SIGNAL(triggered()), m_listMenu, SLOT(slotUnclutterWindows()));
connect(cascadeAction, SIGNAL(triggered()), m_listMenu, SLOT(slotCascadeWindows()));
}
for (int i = 0; i <= KWindowSystem::numberOfDesktops(); ++i) {
windowList.append(QList<QAction*>());
}
for (int i = 0; i < windows.count(); ++i) {
KWindowInfo window = KWindowSystem::windowInfo(windows.at(i), (NET::WMGeometry | NET::WMFrameExtents | NET::WMWindowType | NET::WMDesktop | NET::WMState | NET::XAWMState | NET::WMVisibleName));
NET::WindowType type = window.windowType(NET::NormalMask | NET::DialogMask | NET::UtilityMask | NET::DesktopMask | NET::DockMask | NET::SplashMask | NET::ToolbarMask | NET::MenuMask);
if ((onlyCurrentDesktop && !window.isOnDesktop(KWindowSystem::currentDesktop())) || type == NET::Desktop || type == NET::Dock || type == NET::Splash || type == NET::Menu || type == NET::Toolbar || window.hasState(NET::SkipPager)) {
windows.removeAt(i);
--i;
continue;
}
++amount;
QAction *action = new QAction(QIcon(KWindowSystem::icon(windows.at(i))), window.visibleName(), this);
action->setData((unsigned long long) windows.at(i));
QString window_title = QString(action->text());
window_title.truncate(55);
action->setText(window_title);
QFont font = QFont(action->font());
if (window.isMinimized()) {
font.setItalic(true);
} else if (KWindowSystem::activeWindow() == windows.at(i)) {
font.setUnderline(true);
font.setBold(true);
}
action->setFont(font);
number = ((onlyCurrentDesktop || window.onAllDesktops()) ? 0 : window.desktop());
QList<QAction*> subList = windowList.value(number);
subList.append(action);
windowList.replace(number, subList);
}
const bool useSubMenus = (!onlyCurrentDesktop && KWindowSystem::numberOfDesktops() > 1 && (amount / KWindowSystem::numberOfDesktops()) > 5);
if (amount && useSubMenus) {
m_listMenu->addTitle(i18n("Desktops"));
}
for (int i = 0; i <= KWindowSystem::numberOfDesktops(); ++i) {
if (windowList.value(i).isEmpty()) {
continue;
}
KMenu *subMenu = NULL;
QAction *subMenuAction = NULL;
QString title = (i ? KWindowSystem::desktopName(i) : (onlyCurrentDesktop ? i18n("Current desktop") : i18n("On all desktops")));
if (useSubMenus) {
subMenuAction = m_listMenu->addAction(title);
subMenu = new KMenu(m_listMenu);
subMenu->installEventFilter(this);
} else {
m_listMenu->addTitle(title);
}
for (int j = 0; j < windowList.value(i).count(); ++j) {
if (useSubMenus) {
subMenu->addAction(windowList.value(i).value(j));
} else {
m_listMenu->addAction(windowList.value(i).value(j));
}
}
if (useSubMenus) {
subMenuAction->setMenu(subMenu);
}
}
if (!amount) {
qDeleteAll(m_listMenu->actions());
m_listMenu->clear();
QAction *noWindows = m_listMenu->addAction(i18n("No windows"));
noWindows->setEnabled(false);
}
if (formFactor() == Plasma::Vertical || formFactor() == Plasma::Horizontal) {
m_listMenu->popup(popupPosition(m_listMenu->sizeHint()));
} else {
m_listMenu->popup(QCursor::pos());
}
}
void WindowList::triggered(QAction *action)
{
if (action->data().type() == QVariant::ULongLong) {
if (KWindowSystem::activeWindow() == (WId)action->data().toULongLong()) {
KWindowSystem::minimizeWindow((WId)action->data().toULongLong());
} else {
KWindowSystem::activateWindow((WId)action->data().toULongLong());
}
}
}
#include "moc_WindowList.cpp"