lxqt-mobile-appswitcher/src/app-switcher.cpp

173 lines
5.0 KiB
C++

/* BEGIN_COMMON_COPYRIGHT_HEADER
* (c)LGPL2+
*
* LXDE-Qt - a lightweight, Qt based, desktop toolset
* https://lxqt.org/
*
* Copyright: 2015 LXQt team
* Authors:
* zjesclean@gmail.com
*
* This program or library is free software; you can redistribute it
* and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General
* Public License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA
*
* END_COMMON_COPYRIGHT_HEADER */
#include "app-itemdelegate.h"
#include "app-model.h"
#include "settings.h"
#include <LXQtGlobalKeys/Action>
#include <LXQtGlobalKeys/Client>
#include <QApplication>
#include <QDebug>
#include <QDesktopWidget>
#include <QKeyEvent>
#include <QScreen>
#include <QTimer>
#include <kwindowsystem.h>
// Should be after Qt headers
#include "app-switcher.h"
AppSwitcher::AppSwitcher(QWidget* parent)
: QListView(parent)
{
setWindowFlags(Qt::Dialog | Qt::WindowStaysOnTopHint | Qt::CustomizeWindowHint);
setObjectName("AppSwitcher");
m_globalShortcut = GlobalKeyShortcut::Client::instance()->addAction(
"Alt+Tab", "/app_switcher/switch", tr("Switch applications"), this);
m_globalRShortcut = GlobalKeyShortcut::Client::instance()->addAction(
"Shift+Alt+Tab", "/app_switcher/rswitch", tr("Reverse switch applications"), this);
connect(m_globalShortcut, &GlobalKeyShortcut::Action::activated, [this] {
if (isVisible()) {
selectItem();
} else {
showSwitcher();
}
});
connect(m_globalRShortcut, &GlobalKeyShortcut::Action::activated, [this] {
if (isVisible()) {
selectItem(false);
} else {
showSwitcher(false);
}
});
setItemDelegate(new AppItemDelegate(this));
setContentsMargins(5, 5, 5, 5);
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
m_timer = new QTimer(this);
m_timer->setInterval(100);
m_timer->setSingleShot(true);
connect(m_timer, &QTimer::timeout, this, &AppSwitcher::timer);
}
void AppSwitcher::showSwitcher(bool forward)
{
Settings::instance().sync();
setModel(new AppModel(this));
dynamic_cast<AppItemDelegate*>(itemDelegate())->init();
m_current = 0;
if (!model()->rowCount()) {
return;
}
QStyleOptionViewItem option;
QFont fnt = font();
if (Settings::instance().customFontSizeEnabled()) {
int fontSize = Settings::instance().customFontSize();
fnt.setPointSize(fontSize);
option.font.setPointSize(fontSize);
} else {
fnt.setPointSize(qApp->font().pointSize());
option.font.setPointSize(qApp->font().pointSize());
}
setFont(fnt);
int w = 0;
int h = 0;
int maxApp = Settings::instance().maxDisplayApps();
for (int i = 0; i < model()->rowCount(); ++i) {
QSize siz = itemDelegate()->sizeHint(option, model()->index(i, 0));
w = qMax(w, siz.width());
h += siz.height();
if (i > maxApp)
break;
}
resize(w + contentsMargins().left() + contentsMargins().right(),
h + contentsMargins().top() + contentsMargins().bottom());
QRect active = QGuiApplication::screenAt(QCursor::pos())->geometry();
move(active.left() + active.width() / 2 - width() / 2, active.top() + active.height() / 2 - height() / 2);
selectItem(forward);
show();
m_timer->start();
}
void AppSwitcher::selectItem(bool forward)
{
m_timer->start();
m_current += forward ? 1 : -1;
if (m_current >= model()->rowCount()) {
m_current = 0;
}
if (m_current < 0) {
m_current = model()->rowCount() - 1;
}
setCurrentIndex(model()->index(m_current, 0));
}
void AppSwitcher::activateWindow(WId id)
{
KWindowInfo info(id, NET::WMDesktop);
if (KWindowSystem::currentDesktop() != info.desktop()) {
KWindowSystem::setCurrentDesktop(info.desktop());
}
KWindowSystem::forceActiveWindow(id);
}
void AppSwitcher::keyReleaseEvent(QKeyEvent* event)
{
if (event->modifiers() == 0) {
close();
activateWindow(model()->data(model()->index(m_current, 0), AppRole::Window).value<WId>());
}
QWidget::keyReleaseEvent(event);
}
void AppSwitcher::timer()
{
if (QApplication::queryKeyboardModifiers() == Qt::NoModifier) {
close();
activateWindow(model()->data(model()->index(m_current, 0), AppRole::Window).value<WId>());
} else {
m_timer->start();
}
}
void AppSwitcher::closeEvent(QCloseEvent*)
{
m_timer->stop();
}