File indexing completed on 2024-04-21 05:54:03
0001 /* 0002 SPDX-FileCopyrightText: 2009 Tom Albers <toma@kde.org> 0003 SPDX-FileCopyrightText: 2010 Juan Luis Baptiste <juan.baptiste@gmail.com> 0004 0005 SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 #include "breakbase.h" 0009 #include "breakcontrol.h" 0010 0011 #include <KWindowSystem> 0012 0013 #include <QApplication> 0014 #include <QDebug> 0015 #include <QKeyEvent> 0016 #include <QObject> 0017 #include <QPainter> 0018 #include <QScreen> 0019 0020 BreakBase::BreakBase(QObject *parent) 0021 : QObject(parent) 0022 , m_grayEffectOnAllScreens(nullptr) 0023 , m_readOnly(false) 0024 , m_disableShortcut(false) 0025 , m_grayEffectOnAllScreensActivated(false) 0026 { 0027 m_breakControl = new BreakControl(nullptr, Qt::Popup); 0028 m_breakControl->hide(); 0029 m_breakControl->installEventFilter(this); 0030 connect(m_breakControl, &BreakControl::skip, this, &BreakBase::skip); 0031 connect(m_breakControl, &BreakControl::lock, this, &BreakBase::lock); 0032 connect(m_breakControl, &BreakControl::postpone, this, &BreakBase::postpone); 0033 } 0034 0035 BreakBase::~BreakBase() 0036 { 0037 delete m_grayEffectOnAllScreens; 0038 delete m_breakControl; 0039 } 0040 0041 void BreakBase::activate() 0042 { 0043 if (m_grayEffectOnAllScreensActivated) 0044 m_grayEffectOnAllScreens->activate(); 0045 0046 m_breakControl->show(); 0047 m_breakControl->setFocus(); 0048 0049 KWindowSystem::forceActiveWindow(m_breakControl->winId()); 0050 KWindowSystem::setOnAllDesktops(m_breakControl->winId(), true); 0051 KWindowSystem::setState(m_breakControl->winId(), NET::KeepAbove); 0052 KWindowSystem::setState(m_breakControl->winId(), NET::FullScreen); 0053 0054 m_breakControl->grabKeyboard(); 0055 m_breakControl->grabMouse(); 0056 } 0057 0058 void BreakBase::deactivate() 0059 { 0060 if (m_grayEffectOnAllScreensActivated) 0061 m_grayEffectOnAllScreens->deactivate(); 0062 0063 m_breakControl->releaseMouse(); 0064 m_breakControl->releaseKeyboard(); 0065 m_breakControl->hide(); 0066 } 0067 0068 bool BreakBase::eventFilter(QObject *obj, QEvent *event) 0069 { 0070 if (event->type() == QEvent::KeyPress) { 0071 QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event); 0072 qDebug() << "Ate key press" << keyEvent->key(); 0073 if (!m_disableShortcut && keyEvent->key() == Qt::Key_Escape) { 0074 qDebug() << "Escape"; 0075 emit skip(); 0076 } 0077 return true; 0078 } else if (m_readOnly && (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonDblClick)) { 0079 qDebug() << "Ate mouse click event"; 0080 return true; 0081 } else { 0082 return QObject::eventFilter(obj, event); 0083 } 0084 } 0085 0086 void BreakBase::setReadOnly(bool ro) 0087 { 0088 m_readOnly = ro; 0089 } 0090 0091 bool BreakBase::readOnly() const 0092 { 0093 return m_readOnly; 0094 } 0095 0096 void BreakBase::setLabel(const QString &text) 0097 { 0098 m_breakControl->setText(text); 0099 } 0100 0101 void BreakBase::showMinimize(bool show) 0102 { 0103 m_breakControl->showMinimize(show); 0104 } 0105 0106 void BreakBase::showLock(bool show) 0107 { 0108 m_breakControl->showLock(show); 0109 } 0110 0111 void BreakBase::showPostpone(bool show) 0112 { 0113 m_breakControl->showPostpone(show); 0114 } 0115 0116 void BreakBase::disableShortcut(bool disable) 0117 { 0118 m_disableShortcut = disable; 0119 } 0120 0121 void BreakBase::setGrayEffectOnAllScreens(bool on) 0122 { 0123 m_grayEffectOnAllScreensActivated = on; 0124 delete m_grayEffectOnAllScreens; 0125 if (on) { 0126 m_grayEffectOnAllScreens = new GrayEffectOnAllScreens(); 0127 m_grayEffectOnAllScreens->setLevel(70); 0128 } 0129 } 0130 0131 void BreakBase::setGrayEffectLevel(int level) 0132 { 0133 m_grayEffectOnAllScreens->setLevel(level); 0134 } 0135 0136 void BreakBase::excludeGrayEffectOnScreen(QScreen *screen) 0137 { 0138 m_grayEffectOnAllScreens->disable(screen); 0139 } 0140 0141 // ------------------------ GrayEffectOnAllScreens -------------// 0142 0143 GrayEffectOnAllScreens::GrayEffectOnAllScreens() 0144 { 0145 for (QScreen *screen : QGuiApplication::screens()) { 0146 GrayWidget *grayWidget = new GrayWidget(nullptr); 0147 m_widgets.insert(screen, grayWidget); 0148 0149 const QRect rect = screen->geometry(); 0150 grayWidget->move(rect.topLeft()); 0151 grayWidget->setGeometry(rect); 0152 0153 KWindowSystem::forceActiveWindow(grayWidget->winId()); 0154 KWindowSystem::setState(grayWidget->winId(), NET::KeepAbove); 0155 KWindowSystem::setOnAllDesktops(grayWidget->winId(), true); 0156 KWindowSystem::setState(grayWidget->winId(), NET::FullScreen); 0157 0158 qDebug() << "Created widget for screen" << screen << "Position:" << rect.topLeft(); 0159 } 0160 } 0161 0162 GrayEffectOnAllScreens::~GrayEffectOnAllScreens() 0163 { 0164 qDeleteAll(m_widgets); 0165 } 0166 0167 void GrayEffectOnAllScreens::disable(QScreen *screen) 0168 { 0169 qDebug() << "Removing widget from screen" << screen; 0170 if (!m_widgets.contains(screen)) 0171 return; 0172 0173 delete m_widgets.take(screen); 0174 } 0175 0176 void GrayEffectOnAllScreens::activate() 0177 { 0178 foreach (GrayWidget *widget, m_widgets) { 0179 widget->show(); 0180 widget->update(); 0181 } 0182 } 0183 0184 void GrayEffectOnAllScreens::deactivate() 0185 { 0186 foreach (GrayWidget *widget, m_widgets) { 0187 widget->hide(); 0188 } 0189 } 0190 0191 void GrayEffectOnAllScreens::setLevel(int val) 0192 { 0193 foreach (GrayWidget *widget, m_widgets) { 0194 widget->setLevel(val); 0195 } 0196 } 0197 0198 //-------------------- GrayWidget ----------------------------// 0199 0200 GrayWidget::GrayWidget(QWidget *parent) 0201 : QWidget(parent, Qt::Popup) 0202 { 0203 setAutoFillBackground(false); 0204 } 0205 0206 bool GrayWidget::event(QEvent *event) 0207 { 0208 if (event->type() == QEvent::Paint) { 0209 qDebug() << "GrayWidget::event"; 0210 QPainter p(this); 0211 p.setCompositionMode(QPainter::CompositionMode_Source); 0212 p.fillRect(rect(), QColor(0, 0, 0, 180)); 0213 } 0214 return QWidget::event(event); 0215 } 0216 0217 void GrayWidget::setLevel(int val) 0218 { 0219 double level = 0; 0220 if (val > 0) 0221 level = (double)val / 100; 0222 0223 qDebug() << "New Value" << level; 0224 setWindowOpacity(level); 0225 update(); 0226 }