/* * windows.cpp * * Copyright (c) 1997 Patrick Dowler dowler@morgul.fsh.uvic.ca * Copyright (c) 2001 Waldo Bastian bastian@kde.org * * 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "windows.h" #include #include // kwin config keywords #define KWIN_FOCUS "FocusPolicy" #define KWIN_PLACEMENT "Placement" #define KWIN_GEOMETRY "GeometryTip" #define KWIN_AUTORAISE_INTERVAL "AutoRaiseInterval" #define KWIN_AUTORAISE "AutoRaise" #define KWIN_DELAYFOCUS_INTERVAL "DelayFocusInterval" #define KWIN_CLICKRAISE "ClickRaise" #define KWIN_SHADEHOVER "ShadeHover" #define KWIN_SHADEHOVER_INTERVAL "ShadeHoverInterval" #define KWIN_FOCUS_STEALING "FocusStealingPreventionLevel" #define KWIN_HIDE_UTILITY "HideUtilityWindowsForInactive" #define KWIN_INACTIVE_SKIP_TASKBAR "InactiveTabsSkipTaskbar" #define KWIN_AUTOGROUP_SIMILAR "AutogroupSimilarWindows" #define KWIN_AUTOGROUP_FOREGROUND "AutogroupInForeground" #define KWIN_SEPARATE_SCREEN_FOCUS "SeparateScreenFocus" #define KWIN_ACTIVE_MOUSE_SCREEN "ActiveMouseScreen" //CT 15mar 98 - magics #define KWM_BRDR_SNAP_ZONE "BorderSnapZone" #define KWM_BRDR_SNAP_ZONE_DEFAULT 10 #define KWM_WNDW_SNAP_ZONE "WindowSnapZone" #define KWM_WNDW_SNAP_ZONE_DEFAULT 10 #define KWM_CNTR_SNAP_ZONE "CenterSnapZone" #define KWM_CNTR_SNAP_ZONE_DEFAULT 0 #define MAX_BRDR_SNAP 100 #define MAX_WNDW_SNAP 100 #define MAX_CNTR_SNAP 100 #define MAX_EDGE_RES 1000 #define CLICK_TO_FOCUS 0 #define FOCUS_FOLLOWS_MOUSE 2 #define FOCUS_UNDER_MOUSE 4 #define FOCUS_STRICTLY_UNDER_MOUSE 5 KFocusConfig::~KFocusConfig() { if (standAlone) delete config; } KWinFocusConfigForm::KWinFocusConfigForm(QWidget* parent) : QWidget(parent) { setupUi(parent); } // removed the LCD display over the slider - this is not good GUI design :) RNolden 051701 KFocusConfig::KFocusConfig(bool _standAlone, KConfig *_config, QWidget * parent) : KCModule(parent), config(_config), standAlone(_standAlone) , m_ui(new KWinFocusConfigForm(this)) { connect(m_ui->focusStealing, SIGNAL(activated(int)), SLOT(changed())); connect(m_ui->windowFocusPolicy, SIGNAL(valueChanged(int)), SLOT(changed())); connect(m_ui->windowFocusPolicy, SIGNAL(valueChanged(int)), this, SLOT(focusPolicyChanged())); connect(m_ui->windowFocusPolicy, SIGNAL(valueChanged(int)), this, SLOT(setDelayFocusEnabled())); connect(m_ui->windowFocusPolicy, SIGNAL(valueChanged(int)), this, SLOT(updateActiveMouseScreen())); connect(m_ui->autoRaiseOn, SIGNAL(clicked()), SLOT(changed())); connect(m_ui->autoRaiseOn, SIGNAL(toggled(bool)), SLOT(autoRaiseOnTog(bool))); connect(m_ui->clickRaiseOn, SIGNAL(clicked()), SLOT(changed())); connect(m_ui->autoRaise, SIGNAL(valueChanged(int)), SLOT(changed())); connect(m_ui->delayFocus, SIGNAL(valueChanged(int)), SLOT(changed())); connect(m_ui->separateScreenFocus, SIGNAL(clicked()), SLOT(changed())); connect(m_ui->activeMouseScreen, SIGNAL(clicked()), SLOT(changed())); connect(QApplication::desktop(), SIGNAL(screenCountChanged(int)), SLOT(updateMultiScreen())); updateMultiScreen(); load(); } void KFocusConfig::updateMultiScreen() { m_ui->multiscreenBox->setVisible(QApplication::desktop()->screenCount() > 1); } int KFocusConfig::getFocus() { int policy = m_ui->windowFocusPolicy->value(); if (policy == 1 || policy == 3) --policy; // fix the NextFocusPrefersMouse condition return policy; } void KFocusConfig::setFocus(int foc) { m_ui->windowFocusPolicy->setValue(foc); // this will disable/hide the auto raise delay widget if focus==click focusPolicyChanged(); } void KFocusConfig::setAutoRaiseInterval(int tb) { m_ui->autoRaise->setValue(tb); } void KFocusConfig::setDelayFocusInterval(int tb) { m_ui->delayFocus->setValue(tb); } int KFocusConfig::getAutoRaiseInterval() { return m_ui->autoRaise->value(); } int KFocusConfig::getDelayFocusInterval() { return m_ui->delayFocus->value(); } void KFocusConfig::setAutoRaise(bool on) { m_ui->autoRaiseOn->setChecked(on); } void KFocusConfig::setClickRaise(bool on) { m_ui->clickRaiseOn->setChecked(on); } void KFocusConfig::focusPolicyChanged() { int policyIndex = getFocus(); // the auto raise related widgets are: autoRaise m_ui->autoRaiseOn->setEnabled(policyIndex != CLICK_TO_FOCUS); autoRaiseOnTog(policyIndex != CLICK_TO_FOCUS && m_ui->autoRaiseOn->isChecked()); m_ui->focusStealing->setDisabled(policyIndex == FOCUS_UNDER_MOUSE || policyIndex == FOCUS_STRICTLY_UNDER_MOUSE); m_ui->focusStealingLabel->setEnabled(m_ui->focusStealing->isEnabled()); setDelayFocusEnabled(); } void KFocusConfig::setDelayFocusEnabled() { int policyIndex = getFocus(); // the delayed focus related widgets are: delayFocus m_ui->delayFocusOnLabel->setEnabled(policyIndex != CLICK_TO_FOCUS); delayFocusOnTog(policyIndex != CLICK_TO_FOCUS); } void KFocusConfig::autoRaiseOnTog(bool a) { m_ui->autoRaise->setEnabled(a); m_ui->clickRaiseOn->setEnabled(!a); } void KFocusConfig::delayFocusOnTog(bool a) { m_ui->delayFocus->setEnabled(a); } void KFocusConfig::setFocusStealing(int l) { l = qMax(0, qMin(4, l)); m_ui->focusStealing->setCurrentIndex(l); } void KFocusConfig::setSeparateScreenFocus(bool s) { m_ui->separateScreenFocus->setChecked(s); } void KFocusConfig::setActiveMouseScreen(bool a) { m_ui->activeMouseScreen->setChecked(a); } void KFocusConfig::updateActiveMouseScreen() { // on by default for non click to focus policies KConfigGroup cfg(config, "Windows"); if (!cfg.hasKey(KWIN_ACTIVE_MOUSE_SCREEN)) setActiveMouseScreen(getFocus() != 0); } void KFocusConfig::showEvent(QShowEvent *ev) { if (!standAlone) { QWidget::showEvent(ev); return; } KCModule::showEvent(ev); } void KFocusConfig::load(void) { QString key; KConfigGroup cg(config, "Windows"); const bool focusNextToMouse = cg.readEntry("NextFocusPrefersMouse", false); key = cg.readEntry(KWIN_FOCUS); if (key == "ClickToFocus") setFocus(CLICK_TO_FOCUS + focusNextToMouse); else if (key == "FocusFollowsMouse") setFocus(FOCUS_FOLLOWS_MOUSE + focusNextToMouse); else if (key == "FocusUnderMouse") setFocus(FOCUS_UNDER_MOUSE); else if (key == "FocusStrictlyUnderMouse") setFocus(FOCUS_STRICTLY_UNDER_MOUSE); int k = cg.readEntry(KWIN_AUTORAISE_INTERVAL, 750); setAutoRaiseInterval(k); k = cg.readEntry(KWIN_DELAYFOCUS_INTERVAL, 300); setDelayFocusInterval(k); setAutoRaise(cg.readEntry(KWIN_AUTORAISE, false)); setClickRaise(cg.readEntry(KWIN_CLICKRAISE, true)); focusPolicyChanged(); // this will disable/hide the auto raise delay widget if focus==click setSeparateScreenFocus(cg.readEntry(KWIN_SEPARATE_SCREEN_FOCUS, false)); // on by default for non click to focus policies setActiveMouseScreen(cg.readEntry(KWIN_ACTIVE_MOUSE_SCREEN, getFocus() != 0)); // setFocusStealing( cg.readEntry(KWIN_FOCUS_STEALING, 2 )); // TODO default to low for now setFocusStealing(cg.readEntry(KWIN_FOCUS_STEALING, 1)); emit KCModule::changed(false); } void KFocusConfig::save(void) { int v; KConfigGroup cg(config, "Windows"); v = getFocus(); if (v == CLICK_TO_FOCUS) cg.writeEntry(KWIN_FOCUS, "ClickToFocus"); else if (v == FOCUS_UNDER_MOUSE) cg.writeEntry(KWIN_FOCUS, "FocusUnderMouse"); else if (v == FOCUS_STRICTLY_UNDER_MOUSE) cg.writeEntry(KWIN_FOCUS, "FocusStrictlyUnderMouse"); else cg.writeEntry(KWIN_FOCUS, "FocusFollowsMouse"); cg.writeEntry("NextFocusPrefersMouse", v != m_ui->windowFocusPolicy->value()); v = getAutoRaiseInterval(); if (v < 0) v = 0; cg.writeEntry(KWIN_AUTORAISE_INTERVAL, v); v = getDelayFocusInterval(); if (v < 0) v = 0; cg.writeEntry(KWIN_DELAYFOCUS_INTERVAL, v); cg.writeEntry(KWIN_AUTORAISE, m_ui->autoRaiseOn->isChecked()); cg.writeEntry(KWIN_CLICKRAISE, m_ui->clickRaiseOn->isChecked()); cg.writeEntry(KWIN_SEPARATE_SCREEN_FOCUS, m_ui->separateScreenFocus->isChecked()); cg.writeEntry(KWIN_ACTIVE_MOUSE_SCREEN, m_ui->activeMouseScreen->isChecked()); cg.writeEntry(KWIN_FOCUS_STEALING, m_ui->focusStealing->currentIndex()); cg.writeEntry(KWIN_SEPARATE_SCREEN_FOCUS, m_ui->separateScreenFocus->isChecked()); cg.writeEntry(KWIN_ACTIVE_MOUSE_SCREEN, m_ui->activeMouseScreen->isChecked()); if (standAlone) { config->sync(); // Send signal to all kwin instances QDBusMessage message = QDBusMessage::createSignal("/KWin", "org.kde.KWin", "reloadConfig"); QDBusConnection::sessionBus().send(message); } emit KCModule::changed(false); } void KFocusConfig::defaults() { setAutoRaiseInterval(0); setDelayFocusInterval(0); setFocus(CLICK_TO_FOCUS); setAutoRaise(false); setClickRaise(true); setSeparateScreenFocus(false); // setFocusStealing(2); // TODO default to low for now setFocusStealing(1); // on by default for non click to focus policies setActiveMouseScreen(getFocus() != 0); setDelayFocusEnabled(); emit KCModule::changed(true); } KWinAdvancedConfigForm::KWinAdvancedConfigForm(QWidget* parent) : QWidget(parent) { setupUi(parent); } KAdvancedConfig::~KAdvancedConfig() { if (standAlone) delete config; } KAdvancedConfig::KAdvancedConfig(bool _standAlone, KConfig *_config, QWidget *parent) : KCModule(parent), config(_config), standAlone(_standAlone) , m_ui(new KWinAdvancedConfigForm(this)) { m_ui->placementCombo->setItemData(0, "Smart"); m_ui->placementCombo->setItemData(1, "Maximizing"); m_ui->placementCombo->setItemData(2, "Cascade"); m_ui->placementCombo->setItemData(3, "Random"); m_ui->placementCombo->setItemData(4, "Centered"); m_ui->placementCombo->setItemData(5, "ZeroCornered"); m_ui->placementCombo->setItemData(6, "UnderMouse"); connect(m_ui->shadeHoverOn, SIGNAL(toggled(bool)), this, SLOT(shadeHoverChanged(bool))); connect(m_ui->inactiveTabsSkipTaskbar, SIGNAL(toggled(bool)), SLOT(changed())); connect(m_ui->autogroupSimilarWindows, SIGNAL(toggled(bool)), SLOT(changed())); connect(m_ui->autogroupInForeground, SIGNAL(toggled(bool)), SLOT(changed())); connect(m_ui->shadeHoverOn, SIGNAL(toggled(bool)), SLOT(changed())); connect(m_ui->shadeHover, SIGNAL(valueChanged(int)), SLOT(changed())); connect(m_ui->placementCombo, SIGNAL(activated(int)), SLOT(changed())); connect(m_ui->hideUtilityWindowsForInactive, SIGNAL(toggled(bool)), SLOT(changed())); m_ui->inactiveTabsSkipTaskbar->setVisible(false); // TODO: We want translations in case this is fixed... load(); } void KAdvancedConfig::setShadeHover(bool on) { m_ui->shadeHoverOn->setChecked(on); m_ui->shadeHoverLabel->setEnabled(on); m_ui->shadeHover->setEnabled(on); } void KAdvancedConfig::setShadeHoverInterval(int k) { m_ui->shadeHover->setValue(k); } int KAdvancedConfig::getShadeHoverInterval() { return m_ui->shadeHover->value(); } void KAdvancedConfig::shadeHoverChanged(bool a) { m_ui->shadeHoverLabel->setEnabled(a); m_ui->shadeHover->setEnabled(a); } void KAdvancedConfig::showEvent(QShowEvent *ev) { if (!standAlone) { QWidget::showEvent(ev); return; } KCModule::showEvent(ev); } void KAdvancedConfig::load(void) { KConfigGroup cg(config, "Windows"); setShadeHover(cg.readEntry(KWIN_SHADEHOVER, false)); setShadeHoverInterval(cg.readEntry(KWIN_SHADEHOVER_INTERVAL, 250)); QString key; key = cg.readEntry(KWIN_PLACEMENT); int idx = m_ui->placementCombo->findData(key); if (idx < 0) idx = m_ui->placementCombo->findData("Smart"); m_ui->placementCombo->setCurrentIndex(idx); setHideUtilityWindowsForInactive(cg.readEntry(KWIN_HIDE_UTILITY, true)); setInactiveTabsSkipTaskbar(cg.readEntry(KWIN_INACTIVE_SKIP_TASKBAR, false)); setAutogroupSimilarWindows(cg.readEntry(KWIN_AUTOGROUP_SIMILAR, false)); setAutogroupInForeground(cg.readEntry(KWIN_AUTOGROUP_FOREGROUND, true)); emit KCModule::changed(false); } void KAdvancedConfig::save(void) { int v; KConfigGroup cg(config, "Windows"); cg.writeEntry(KWIN_SHADEHOVER, m_ui->shadeHoverOn->isChecked()); v = getShadeHoverInterval(); if (v < 0) v = 0; cg.writeEntry(KWIN_SHADEHOVER_INTERVAL, v); cg.writeEntry(KWIN_PLACEMENT, m_ui->placementCombo->itemData(m_ui->placementCombo->currentIndex()).toString()); cg.writeEntry(KWIN_HIDE_UTILITY, m_ui->hideUtilityWindowsForInactive->isChecked()); cg.writeEntry(KWIN_INACTIVE_SKIP_TASKBAR, m_ui->inactiveTabsSkipTaskbar->isChecked()); cg.writeEntry(KWIN_AUTOGROUP_SIMILAR, m_ui->autogroupSimilarWindows->isChecked()); cg.writeEntry(KWIN_AUTOGROUP_FOREGROUND, m_ui->autogroupInForeground->isChecked()); if (standAlone) { config->sync(); // Send signal to all kwin instances QDBusMessage message = QDBusMessage::createSignal("/KWin", "org.kde.KWin", "reloadConfig"); QDBusConnection::sessionBus().send(message); } emit KCModule::changed(false); } void KAdvancedConfig::defaults() { setShadeHover(false); setShadeHoverInterval(250); m_ui->placementCombo->setCurrentIndex(0); // default to Smart setHideUtilityWindowsForInactive(true); setInactiveTabsSkipTaskbar(false); setAutogroupSimilarWindows(false); setAutogroupInForeground(true); emit KCModule::changed(true); } void KAdvancedConfig::setHideUtilityWindowsForInactive(bool s) { m_ui->hideUtilityWindowsForInactive->setChecked(s); } void KAdvancedConfig::setInactiveTabsSkipTaskbar(bool s) { m_ui->inactiveTabsSkipTaskbar->setChecked(s); } void KAdvancedConfig::setAutogroupSimilarWindows(bool s) { m_ui->autogroupSimilarWindows->setChecked(s); } void KAdvancedConfig::setAutogroupInForeground(bool s) { m_ui->autogroupInForeground->setChecked(s); } KWinMovingConfigForm::KWinMovingConfigForm(QWidget* parent) : QWidget(parent) { setupUi(parent); } KMovingConfig::~KMovingConfig() { if (standAlone) delete config; } KMovingConfig::KMovingConfig(bool _standAlone, KConfig *_config, QWidget *parent) : KCModule(parent), config(_config), standAlone(_standAlone) , m_ui(new KWinMovingConfigForm(this)) { // Any changes goes to slotChanged() connect(m_ui->geometryTipOn, SIGNAL(clicked()), SLOT(changed())); connect(m_ui->borderSnap, SIGNAL(valueChanged(int)), SLOT(changed())); connect(m_ui->windowSnap, SIGNAL(valueChanged(int)), SLOT(changed())); connect(m_ui->centerSnap, SIGNAL(valueChanged(int)), SLOT(changed())); connect(m_ui->OverlapSnap, SIGNAL(clicked()), SLOT(changed())); load(); } void KMovingConfig::setGeometryTip(bool showGeometryTip) { m_ui->geometryTipOn->setChecked(showGeometryTip); } bool KMovingConfig::getGeometryTip() { return m_ui->geometryTipOn->isChecked(); } void KMovingConfig::showEvent(QShowEvent *ev) { if (!standAlone) { QWidget::showEvent(ev); return; } KCModule::showEvent(ev); } void KMovingConfig::load(void) { QString key; KConfigGroup cg(config, "Windows"); //KS 10Jan2003 - Geometry Tip during window move/resize bool showGeomTip = cg.readEntry(KWIN_GEOMETRY, false); setGeometryTip(showGeomTip); int v; v = cg.readEntry(KWM_BRDR_SNAP_ZONE, KWM_BRDR_SNAP_ZONE_DEFAULT); if (v > MAX_BRDR_SNAP) setBorderSnapZone(MAX_BRDR_SNAP); else if (v < 0) setBorderSnapZone(0); else setBorderSnapZone(v); v = cg.readEntry(KWM_WNDW_SNAP_ZONE, KWM_WNDW_SNAP_ZONE_DEFAULT); if (v > MAX_WNDW_SNAP) setWindowSnapZone(MAX_WNDW_SNAP); else if (v < 0) setWindowSnapZone(0); else setWindowSnapZone(v); v = cg.readEntry(KWM_CNTR_SNAP_ZONE, KWM_CNTR_SNAP_ZONE_DEFAULT); if (v > MAX_CNTR_SNAP) setCenterSnapZone(MAX_CNTR_SNAP); else if (v < 0) setCenterSnapZone(0); else setCenterSnapZone(v); m_ui->OverlapSnap->setChecked(cg.readEntry("SnapOnlyWhenOverlapping", false)); emit KCModule::changed(false); } void KMovingConfig::save(void) { KConfigGroup cg(config, "Windows"); cg.writeEntry(KWIN_GEOMETRY, getGeometryTip()); cg.writeEntry(KWM_BRDR_SNAP_ZONE, getBorderSnapZone()); cg.writeEntry(KWM_WNDW_SNAP_ZONE, getWindowSnapZone()); cg.writeEntry(KWM_CNTR_SNAP_ZONE, getCenterSnapZone()); cg.writeEntry("SnapOnlyWhenOverlapping", m_ui->OverlapSnap->isChecked()); const bool geometryTip = getGeometryTip(); KConfigGroup(config, "Plugins").writeEntry("windowgeometryEnabled", geometryTip); if (standAlone) { config->sync(); // Send signal to all kwin instances QDBusMessage message = QDBusMessage::createSignal("/KWin", "org.kde.KWin", "reloadConfig"); QDBusConnection::sessionBus().send(message); } // and reconfigure the effect OrgKdeKwinEffectsInterface interface(QStringLiteral("org.kde.KWin"), QStringLiteral("/Effects"), QDBusConnection::sessionBus()); if (geometryTip) { interface.loadEffect(KWin::BuiltInEffects::nameForEffect(KWin::BuiltInEffect::WindowGeometry)); } else { interface.unloadEffect(KWin::BuiltInEffects::nameForEffect(KWin::BuiltInEffect::WindowGeometry)); } emit KCModule::changed(false); } void KMovingConfig::defaults() { setGeometryTip(false); //copied from kcontrol/konq/kwindesktop, aleXXX setWindowSnapZone(KWM_WNDW_SNAP_ZONE_DEFAULT); setBorderSnapZone(KWM_BRDR_SNAP_ZONE_DEFAULT); setCenterSnapZone(KWM_CNTR_SNAP_ZONE_DEFAULT); m_ui->OverlapSnap->setChecked(false); emit KCModule::changed(true); } int KMovingConfig::getBorderSnapZone() { return m_ui->borderSnap->value(); } void KMovingConfig::setBorderSnapZone(int pxls) { m_ui->borderSnap->setValue(pxls); } int KMovingConfig::getWindowSnapZone() { return m_ui->windowSnap->value(); } void KMovingConfig::setWindowSnapZone(int pxls) { m_ui->windowSnap->setValue(pxls); } int KMovingConfig::getCenterSnapZone() { return m_ui->centerSnap->value(); } void KMovingConfig::setCenterSnapZone(int pxls) { m_ui->centerSnap->setValue(pxls); } #include "windows.moc"