162 lines
4.8 KiB
C++
162 lines
4.8 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 <QDebug>
|
|
#include <QApplication>
|
|
#include <QDesktopWidget>
|
|
#include <LXQtGlobalKeys/Action>
|
|
#include <LXQtGlobalKeys/Client>
|
|
#include <QKeyEvent>
|
|
#include <QTimer>
|
|
#include <kwindowsystem.h>
|
|
|
|
#include "app-switcher.h"
|
|
#include "app-model.h"
|
|
#include "app-itemdelegate.h"
|
|
#include "settings.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 = QApplication::desktop()->screenGeometry(QCursor::pos());
|
|
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();
|
|
}
|