mirror of
https://bitbucket.org/smil3y/kde-extraapps.git
synced 2025-02-25 03:12:53 +00:00
1372 lines
46 KiB
C++
1372 lines
46 KiB
C++
/*
|
|
Copyright (C) 2008-2011 by Eike Hein <hein@kde.org>
|
|
Copyright (C) 2009 by Juan Carlos Torres <carlosdgtorres@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) version 3 or any later version
|
|
accepted by the membership of KDE e.V. (or its successor appro-
|
|
ved by the membership of KDE e.V.), which shall act as a proxy
|
|
defined in Section 14 of version 3 of the license.
|
|
|
|
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, see http://www.gnu.org/licenses/.
|
|
*/
|
|
|
|
|
|
#include "mainwindow.h"
|
|
#include "application.h"
|
|
#include "settings.h"
|
|
#include "config/appearancesettings.h"
|
|
#include "config/windowsettings.h"
|
|
#include "firstrundialog.h"
|
|
#include "sessionstack.h"
|
|
#include "skin.h"
|
|
#include "tabbar.h"
|
|
#include "terminal.h"
|
|
#include "titlebar.h"
|
|
#include "ui_behaviorsettings.h"
|
|
|
|
#include <KApplication>
|
|
#include <KConfigDialog>
|
|
#include <KHelpMenu>
|
|
#include <KMenu>
|
|
#include <KMessageBox>
|
|
#include <KNotification>
|
|
#include <KNotifyConfigWidget>
|
|
#include <KPushButton>
|
|
#include <KShortcutsDialog>
|
|
#include <KAction>
|
|
#include <KStandardAction>
|
|
#include <KToggleFullScreenAction>
|
|
#include <KActionCollection>
|
|
#include <KWindowSystem>
|
|
#include <KLocalizedString>
|
|
|
|
#include <QDesktopWidget>
|
|
#include <QPainter>
|
|
#include <QWhatsThis>
|
|
#include <QVarLengthArray>
|
|
#include <QtDBus/QtDBus>
|
|
|
|
#if defined(Q_WS_X11)
|
|
#include <QX11Info>
|
|
|
|
#include <X11/Xlib.h>
|
|
#endif
|
|
|
|
|
|
MainWindow::MainWindow(QWidget* parent)
|
|
: KMainWindow(parent, Qt::CustomizeWindowHint | Qt::FramelessWindowHint)
|
|
{
|
|
QDBusConnection::sessionBus().registerObject("/yakuake/window", this, QDBusConnection::ExportScriptableSlots);
|
|
|
|
setAttribute(Qt::WA_TranslucentBackground, true);
|
|
|
|
m_skin = new Skin();
|
|
m_menu = new KMenu(this);
|
|
m_helpMenu = new KHelpMenu(this, KGlobal::mainComponent().aboutData());
|
|
m_sessionStack = new SessionStack(this);
|
|
m_tabBar = new TabBar(this);
|
|
m_titleBar = new TitleBar(this);
|
|
m_firstRunDialog = NULL;
|
|
m_listenForActivationChanges = false;
|
|
|
|
#if defined(Q_WS_X11)
|
|
m_kwinAssistPropSet = false;
|
|
#endif
|
|
|
|
setupActions();
|
|
setupMenu();
|
|
|
|
connect(m_tabBar, SIGNAL(newTabRequested()), m_sessionStack, SLOT(addSession()));
|
|
connect(m_tabBar, SIGNAL(lastTabClosed()), m_tabBar, SIGNAL(newTabRequested()));
|
|
connect(m_tabBar, SIGNAL(lastTabClosed()), this, SLOT(handleLastTabClosed()));
|
|
connect(m_tabBar, SIGNAL(tabSelected(int)), m_sessionStack, SLOT(raiseSession(int)));
|
|
connect(m_tabBar, SIGNAL(tabClosed(int)), m_sessionStack, SLOT(removeSession(int)));
|
|
connect(m_tabBar, SIGNAL(requestTerminalHighlight(int)), m_sessionStack, SLOT(handleTerminalHighlightRequest(int)));
|
|
connect(m_tabBar, SIGNAL(requestRemoveTerminalHighlight()), m_sessionStack, SIGNAL(removeTerminalHighlight()));
|
|
connect(m_tabBar, SIGNAL(tabContextMenuClosed()), m_sessionStack, SIGNAL(removeTerminalHighlight()));
|
|
|
|
connect(m_sessionStack, SIGNAL(sessionAdded(int,QString)),
|
|
m_tabBar, SLOT(addTab(int,QString)));
|
|
connect(m_sessionStack, SIGNAL(sessionRaised(int)), m_tabBar, SLOT(selectTab(int)));
|
|
connect(m_sessionStack, SIGNAL(sessionRemoved(int)), m_tabBar, SLOT(removeTab(int)));
|
|
connect(m_sessionStack, SIGNAL(activeTitleChanged(QString)),
|
|
m_titleBar, SLOT(setTitle(QString)));
|
|
|
|
connect(&m_mousePoller, SIGNAL(timeout()), this, SLOT(pollMouse()));
|
|
|
|
connect(KWindowSystem::self(), SIGNAL(workAreaChanged()), this, SLOT(applyWindowGeometry()));
|
|
connect(KApplication::desktop(), SIGNAL(screenCountChanged(int)), this, SLOT(updateScreenMenu()));
|
|
|
|
applySettings();
|
|
|
|
m_sessionStack->addSession();
|
|
|
|
if (Settings::firstRun())
|
|
{
|
|
QMetaObject::invokeMethod(this, "toggleWindowState", Qt::QueuedConnection);
|
|
QMetaObject::invokeMethod(this, "showFirstRunDialog", Qt::QueuedConnection);
|
|
}
|
|
else
|
|
{
|
|
showStartupPopup();
|
|
if (Settings::pollMouse()) toggleMousePoll(true);
|
|
}
|
|
|
|
if (Settings::openAfterStart())
|
|
QMetaObject::invokeMethod(this, "toggleWindowState", Qt::QueuedConnection);
|
|
}
|
|
|
|
MainWindow::~MainWindow()
|
|
{
|
|
Settings::self()->writeConfig();
|
|
|
|
delete m_skin;
|
|
}
|
|
|
|
bool MainWindow::queryClose()
|
|
{
|
|
bool confirmQuit = Settings::confirmQuit();
|
|
bool hasUnclosableSessions = m_sessionStack->hasUnclosableSessions();
|
|
|
|
QString closeQuestion = i18nc("@info","Are you sure you want to quit?");
|
|
QString warningMessage;
|
|
|
|
if ((confirmQuit && m_sessionStack->count() > 1) || hasUnclosableSessions)
|
|
{
|
|
if (confirmQuit && m_sessionStack->count() > 1)
|
|
{
|
|
if (hasUnclosableSessions)
|
|
warningMessage = i18nc("@info", "<warning>There are multiple open sessions, <emphasis>some of which you have locked to prevent closing them accidentally.</emphasis> These will be killed if you continue.</warning>");
|
|
else
|
|
warningMessage = i18nc("@info", "<warning>There are multiple open sessions. These will be killed if you continue.</warning>");
|
|
}
|
|
else if (hasUnclosableSessions)
|
|
{
|
|
warningMessage = i18nc("@info", "<warning>There are one or more open sessions that you have locked to prevent closing them accidentally. These will be killed if you continue.</warning>");
|
|
}
|
|
|
|
int result = KMessageBox::warningContinueCancel(this,
|
|
warningMessage + "<br /><br />" + closeQuestion,
|
|
i18nc("@title:window", "Really Quit?"), KStandardGuiItem::quit(), KStandardGuiItem::cancel());
|
|
|
|
if (result == KMessageBox::Continue)
|
|
return true;
|
|
else
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void MainWindow::setupActions()
|
|
{
|
|
m_actionCollection = new KActionCollection(this);
|
|
|
|
KToggleFullScreenAction* fullScreenAction = new KToggleFullScreenAction(this);
|
|
fullScreenAction->setWindow(this);
|
|
fullScreenAction->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_F11));
|
|
m_actionCollection->addAction("view-full-screen", fullScreenAction);
|
|
connect(fullScreenAction, SIGNAL(toggled(bool)), this, SLOT(setFullScreen(bool)));
|
|
|
|
KAction* action = KStandardAction::quit(this, SLOT(close()), actionCollection());
|
|
action->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_Q));
|
|
|
|
action = KStandardAction::aboutApp(m_helpMenu, SLOT(aboutApplication()), actionCollection());
|
|
action = KStandardAction::reportBug(m_helpMenu, SLOT(reportBug()), actionCollection());
|
|
action = KStandardAction::aboutKDE(m_helpMenu, SLOT(aboutKDE()), actionCollection());
|
|
|
|
action = KStandardAction::keyBindings(this, SLOT(configureKeys()), actionCollection());
|
|
action = KStandardAction::configureNotifications(this, SLOT(configureNotifications()), actionCollection());
|
|
action = KStandardAction::preferences(this, SLOT(configureApp()), actionCollection());
|
|
|
|
action = KStandardAction::whatsThis(this, SLOT(whatsThis()), actionCollection());
|
|
|
|
action = actionCollection()->addAction("toggle-window-state");
|
|
action->setText(i18nc("@action", "Open/Retract Yakuake"));
|
|
action->setIcon(KIcon("yakuake"));
|
|
action->setGlobalShortcut(KShortcut(Qt::Key_F12));
|
|
connect(action, SIGNAL(triggered()), this, SLOT(toggleWindowState()));
|
|
|
|
action = actionCollection()->addAction("keep-open");
|
|
action->setText(i18nc("@action", "Keep window open when it loses focus"));
|
|
action->setCheckable(true);
|
|
connect(action, SIGNAL(toggled(bool)), this, SLOT(setKeepOpen(bool)));
|
|
|
|
action = actionCollection()->addAction("manage-profiles");
|
|
action->setText(i18nc("@action", "Manage Profiles..."));
|
|
action->setIcon(KIcon("configure"));
|
|
connect(action, SIGNAL(triggered()), m_sessionStack, SIGNAL(manageProfiles()));
|
|
|
|
action = actionCollection()->addAction("edit-profile");
|
|
action->setText(i18nc("@action", "Edit Current Profile..."));
|
|
action->setIcon(KIcon("document-properties"));
|
|
connect(action, SIGNAL(triggered()), this, SLOT(handleContextDependentAction()));
|
|
m_contextDependentActions << action;
|
|
|
|
action = actionCollection()->addAction("increase-window-width");
|
|
action->setText(i18nc("@action", "Increase Window Width"));
|
|
action->setShortcut(QKeySequence(Qt::ALT + Qt::SHIFT + Qt::Key_Right));
|
|
connect(action, SIGNAL(triggered()), this, SLOT(increaseWindowWidth()));
|
|
|
|
action = actionCollection()->addAction("decrease-window-width");
|
|
action->setText(i18nc("@action", "Decrease Window Width"));
|
|
action->setShortcut(QKeySequence(Qt::ALT + Qt::SHIFT + Qt::Key_Left));
|
|
connect(action, SIGNAL(triggered()), this, SLOT(decreaseWindowWidth()));
|
|
|
|
action = actionCollection()->addAction("increase-window-height");
|
|
action->setText(i18nc("@action", "Increase Window Height"));
|
|
action->setShortcut(QKeySequence(Qt::ALT + Qt::SHIFT + Qt::Key_Down));
|
|
connect(action, SIGNAL(triggered()), this, SLOT(increaseWindowHeight()));
|
|
|
|
action = actionCollection()->addAction("decrease-window-height");
|
|
action->setText(i18nc("@action", "Decrease Window Height"));
|
|
action->setShortcut(QKeySequence(Qt::ALT + Qt::SHIFT + Qt::Key_Up));
|
|
connect(action, SIGNAL(triggered()), this, SLOT(decreaseWindowHeight()));
|
|
|
|
action = actionCollection()->addAction("new-session");
|
|
action->setText(i18nc("@action", "New Session"));
|
|
action->setIcon(KIcon("tab-new"));
|
|
action->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_T));
|
|
connect(action, SIGNAL(triggered()), m_sessionStack, SLOT(addSession()));
|
|
|
|
action = actionCollection()->addAction("new-session-two-horizontal");
|
|
action->setText(i18nc("@action", "Two Terminals, Horizontally"));
|
|
action->setIcon(KIcon("tab-new"));
|
|
connect(action, SIGNAL(triggered()), m_sessionStack, SLOT(addSessionTwoHorizontal()));
|
|
|
|
action = actionCollection()->addAction("new-session-two-vertical");
|
|
action->setText(i18nc("@action", "Two Terminals, Vertically"));
|
|
action->setIcon(KIcon("tab-new"));
|
|
connect(action, SIGNAL(triggered()), m_sessionStack, SLOT(addSessionTwoVertical()));
|
|
|
|
action = actionCollection()->addAction("new-session-quad");
|
|
action->setText(i18nc("@action", "Four Terminals, Grid"));
|
|
action->setIcon(KIcon("tab-new"));
|
|
connect(action, SIGNAL(triggered()), m_sessionStack, SLOT(addSessionQuad()));
|
|
|
|
action = actionCollection()->addAction("close-session");
|
|
action->setText(i18nc("@action", "Close Session"));
|
|
action->setIcon(KIcon("tab-close"));
|
|
action->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_W));
|
|
connect(action, SIGNAL(triggered()), this, SLOT(handleContextDependentAction()));
|
|
m_contextDependentActions << action;
|
|
|
|
action = actionCollection()->addAction("previous-session");
|
|
action->setText(i18nc("@action", "Previous Session"));
|
|
action->setIcon(KIcon("go-previous"));
|
|
action->setShortcut(QKeySequence(Qt::SHIFT + Qt::Key_Left));
|
|
connect(action, SIGNAL(triggered()), m_tabBar, SLOT(selectPreviousTab()));
|
|
|
|
action = actionCollection()->addAction("next-session");
|
|
action->setText(i18nc("@action", "Next Session"));
|
|
action->setIcon(KIcon("go-next"));
|
|
action->setShortcut(QKeySequence(Qt::SHIFT + Qt::Key_Right));
|
|
connect(action, SIGNAL(triggered()), m_tabBar, SLOT(selectNextTab()));
|
|
|
|
action = actionCollection()->addAction("move-session-left");
|
|
action->setText(i18nc("@action", "Move Session Left"));
|
|
action->setIcon(KIcon("arrow-left"));
|
|
action->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_Left));
|
|
connect(action, SIGNAL(triggered()), this, SLOT(handleContextDependentAction()));
|
|
m_contextDependentActions << action;
|
|
|
|
action = actionCollection()->addAction("move-session-right");
|
|
action->setText(i18nc("@action", "Move Session Right"));
|
|
action->setIcon(KIcon("arrow-right"));
|
|
action->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_Right));
|
|
connect(action, SIGNAL(triggered()), this, SLOT(handleContextDependentAction()));
|
|
m_contextDependentActions << action;
|
|
|
|
action = actionCollection()->addAction("grow-terminal-right");
|
|
action->setText(i18nc("@action", "Grow Terminal to the Right"));
|
|
action->setIcon(KIcon("arrow-right"));
|
|
action->setShortcut(QKeySequence(Qt::CTRL + Qt::ALT + Qt::Key_Right));
|
|
connect(action, SIGNAL(triggered()), this, SLOT(handleContextDependentAction()));
|
|
m_contextDependentActions << action;
|
|
|
|
action = actionCollection()->addAction("grow-terminal-left");
|
|
action->setText(i18nc("@action", "Grow Terminal to the Left"));
|
|
action->setIcon(KIcon("arrow-left"));
|
|
action->setShortcut(QKeySequence(Qt::CTRL + Qt::ALT + Qt::Key_Left));
|
|
connect(action, SIGNAL(triggered()), this, SLOT(handleContextDependentAction()));
|
|
m_contextDependentActions << action;
|
|
|
|
action = actionCollection()->addAction("grow-terminal-top");
|
|
action->setText(i18nc("@action", "Grow Terminal to the Top"));
|
|
action->setIcon(KIcon("arrow-up"));
|
|
action->setShortcut(QKeySequence(Qt::CTRL + Qt::ALT + Qt::Key_Up));
|
|
connect(action, SIGNAL(triggered()), this, SLOT(handleContextDependentAction()));
|
|
m_contextDependentActions << action;
|
|
|
|
action = actionCollection()->addAction("grow-terminal-bottom");
|
|
action->setText(i18nc("@action", "Grow Terminal to the Bottom"));
|
|
action->setIcon(KIcon("arrow-down"));
|
|
action->setShortcut(QKeySequence(Qt::CTRL + Qt::ALT + Qt::Key_Down));
|
|
connect(action, SIGNAL(triggered()), this, SLOT(handleContextDependentAction()));
|
|
m_contextDependentActions << action;
|
|
|
|
action = actionCollection()->addAction("rename-session");
|
|
action->setText(i18nc("@action", "Rename Session..."));
|
|
action->setIcon(KIcon("edit-rename"));
|
|
action->setShortcut(QKeySequence(Qt::CTRL + Qt::ALT + Qt::Key_S));
|
|
connect(action, SIGNAL(triggered()), this, SLOT(handleContextDependentAction()));
|
|
m_contextDependentActions << action;
|
|
|
|
action = actionCollection()->addAction("previous-terminal");
|
|
action->setText(i18nc("@action", "Previous Terminal"));
|
|
action->setIcon(KIcon("go-previous"));
|
|
action->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_Up));
|
|
connect(action, SIGNAL(triggered()), m_sessionStack, SIGNAL(previousTerminal()));
|
|
|
|
action = actionCollection()->addAction("next-terminal");
|
|
action->setText(i18nc("@action", "Next Terminal"));
|
|
action->setIcon(KIcon("go-next"));
|
|
action->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_Down));
|
|
connect(action, SIGNAL(triggered()), m_sessionStack, SIGNAL(nextTerminal()));
|
|
|
|
action = actionCollection()->addAction("close-active-terminal");
|
|
action->setText(i18nc("@action", "Close Active Terminal"));
|
|
action->setIcon(KIcon("view-close"));
|
|
action->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_R));
|
|
connect(action, SIGNAL(triggered()), this, SLOT(handleContextDependentAction()));
|
|
m_contextDependentActions << action;
|
|
|
|
action = actionCollection()->addAction("split-left-right");
|
|
action->setText(i18nc("@action", "Split Left/Right"));
|
|
action->setIcon(KIcon("view-split-left-right"));
|
|
action->setShortcut(QKeySequence(Qt::CTRL+ Qt::Key_ParenLeft));
|
|
connect(action, SIGNAL(triggered()), this, SLOT(handleContextDependentAction()));
|
|
m_contextDependentActions << action;
|
|
|
|
action = actionCollection()->addAction("split-top-bottom");
|
|
action->setText(i18nc("@action", "Split Top/Bottom"));
|
|
action->setIcon(KIcon("view-split-top-bottom"));
|
|
action->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_ParenRight));
|
|
connect(action, SIGNAL(triggered()), this, SLOT(handleContextDependentAction()));
|
|
m_contextDependentActions << action;
|
|
|
|
action = actionCollection()->addAction("toggle-session-prevent-closing");
|
|
action->setText(i18nc("@action", "Prevent Closing"));
|
|
action->setCheckable(true);
|
|
connect(action, SIGNAL(triggered(bool)), this, SLOT(handleContextDependentToggleAction(bool)));
|
|
m_contextDependentActions << action;
|
|
|
|
action = actionCollection()->addAction("toggle-session-keyboard-input");
|
|
action->setText(i18nc("@action", "Disable Keyboard Input"));
|
|
action->setCheckable(true);
|
|
connect(action, SIGNAL(triggered(bool)), this, SLOT(handleContextDependentToggleAction(bool)));
|
|
m_contextDependentActions << action;
|
|
|
|
action = actionCollection()->addAction("toggle-session-monitor-activity");
|
|
action->setText(i18nc("@action", "Monitor for Activity"));
|
|
action->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_A));
|
|
action->setCheckable(true);
|
|
connect(action, SIGNAL(triggered(bool)), this, SLOT(handleContextDependentToggleAction(bool)));
|
|
m_contextDependentActions << action;
|
|
|
|
action = actionCollection()->addAction("toggle-session-monitor-silence");
|
|
action->setText(i18nc("@action", "Monitor for Silence"));
|
|
action->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_I));
|
|
action->setCheckable(true);
|
|
connect(action, SIGNAL(triggered(bool)), this, SLOT(handleContextDependentToggleAction(bool)));
|
|
m_contextDependentActions << action;
|
|
|
|
for (uint i = 1; i <= 10; ++i)
|
|
{
|
|
action = actionCollection()->addAction(QString("switch-to-session-%1").arg(i));
|
|
action->setText(i18nc("@action", "Switch to Session <numid>%1</numid>", i));
|
|
action->setData(i);
|
|
connect(action, SIGNAL(triggered()), this, SLOT(handleSwitchToAction()));
|
|
}
|
|
|
|
m_actionCollection->associateWidget(this);
|
|
m_actionCollection->readSettings();
|
|
}
|
|
|
|
void MainWindow::handleContextDependentAction(QAction* action, int sessionId)
|
|
{
|
|
if (sessionId == -1) sessionId = m_sessionStack->activeSessionId();
|
|
if (sessionId == -1) return;
|
|
|
|
if (!action) action = qobject_cast<QAction*>(QObject::sender());
|
|
|
|
if (action == actionCollection()->action("edit-profile"))
|
|
m_sessionStack->editProfile(sessionId);
|
|
|
|
if (action == actionCollection()->action("close-session"))
|
|
m_sessionStack->removeSession(sessionId);
|
|
|
|
if (action == actionCollection()->action("move-session-left"))
|
|
m_tabBar->moveTabLeft(sessionId);
|
|
|
|
if (action == actionCollection()->action("move-session-right"))
|
|
m_tabBar->moveTabRight(sessionId);
|
|
|
|
if (action == actionCollection()->action("rename-session"))
|
|
m_tabBar->interactiveRename(sessionId);
|
|
|
|
if (action == actionCollection()->action("close-active-terminal"))
|
|
m_sessionStack->closeActiveTerminal(sessionId);
|
|
|
|
if (action == actionCollection()->action("split-left-right"))
|
|
m_sessionStack->splitSessionLeftRight(sessionId);
|
|
|
|
if (action == actionCollection()->action("split-top-bottom"))
|
|
m_sessionStack->splitSessionTopBottom(sessionId);
|
|
|
|
if (action == actionCollection()->action("grow-terminal-right"))
|
|
m_sessionStack->tryGrowTerminalRight(m_sessionStack->activeTerminalId());
|
|
|
|
if (action == actionCollection()->action("grow-terminal-left"))
|
|
m_sessionStack->tryGrowTerminalLeft(m_sessionStack->activeTerminalId());
|
|
|
|
if (action == actionCollection()->action("grow-terminal-top"))
|
|
m_sessionStack->tryGrowTerminalTop(m_sessionStack->activeTerminalId());
|
|
|
|
if (action == actionCollection()->action("grow-terminal-bottom"))
|
|
m_sessionStack->tryGrowTerminalBottom(m_sessionStack->activeTerminalId());
|
|
}
|
|
|
|
void MainWindow::handleContextDependentToggleAction(bool checked, QAction* action, int sessionId)
|
|
{
|
|
if (sessionId == -1) sessionId = m_sessionStack->activeSessionId();
|
|
if (sessionId == -1) return;
|
|
|
|
if (!action) action = qobject_cast<QAction*>(QObject::sender());
|
|
|
|
if (action == actionCollection()->action("toggle-session-prevent-closing")) {
|
|
m_sessionStack->setSessionClosable(sessionId, !checked);
|
|
|
|
// Repaint the tab bar when the Prevent Closing action is toggled
|
|
// so the lock icon is added to or removed from the tab label.
|
|
m_tabBar->repaint();
|
|
}
|
|
|
|
if (action == actionCollection()->action("toggle-session-keyboard-input"))
|
|
m_sessionStack->setSessionKeyboardInputEnabled(sessionId, !checked);
|
|
|
|
if (action == actionCollection()->action("toggle-session-monitor-activity"))
|
|
m_sessionStack->setSessionMonitorActivityEnabled(sessionId, checked);
|
|
|
|
if (action == actionCollection()->action("toggle-session-monitor-silence"))
|
|
m_sessionStack->setSessionMonitorSilenceEnabled(sessionId, checked);
|
|
}
|
|
|
|
void MainWindow::setContextDependentActionsQuiet(bool quiet)
|
|
{
|
|
QListIterator<KAction*> i(m_contextDependentActions);
|
|
|
|
while (i.hasNext()) i.next()->blockSignals(quiet);
|
|
}
|
|
|
|
void MainWindow::handleToggleTerminalKeyboardInput(bool checked)
|
|
{
|
|
QAction* action = qobject_cast<QAction*>(QObject::sender());
|
|
|
|
if (!action || action->data().isNull()) return;
|
|
|
|
bool ok = false;
|
|
int terminalId = action->data().toInt(&ok);
|
|
if (!ok) return;
|
|
|
|
m_sessionStack->setTerminalKeyboardInputEnabled(terminalId, !checked);
|
|
}
|
|
|
|
void MainWindow::handleToggleTerminalMonitorActivity(bool checked)
|
|
{
|
|
QAction* action = qobject_cast<QAction*>(QObject::sender());
|
|
|
|
if (!action || action->data().isNull()) return;
|
|
|
|
bool ok = false;
|
|
int terminalId = action->data().toInt(&ok);
|
|
if (!ok) return;
|
|
|
|
m_sessionStack->setTerminalMonitorActivityEnabled(terminalId, checked);
|
|
}
|
|
|
|
void MainWindow::handleToggleTerminalMonitorSilence(bool checked)
|
|
{
|
|
QAction* action = qobject_cast<QAction*>(QObject::sender());
|
|
|
|
if (!action || action->data().isNull()) return;
|
|
|
|
bool ok = false;
|
|
int terminalId = action->data().toInt(&ok);
|
|
if (!ok) return;
|
|
|
|
m_sessionStack->setTerminalMonitorSilenceEnabled(terminalId, checked);
|
|
}
|
|
|
|
void MainWindow::handleTerminalActivity(Terminal* terminal)
|
|
{
|
|
Session* session = qobject_cast<Session*>(sender());
|
|
|
|
if (session)
|
|
{
|
|
disconnect(terminal, SIGNAL(activityDetected(Terminal*)), session, SIGNAL(activityDetected(Terminal*)));
|
|
|
|
QString message(i18nc("@info", "Activity detected in monitored terminal in session \"%1\".",
|
|
m_tabBar->tabTitle(session->id())));
|
|
|
|
KNotification::event(QLatin1String("activity"), message, QPixmap(), terminal->partWidget(),
|
|
KNotification::CloseWhenWidgetActivated);
|
|
}
|
|
}
|
|
|
|
void MainWindow::handleTerminalSilence(Terminal* terminal)
|
|
{
|
|
Session* session = qobject_cast<Session*>(sender());
|
|
|
|
if (session)
|
|
{
|
|
QString message(i18nc("@info", "Silence detected in monitored terminal in session \"%1\".",
|
|
m_tabBar->tabTitle(session->id())));
|
|
|
|
KNotification::event(QLatin1String("silence"), message, QPixmap(), terminal->partWidget(),
|
|
KNotification::CloseWhenWidgetActivated);
|
|
}
|
|
}
|
|
|
|
void MainWindow::handleLastTabClosed()
|
|
{
|
|
if (isVisible())
|
|
toggleWindowState();
|
|
}
|
|
|
|
void MainWindow::handleSwitchToAction()
|
|
{
|
|
QAction* action = qobject_cast<QAction*>(QObject::sender());
|
|
|
|
if (action && !action->data().isNull())
|
|
m_sessionStack->raiseSession(m_tabBar->sessionAtTab(action->data().toInt()-1));
|
|
}
|
|
|
|
void MainWindow::setupMenu()
|
|
{
|
|
m_menu->addTitle(i18nc("@title:menu", "Help"));
|
|
m_menu->addAction(actionCollection()->action(KStandardAction::name(KStandardAction::WhatsThis)));
|
|
m_menu->addAction(actionCollection()->action(KStandardAction::name(KStandardAction::ReportBug)));
|
|
m_menu->addAction(actionCollection()->action(KStandardAction::name(KStandardAction::AboutApp)));
|
|
m_menu->addAction(actionCollection()->action(KStandardAction::name(KStandardAction::AboutKDE)));
|
|
|
|
m_menu->addTitle(i18nc("@title:menu", "Quick Options"));
|
|
m_menu->addAction(actionCollection()->action("view-full-screen"));
|
|
m_menu->addAction(actionCollection()->action("keep-open"));
|
|
|
|
m_screenMenu = new KMenu(this);
|
|
connect(m_screenMenu, SIGNAL(triggered(QAction*)), this, SLOT(setScreen(QAction*)));
|
|
m_screenMenu->setTitle(i18nc("@title:menu", "Screen"));
|
|
m_menu->addMenu(m_screenMenu);
|
|
|
|
m_windowWidthMenu = new KMenu(this);
|
|
connect(m_windowWidthMenu, SIGNAL(triggered(QAction*)), this, SLOT(setWindowWidth(QAction*)));
|
|
m_windowWidthMenu->setTitle(i18nc("@title:menu", "Width"));
|
|
m_menu->addMenu(m_windowWidthMenu);
|
|
|
|
m_windowHeightMenu = new KMenu(this);
|
|
connect(m_windowHeightMenu, SIGNAL(triggered(QAction*)), this, SLOT(setWindowHeight(QAction*)));
|
|
m_windowHeightMenu->setTitle(i18nc("@title:menu", "Height"));
|
|
m_menu->addMenu(m_windowHeightMenu);
|
|
|
|
m_menu->addTitle(i18nc("@title:menu", "Settings"));
|
|
m_menu->addAction(actionCollection()->action("manage-profiles"));
|
|
m_menu->addAction(actionCollection()->action(KStandardAction::name(KStandardAction::KeyBindings)));
|
|
m_menu->addAction(actionCollection()->action(KStandardAction::name(KStandardAction::ConfigureNotifications)));
|
|
m_menu->addAction(actionCollection()->action(KStandardAction::name(KStandardAction::Preferences)));
|
|
}
|
|
|
|
void MainWindow::updateScreenMenu()
|
|
{
|
|
QAction* action;
|
|
|
|
m_screenMenu->clear();
|
|
|
|
action = m_screenMenu->addAction(i18nc("@item:inmenu", "At mouse location"));
|
|
action->setCheckable(true);
|
|
action->setData(0);
|
|
action->setChecked(Settings::screen() == 0);
|
|
|
|
const int screencount = KApplication::desktop()->screenCount();
|
|
for (int i = 1; i <= screencount; i++)
|
|
{
|
|
action = m_screenMenu->addAction(i18nc("@item:inmenu", "Screen <numid>%1</numid>", i));
|
|
action->setCheckable(true);
|
|
action->setData(i);
|
|
action->setChecked(i == Settings::screen());
|
|
}
|
|
|
|
action = m_screenMenu->menuAction();
|
|
action->setVisible(screencount > 1);
|
|
}
|
|
|
|
void MainWindow::updateWindowSizeMenus()
|
|
{
|
|
updateWindowWidthMenu();
|
|
updateWindowHeightMenu();
|
|
}
|
|
|
|
void MainWindow::updateWindowWidthMenu()
|
|
{
|
|
QAction* action = 0;
|
|
|
|
if (m_windowWidthMenu->isEmpty())
|
|
{
|
|
for (int i = 10; i <= 100; i += 10)
|
|
{
|
|
action = m_windowWidthMenu->addAction(QString::number(i) + '%');
|
|
action->setCheckable(true);
|
|
action->setData(i);
|
|
action->setChecked(i == Settings::width());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
QListIterator<QAction*> i(m_windowWidthMenu->actions());
|
|
|
|
while (i.hasNext())
|
|
{
|
|
action = i.next();
|
|
|
|
action->setChecked(action->data().toInt() == Settings::width());
|
|
}
|
|
}
|
|
}
|
|
|
|
void MainWindow::updateWindowHeightMenu()
|
|
{
|
|
QAction* action = 0;
|
|
|
|
if (m_windowHeightMenu->isEmpty())
|
|
{
|
|
for (int i = 10; i <= 100; i += 10)
|
|
{
|
|
action = m_windowHeightMenu->addAction(QString::number(i) + '%');
|
|
action->setCheckable(true);
|
|
action->setData(i);
|
|
action->setChecked(i == Settings::height());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
QListIterator<QAction*> i(m_windowHeightMenu->actions());
|
|
|
|
while (i.hasNext())
|
|
{
|
|
action = i.next();
|
|
|
|
action->setChecked(action->data().toInt() == Settings::height());
|
|
}
|
|
}
|
|
}
|
|
|
|
void MainWindow::configureKeys()
|
|
{
|
|
KShortcutsDialog::configure(actionCollection());
|
|
}
|
|
|
|
void MainWindow::configureNotifications()
|
|
{
|
|
KNotifyConfigWidget::configure(this);
|
|
}
|
|
|
|
void MainWindow::configureApp()
|
|
{
|
|
if (KConfigDialog::showDialog("settings")) return;
|
|
|
|
KConfigDialog* settingsDialog = new KConfigDialog(this, "settings", Settings::self());
|
|
settingsDialog->setFaceType(KPageDialog::List);
|
|
connect(settingsDialog, SIGNAL(settingsChanged(QString)), this, SLOT(applySettings()));
|
|
connect(settingsDialog, SIGNAL(hidden()), this, SLOT(activate()));
|
|
|
|
WindowSettings* windowSettings = new WindowSettings(settingsDialog);
|
|
settingsDialog->addPage(windowSettings, i18nc("@title Preferences page name", "Window"), "yakuake");
|
|
connect(windowSettings, SIGNAL(updateWindowGeometry(int,int,int)),
|
|
this, SLOT(setWindowGeometry(int,int,int)));
|
|
|
|
QWidget* behaviorSettings = new QWidget(settingsDialog);
|
|
Ui::BehaviorSettings behaviorSettingsUi;
|
|
behaviorSettingsUi.setupUi(behaviorSettings);
|
|
settingsDialog->addPage(behaviorSettings, i18nc("@title Preferences page name", "Behavior"),
|
|
"preferences-other");
|
|
|
|
AppearanceSettings* appearanceSettings = new AppearanceSettings(settingsDialog);
|
|
settingsDialog->addPage(appearanceSettings, i18nc("@title Preferences page name", "Appearance"),
|
|
"preferences-desktop-theme");
|
|
connect(appearanceSettings, SIGNAL(settingsChanged()), this, SLOT(applySettings()));
|
|
connect(settingsDialog, SIGNAL(closeClicked()), appearanceSettings, SLOT(resetSelection()));
|
|
connect(settingsDialog, SIGNAL(cancelClicked()), appearanceSettings, SLOT(resetSelection()));
|
|
|
|
settingsDialog->button(KDialog::Help)->hide();
|
|
|
|
settingsDialog->show();
|
|
}
|
|
|
|
void MainWindow::applySettings()
|
|
{
|
|
if (Settings::dynamicTabTitles())
|
|
{
|
|
connect(m_sessionStack, SIGNAL(titleChanged(int,QString)),
|
|
m_tabBar, SLOT(setTabTitle(int,QString)));
|
|
|
|
m_sessionStack->emitTitles();
|
|
}
|
|
else
|
|
{
|
|
disconnect(m_sessionStack, SIGNAL(titleChanged(int,QString)),
|
|
m_tabBar, SLOT(setTabTitle(int,QString)));
|
|
}
|
|
|
|
m_animationTimer.setInterval(10);
|
|
|
|
m_tabBar->setVisible(Settings::showTabBar());
|
|
|
|
setKeepOpen(Settings::keepOpen());
|
|
|
|
updateScreenMenu();
|
|
updateWindowSizeMenus();
|
|
|
|
updateUseTranslucency();
|
|
|
|
applySkin();
|
|
applyWindowGeometry();
|
|
applyWindowProperties();
|
|
}
|
|
|
|
void MainWindow::applySkin()
|
|
{
|
|
bool gotSkin = m_skin->load(Settings::skin(), Settings::skinInstalledWithKns());
|
|
|
|
if (!gotSkin)
|
|
{
|
|
Settings::setSkin("default");
|
|
gotSkin = m_skin->load(Settings::skin());
|
|
}
|
|
|
|
if (!gotSkin)
|
|
{
|
|
KMessageBox::error(parentWidget(),
|
|
i18nc("@info", "<application>Yakuake</application> was unable to load a skin. It is likely that it was installed incorrectly.<nl/><nl/>"
|
|
"The application will now quit."),
|
|
i18nc("@title:window", "Cannot Load Skin"));
|
|
|
|
QMetaObject::invokeMethod(kapp, "quit", Qt::QueuedConnection);
|
|
}
|
|
|
|
m_titleBar->applySkin();
|
|
m_tabBar->applySkin();
|
|
}
|
|
|
|
void MainWindow::applyWindowProperties()
|
|
{
|
|
if (Settings::keepOpen() && !Settings::keepAbove())
|
|
{
|
|
KWindowSystem::clearState(winId(), NET::KeepAbove);
|
|
KWindowSystem::setState(winId(), NET::Sticky | NET::SkipTaskbar | NET::SkipPager);
|
|
}
|
|
else
|
|
KWindowSystem::setState(winId(), NET::KeepAbove | NET::Sticky | NET::SkipTaskbar | NET::SkipPager);
|
|
|
|
KWindowSystem::setOnAllDesktops(winId(), Settings::showOnAllDesktops());
|
|
}
|
|
|
|
void MainWindow::applyWindowGeometry()
|
|
{
|
|
int width, height;
|
|
|
|
QAction* action = actionCollection()->action("view-full-screen");
|
|
|
|
if (action->isChecked())
|
|
{
|
|
width = 100;
|
|
height = 100;
|
|
}
|
|
else
|
|
{
|
|
width = Settings::width();
|
|
height = Settings::height();
|
|
}
|
|
|
|
setWindowGeometry(width, height, Settings::position());
|
|
}
|
|
|
|
void MainWindow::setWindowGeometry(int newWidth, int newHeight, int newPosition)
|
|
{
|
|
QRect workArea = getDesktopGeometry();
|
|
|
|
int maxHeight = workArea.height() * newHeight / 100;
|
|
|
|
int targetWidth = workArea.width() * newWidth / 100;
|
|
|
|
setGeometry(workArea.x() + workArea.width() * newPosition * (100 - newWidth) / 10000,
|
|
workArea.y(), targetWidth, maxHeight);
|
|
|
|
maxHeight -= m_titleBar->height();
|
|
m_titleBar->setGeometry(0, maxHeight, targetWidth, m_titleBar->height());
|
|
if (!isVisible()) m_titleBar->updateMask();
|
|
|
|
if (Settings::frames() > 0)
|
|
m_animationStepSize = maxHeight / Settings::frames();
|
|
else
|
|
m_animationStepSize = maxHeight;
|
|
|
|
if (Settings::showTabBar())
|
|
{
|
|
maxHeight -= m_tabBar->height();
|
|
m_tabBar->setGeometry(m_skin->borderWidth(), maxHeight,
|
|
width() - 2 * m_skin->borderWidth(), m_tabBar->height());
|
|
}
|
|
|
|
m_sessionStack->setGeometry(m_skin->borderWidth(), 0,
|
|
width() - 2 * m_skin->borderWidth(), maxHeight);
|
|
|
|
updateMask();
|
|
}
|
|
|
|
void MainWindow::setScreen(QAction* action)
|
|
{
|
|
Settings::setScreen(action->data().toInt());
|
|
|
|
applyWindowGeometry();
|
|
|
|
updateScreenMenu();
|
|
}
|
|
|
|
void MainWindow::setWindowWidth(int width)
|
|
{
|
|
Settings::setWidth(width);
|
|
|
|
applyWindowGeometry();
|
|
|
|
updateWindowWidthMenu();
|
|
}
|
|
|
|
void MainWindow::setWindowHeight(int height)
|
|
{
|
|
Settings::setHeight(height);
|
|
|
|
applyWindowGeometry();
|
|
|
|
updateWindowHeightMenu();
|
|
}
|
|
|
|
void MainWindow::setWindowWidth(QAction* action)
|
|
{
|
|
setWindowWidth(action->data().toInt());
|
|
}
|
|
|
|
void MainWindow::setWindowHeight(QAction* action)
|
|
{
|
|
setWindowHeight(action->data().toInt());
|
|
}
|
|
|
|
void MainWindow::increaseWindowWidth()
|
|
{
|
|
if (Settings::width() <= 90) setWindowWidth(Settings::width() + 10);
|
|
}
|
|
|
|
void MainWindow:: decreaseWindowWidth()
|
|
{
|
|
if (Settings::width() >= 20) setWindowWidth(Settings::width() - 10);
|
|
}
|
|
|
|
void MainWindow::increaseWindowHeight()
|
|
{
|
|
if (Settings::height() <= 90) setWindowHeight(Settings::height() + 10);
|
|
}
|
|
|
|
void MainWindow::decreaseWindowHeight()
|
|
{
|
|
if (Settings::height() >= 20) setWindowHeight(Settings::height() - 10);
|
|
}
|
|
|
|
void MainWindow::updateMask()
|
|
{
|
|
QRegion region = m_titleBar->mask();
|
|
|
|
region.translate(0, m_titleBar->y());
|
|
|
|
region += QRegion(0, 0, width(), m_titleBar->y());
|
|
|
|
setMask(region);
|
|
}
|
|
|
|
void MainWindow::paintEvent(QPaintEvent* event)
|
|
{
|
|
QPainter painter(this);
|
|
|
|
if (useTranslucency())
|
|
{
|
|
painter.setOpacity(qreal(Settings::backgroundColorOpacity()) / 100);
|
|
painter.fillRect(rect(), Settings::backgroundColor());
|
|
painter.setOpacity(1.0);
|
|
}
|
|
else
|
|
painter.fillRect(rect(), Settings::backgroundColor());
|
|
|
|
QRect leftBorder(0, 0, m_skin->borderWidth(), height() - m_titleBar->height());
|
|
painter.fillRect(leftBorder, m_skin->borderColor());
|
|
|
|
QRect rightBorder(width() - m_skin->borderWidth(), 0, m_skin->borderWidth(),
|
|
height() - m_titleBar->height());
|
|
painter.fillRect(rightBorder, m_skin->borderColor());
|
|
|
|
KMainWindow::paintEvent(event);
|
|
}
|
|
|
|
void MainWindow::moveEvent(QMoveEvent* event)
|
|
{
|
|
if (Settings::screen() && KApplication::desktop()->screenNumber(this) != getScreen())
|
|
{
|
|
Settings::setScreen(KApplication::desktop()->screenNumber(this)+1);
|
|
|
|
updateScreenMenu();
|
|
|
|
applyWindowGeometry();
|
|
}
|
|
|
|
KMainWindow::moveEvent(event);
|
|
}
|
|
|
|
void MainWindow::changeEvent(QEvent* event)
|
|
{
|
|
if (m_listenForActivationChanges && event->type() == QEvent::ActivationChange)
|
|
{
|
|
if (isVisible() && !KApplication::activeWindow() && !Settings::keepOpen())
|
|
toggleWindowState();
|
|
}
|
|
|
|
if (event->type() == QEvent::WindowStateChange
|
|
&& (windowState() & Qt::WindowMaximized)
|
|
&& Settings::width() != 100
|
|
&& Settings::height() != 100)
|
|
{
|
|
Settings::setWidth(100);
|
|
Settings::setHeight(100);
|
|
|
|
applyWindowGeometry();
|
|
|
|
updateWindowWidthMenu();
|
|
updateWindowHeightMenu();
|
|
}
|
|
|
|
KMainWindow::changeEvent(event);
|
|
}
|
|
|
|
void MainWindow::toggleWindowState()
|
|
{
|
|
bool visible = isVisible();
|
|
|
|
if (visible && !isActiveWindow() && Settings::keepOpen())
|
|
{
|
|
// Window is open but doesn't have focus; it's set to stay open
|
|
// regardless of focus loss.
|
|
|
|
if (Settings::toggleToFocus())
|
|
{
|
|
// The open/retract action is set to focus the window when it's
|
|
// open but lacks focus. The following will cause it to receive
|
|
// focus, and in an environment with multiple virtual desktops
|
|
// will also cause the window manager to switch to the virtual
|
|
// desktop the window resides on.
|
|
|
|
KWindowSystem::activateWindow(winId());
|
|
KWindowSystem::forceActiveWindow(winId());
|
|
|
|
return;
|
|
}
|
|
else if (!Settings::showOnAllDesktops()
|
|
&& KWindowSystem::windowInfo(winId(), NET::WMDesktop).desktop() != KWindowSystem::currentDesktop())
|
|
{
|
|
// The open/restract action isn't set to focus the window, but
|
|
// the window is currently on another virtual desktop (the option
|
|
// to show it on all of them is disabled), so closing it doesn't
|
|
// make sense and we're opting to show it instead to avoid re-
|
|
// quiring the user to invoke the action twice to get to see
|
|
// Yakuake. Just forcing focus would cause the window manager to
|
|
// switch to the virtual desktop the window currently resides on,
|
|
// so move the window to the current desktop before doing so.
|
|
|
|
KWindowSystem::setOnDesktop(winId(), KWindowSystem::currentDesktop());
|
|
|
|
KWindowSystem::activateWindow(winId());
|
|
KWindowSystem::forceActiveWindow(winId());
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
#if defined(Q_WS_X11)
|
|
if (!Settings::useWMAssist() && m_kwinAssistPropSet)
|
|
kwinAssistPropCleanup();
|
|
|
|
if (Settings::useWMAssist() && KWindowSystem::compositingActive())
|
|
kwinAssistToggleWindowState(visible);
|
|
else
|
|
#endif
|
|
xshapeToggleWindowState(visible);
|
|
}
|
|
|
|
#if defined(Q_WS_X11)
|
|
void MainWindow::kwinAssistToggleWindowState(bool visible)
|
|
{
|
|
bool gotEffect = false;
|
|
|
|
Display* display = QX11Info::display();
|
|
Atom atom = XInternAtom(display, "_KDE_SLIDE", false);
|
|
int count;
|
|
Atom* list = XListProperties(display, DefaultRootWindow(display), &count);
|
|
|
|
if (list != NULL)
|
|
{
|
|
gotEffect = (qFind(list, list + count, atom) != list + count);
|
|
|
|
XFree(list);
|
|
}
|
|
|
|
if (gotEffect)
|
|
{
|
|
Atom atom = XInternAtom(display, "_KDE_SLIDE", false);
|
|
|
|
if (Settings::frames() > 0)
|
|
{
|
|
QVarLengthArray<long, 1024> data(4);
|
|
|
|
data[0] = 0;
|
|
data[1] = 1;
|
|
data[2] = Settings::frames() * 10;
|
|
data[3] = Settings::frames() * 10;
|
|
|
|
XChangeProperty(display, winId(), atom, atom, 32, PropModeReplace,
|
|
reinterpret_cast<unsigned char *>(data.data()), data.size());
|
|
|
|
m_kwinAssistPropSet = true;
|
|
}
|
|
else
|
|
XDeleteProperty(display, winId(), atom);
|
|
|
|
if (visible)
|
|
{
|
|
sharedPreHideWindow();
|
|
|
|
hide();
|
|
|
|
sharedAfterHideWindow();
|
|
}
|
|
else
|
|
{
|
|
sharedPreOpenWindow();
|
|
|
|
show();
|
|
|
|
sharedAfterOpenWindow();
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
// Fall back to legacy animation strategy if kwin doesn't have the
|
|
// effect loaded.
|
|
xshapeToggleWindowState(visible);
|
|
}
|
|
|
|
void MainWindow::kwinAssistPropCleanup()
|
|
{
|
|
Display* display = QX11Info::display();
|
|
Atom atom = XInternAtom(display, "_KDE_SLIDE", false);
|
|
|
|
XDeleteProperty(display, winId(), atom);
|
|
|
|
m_kwinAssistPropSet = false;
|
|
}
|
|
#endif
|
|
|
|
void MainWindow::xshapeToggleWindowState(bool visible)
|
|
{
|
|
if (m_animationTimer.isActive()) return;
|
|
|
|
if (visible)
|
|
{
|
|
sharedPreHideWindow();
|
|
|
|
m_animationFrame = Settings::frames();
|
|
|
|
connect(&m_animationTimer, SIGNAL(timeout()), this, SLOT(xshapeRetractWindow()));
|
|
m_animationTimer.start();
|
|
}
|
|
else
|
|
{
|
|
m_animationFrame = 0;
|
|
|
|
connect(&m_animationTimer, SIGNAL(timeout()), this, SLOT(xshapeOpenWindow()));
|
|
m_animationTimer.start();
|
|
}
|
|
}
|
|
|
|
void MainWindow::xshapeOpenWindow()
|
|
{
|
|
if (m_animationFrame == 0)
|
|
{
|
|
sharedPreOpenWindow();
|
|
|
|
show();
|
|
}
|
|
|
|
if (m_animationFrame == Settings::frames())
|
|
{
|
|
m_animationTimer.stop();
|
|
m_animationTimer.disconnect();
|
|
|
|
m_titleBar->move(0, height() - m_titleBar->height());
|
|
updateMask();
|
|
|
|
sharedAfterOpenWindow();
|
|
}
|
|
else
|
|
{
|
|
int maskHeight = m_animationStepSize * m_animationFrame;
|
|
|
|
QRegion newMask = m_titleBar->mask();
|
|
newMask.translate(0, maskHeight);
|
|
newMask += QRegion(0, 0, width(), maskHeight);
|
|
|
|
m_titleBar->move(0, maskHeight);
|
|
setMask(newMask);
|
|
|
|
m_animationFrame++;
|
|
}
|
|
}
|
|
|
|
void MainWindow::xshapeRetractWindow()
|
|
{
|
|
if (m_animationFrame == 0)
|
|
{
|
|
m_animationTimer.stop();
|
|
m_animationTimer.disconnect();
|
|
|
|
hide();
|
|
|
|
sharedAfterHideWindow();
|
|
}
|
|
else
|
|
{
|
|
m_titleBar->move(0,m_titleBar->y() - m_animationStepSize);
|
|
setMask(QRegion(mask()).translated(0, -m_animationStepSize));
|
|
|
|
--m_animationFrame;
|
|
}
|
|
}
|
|
|
|
void MainWindow::sharedPreOpenWindow()
|
|
{
|
|
applyWindowGeometry();
|
|
|
|
updateUseTranslucency();
|
|
|
|
applyWindowProperties();
|
|
|
|
if (Settings::pollMouse()) toggleMousePoll(false);
|
|
}
|
|
|
|
void MainWindow::sharedAfterOpenWindow()
|
|
{
|
|
if (!Settings::firstRun()) KWindowSystem::forceActiveWindow(winId());
|
|
|
|
m_listenForActivationChanges = true;
|
|
|
|
emit windowOpened();
|
|
}
|
|
|
|
void MainWindow::sharedPreHideWindow()
|
|
{
|
|
m_listenForActivationChanges = false;
|
|
}
|
|
|
|
void MainWindow::sharedAfterHideWindow()
|
|
{
|
|
if (Settings::pollMouse()) toggleMousePoll(true);
|
|
|
|
emit windowClosed();
|
|
}
|
|
|
|
void MainWindow::activate()
|
|
{
|
|
KWindowSystem::activateWindow(winId());
|
|
}
|
|
|
|
void MainWindow::toggleMousePoll(bool poll)
|
|
{
|
|
if (poll)
|
|
m_mousePoller.start(Settings::pollInterval());
|
|
else
|
|
m_mousePoller.stop();
|
|
}
|
|
|
|
void MainWindow::pollMouse()
|
|
{
|
|
QPoint pos = QCursor::pos();
|
|
QRect workArea = getDesktopGeometry();
|
|
|
|
int windowX = workArea.x() + workArea.width() * Settings::position() * (100 - Settings::width()) / 10000;
|
|
int windowWidth = workArea.width() * Settings::width() / 100;
|
|
|
|
if (pos.y() == 0 && pos.x() >= windowX && pos.x() <= (windowX + windowWidth))
|
|
toggleWindowState();
|
|
}
|
|
|
|
void MainWindow::setKeepOpen(bool keepOpen)
|
|
{
|
|
if (Settings::keepOpen() != keepOpen)
|
|
{
|
|
Settings::setKeepOpen(keepOpen);
|
|
|
|
applyWindowProperties();
|
|
}
|
|
|
|
actionCollection()->action("keep-open")->setChecked(keepOpen);
|
|
m_titleBar->setFocusButtonState(keepOpen);
|
|
}
|
|
|
|
void MainWindow::setFullScreen(bool state)
|
|
{
|
|
if (state)
|
|
{
|
|
setWindowState(windowState() | Qt::WindowFullScreen);
|
|
setWindowGeometry(100, 100, Settings::position());
|
|
}
|
|
else
|
|
{
|
|
setWindowState(windowState() & ~Qt::WindowFullScreen);
|
|
setWindowGeometry(Settings::width(), Settings::height(), Settings::position());
|
|
}
|
|
}
|
|
|
|
int MainWindow::getScreen()
|
|
{
|
|
if (!Settings::screen())
|
|
return KApplication::desktop()->screenNumber(QCursor::pos());
|
|
else
|
|
return Settings::screen() - 1;
|
|
}
|
|
|
|
QRect MainWindow::getDesktopGeometry()
|
|
{
|
|
QRect screenGeometry = KApplication::desktop()->screenGeometry(getScreen());
|
|
|
|
QAction* action = actionCollection()->action("view-full-screen");
|
|
|
|
if (action->isChecked())
|
|
return screenGeometry;
|
|
|
|
int currentDesktop = KWindowSystem::windowInfo(winId(), NET::WMDesktop).desktop();
|
|
|
|
if (KApplication::desktop()->screenCount() > 1)
|
|
{
|
|
const QList<WId> allWindows = KWindowSystem::windows();
|
|
QList<WId> offScreenWindows;
|
|
|
|
QListIterator<WId> i(allWindows);
|
|
|
|
while (i.hasNext())
|
|
{
|
|
WId windowId = i.next();
|
|
|
|
if (KWindowSystem::hasWId(windowId))
|
|
{
|
|
KWindowInfo windowInfo = KWindowSystem::windowInfo(windowId, NET::WMDesktop, NET::WM2ExtendedStrut);
|
|
|
|
if (windowInfo.valid() && windowInfo.desktop() == currentDesktop)
|
|
{
|
|
NETExtendedStrut strut = windowInfo.extendedStrut();
|
|
|
|
// Get the area covered by each strut.
|
|
QRect topStrut(strut.top_start, 0, strut.top_end - strut.top_start, strut.top_width);
|
|
QRect bottomStrut(strut.bottom_start, screenGeometry.bottom() - strut.bottom_width,
|
|
strut.bottom_end - strut.bottom_start, strut.bottom_width);
|
|
QRect leftStrut(0, strut.left_width, strut.left_start, strut.left_end - strut.left_start);
|
|
QRect rightStrut(screenGeometry.right() - strut.right_width, strut.right_start,
|
|
strut.right_end - strut.right_start, strut.right_width);
|
|
|
|
// If the window has no strut, no need to bother further.
|
|
if (topStrut.isEmpty() && bottomStrut.isEmpty() && leftStrut.isEmpty() && rightStrut.isEmpty())
|
|
continue;
|
|
|
|
// If any of the strut intersects with our screen geometry, it will be correctly handled
|
|
// by workArea().
|
|
if (topStrut.intersects(screenGeometry) || bottomStrut.intersects(screenGeometry) ||
|
|
leftStrut.intersects(screenGeometry) || rightStrut.intersects(screenGeometry))
|
|
continue;
|
|
|
|
// This window has a strut on the same desktop as us but which does not cover our screen
|
|
// geometry. It should be ignored, otherwise the returned work area will wrongly include
|
|
// the strut.
|
|
offScreenWindows << windowId;
|
|
}
|
|
}
|
|
}
|
|
|
|
return KWindowSystem::workArea(offScreenWindows, currentDesktop).intersect(screenGeometry);
|
|
}
|
|
|
|
return KWindowSystem::workArea(currentDesktop);
|
|
}
|
|
|
|
void MainWindow::whatsThis()
|
|
{
|
|
QWhatsThis::enterWhatsThisMode();
|
|
}
|
|
|
|
void MainWindow::showStartupPopup()
|
|
{
|
|
KAction* action = static_cast<KAction*>(actionCollection()->action("toggle-window-state"));
|
|
QString shortcut(action->globalShortcut().toString());
|
|
QString message(i18nc("@info", "Application successfully started.<nl/>" "Press <shortcut>%1</shortcut> to use it ...", shortcut));
|
|
|
|
KNotification::event(QLatin1String("startup"), message, QPixmap(), this);
|
|
}
|
|
|
|
void MainWindow::showFirstRunDialog()
|
|
{
|
|
if (!m_firstRunDialog)
|
|
{
|
|
m_firstRunDialog = new FirstRunDialog(this);
|
|
connect(m_firstRunDialog, SIGNAL(finished()), this, SLOT(firstRunDialogFinished()));
|
|
connect(m_firstRunDialog, SIGNAL(okClicked()), this, SLOT(firstRunDialogOk()));
|
|
}
|
|
|
|
m_firstRunDialog->show();
|
|
}
|
|
|
|
void MainWindow::firstRunDialogFinished()
|
|
{
|
|
Settings::setFirstRun(false);
|
|
Settings::self()->writeConfig();
|
|
|
|
m_firstRunDialog->deleteLater();
|
|
|
|
KWindowSystem::forceActiveWindow(winId());
|
|
}
|
|
|
|
void MainWindow::firstRunDialogOk()
|
|
{
|
|
KAction* action = static_cast<KAction*>(actionCollection()->action("toggle-window-state"));
|
|
|
|
action->setGlobalShortcut(KShortcut(m_firstRunDialog->keySequence()),
|
|
KAction::ActiveShortcut, KAction::NoAutoloading);
|
|
|
|
actionCollection()->writeSettings();
|
|
}
|
|
|
|
void MainWindow::updateUseTranslucency()
|
|
{
|
|
m_useTranslucency = (Settings::translucency() && KWindowSystem::compositingActive());
|
|
}
|