From 850c1e6f0deb85b40a3a7cbc4cc8cb2bc1fdfba7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20L=C3=BCbking?= Date: Fri, 24 Aug 2012 18:48:50 +0200 Subject: [PATCH] add screen rule --- geometry.cpp | 9 +- kcmkwin/kwinrules/ruleswidget.cpp | 8 + kcmkwin/kwinrules/ruleswidget.h | 3 + kcmkwin/kwinrules/ruleswidgetbase.ui | 1046 ++++++++++++++------------ manage.cpp | 1 + rules.cpp | 26 + rules.h | 6 +- workspace.cpp | 1 + 8 files changed, 623 insertions(+), 477 deletions(-) diff --git a/geometry.cpp b/geometry.cpp index 3dbc2f1aba..d4c94510f6 100644 --- a/geometry.cpp +++ b/geometry.cpp @@ -2607,7 +2607,6 @@ static ElectricBorder electricBorderFromMode(QuickTileMode mode) void Client::finishMoveResize(bool cancel) { const bool wasResize = isResize(); // store across leaveMoveResize - const bool wasMove = isMove(); leaveMoveResize(); if (cancel) @@ -2623,8 +2622,12 @@ void Client::finishMoveResize(bool cancel) } setGeometry(moveResizeGeom); } - if (screen() != moveResizeStartScreen && maximizeMode() != MaximizeRestore) - checkWorkspacePosition(); + const int newScreen = screen(); + if (newScreen != moveResizeStartScreen) { + workspace()->sendClientToScreen(this, newScreen); // checks rule validity + if (maximizeMode() != MaximizeRestore) + checkWorkspacePosition(); + } if (isElectricBorderMaximizing()) { setQuickTileMode(electricMode); diff --git a/kcmkwin/kwinrules/ruleswidget.cpp b/kcmkwin/kwinrules/ruleswidget.cpp index 5c1ee928e6..264fc9455d 100644 --- a/kcmkwin/kwinrules/ruleswidget.cpp +++ b/kcmkwin/kwinrules/ruleswidget.cpp @@ -85,6 +85,7 @@ RulesWidget::RulesWidget(QWidget* parent) SETUP(position, set); SETUP(size, set); SETUP(desktop, set); + SETUP(screen, set); SETUP(activity, set); SETUP(maximizehoriz, set); SETUP(maximizevert, set); @@ -152,6 +153,7 @@ RulesWidget::RulesWidget(QWidget* parent) UPDATE_ENABLE_SLOT(position) UPDATE_ENABLE_SLOT(size) UPDATE_ENABLE_SLOT(desktop) +UPDATE_ENABLE_SLOT(screen) UPDATE_ENABLE_SLOT(activity) UPDATE_ENABLE_SLOT(maximizehoriz) UPDATE_ENABLE_SLOT(maximizevert) @@ -403,6 +405,7 @@ static NET::WindowType comboToType(int val) #define CHECKBOX_SET_RULE( var, func ) GENERIC_RULE( var, func, Set, set, setChecked, setChecked( false )) #define LINEEDIT_SET_RULE( var, func ) GENERIC_RULE( var, func, Set, set, setText, setText( "" )) #define COMBOBOX_SET_RULE( var, func ) GENERIC_RULE( var, func, Set, set, setCurrentIndex, setCurrentIndex( 0 )) +#define SPINBOX_SET_RULE( var, func ) GENERIC_RULE( var, func, Set, set, setValue, setValue(0)) #define CHECKBOX_FORCE_RULE( var, func ) GENERIC_RULE( var, func, Force, force, setChecked, setChecked( false )) #define LINEEDIT_FORCE_RULE( var, func ) GENERIC_RULE( var, func, Force, force, setText, setText( "" )) #define COMBOBOX_FORCE_RULE( var, func ) GENERIC_RULE( var, func, Force, force, setCurrentIndex, setCurrentIndex( 0 )) @@ -440,6 +443,7 @@ void RulesWidget::setRules(Rules* rules) LINEEDIT_SET_RULE(position, positionToStr); LINEEDIT_SET_RULE(size, sizeToStr); COMBOBOX_SET_RULE(desktop, desktopToCombo); + SPINBOX_SET_RULE(screen, inc); COMBOBOX_SET_RULE(activity, activityToCombo); CHECKBOX_SET_RULE(maximizehoriz,); CHECKBOX_SET_RULE(maximizevert,); @@ -475,6 +479,7 @@ void RulesWidget::setRules(Rules* rules) #undef CHECKBOX_SET_RULE #undef LINEEDIT_SET_RULE #undef COMBOBOX_SET_RULE +#undef SPINBOX_SET_RULE #undef CHECKBOX_FORCE_RULE #undef LINEEDIT_FORCE_RULE #undef COMBOBOX_FORCE_RULE @@ -492,6 +497,7 @@ void RulesWidget::setRules(Rules* rules) #define CHECKBOX_SET_RULE( var, func ) GENERIC_RULE( var, func, Set, set, isChecked ) #define LINEEDIT_SET_RULE( var, func ) GENERIC_RULE( var, func, Set, set, text ) #define COMBOBOX_SET_RULE( var, func ) GENERIC_RULE( var, func, Set, set, currentIndex ) +#define SPINBOX_SET_RULE( var, func ) GENERIC_RULE( var, func, Set, set, value) #define CHECKBOX_FORCE_RULE( var, func ) GENERIC_RULE( var, func, Force, force, isChecked ) #define LINEEDIT_FORCE_RULE( var, func ) GENERIC_RULE( var, func, Force, force, text ) #define COMBOBOX_FORCE_RULE( var, func ) GENERIC_RULE( var, func, Force, force, currentIndex ) @@ -534,6 +540,7 @@ Rules* RulesWidget::rules() const LINEEDIT_SET_RULE(position, strToPosition); LINEEDIT_SET_RULE(size, strToSize); COMBOBOX_SET_RULE(desktop, comboToDesktop); + SPINBOX_SET_RULE(screen, dec); COMBOBOX_SET_RULE(activity, comboToActivity); CHECKBOX_SET_RULE(maximizehoriz,); CHECKBOX_SET_RULE(maximizevert,); @@ -570,6 +577,7 @@ Rules* RulesWidget::rules() const #undef CHECKBOX_SET_RULE #undef LINEEDIT_SET_RULE #undef COMBOBOX_SET_RULE +#undef SPINBOX_SET_RULE #undef CHECKBOX_FORCE_RULE #undef LINEEDIT_FORCE_RULE #undef COMBOBOX_FORCE_RULE diff --git a/kcmkwin/kwinrules/ruleswidget.h b/kcmkwin/kwinrules/ruleswidget.h index 27cf7314ca..a4b5b91330 100644 --- a/kcmkwin/kwinrules/ruleswidget.h +++ b/kcmkwin/kwinrules/ruleswidget.h @@ -57,6 +57,7 @@ private slots: void updateEnableposition(); void updateEnablesize(); void updateEnabledesktop(); + void updateEnablescreen(); void updateEnableactivity(); void updateEnablemaximizehoriz(); void updateEnablemaximizevert(); @@ -96,6 +97,8 @@ private: int activityToCombo(QString d) const; QString comboToActivity(int val) const; int comboToTiling(int val) const; + int inc(int i) const { return i+1; } + int dec(int i) const { return i-1; } void prefillUnusedValues(const KWindowInfo& info); DetectDialog* detect_dlg; bool detect_dlg_ok; diff --git a/kcmkwin/kwinrules/ruleswidgetbase.ui b/kcmkwin/kwinrules/ruleswidgetbase.ui index 0ff1abd78c..a1aed46100 100644 --- a/kcmkwin/kwinrules/ruleswidgetbase.ui +++ b/kcmkwin/kwinrules/ruleswidgetbase.ui @@ -6,8 +6,8 @@ 0 0 - 569 - 535 + 630 + 580 @@ -489,7 +489,14 @@ &Size && Position - + + + + &Position + + + + false @@ -526,44 +533,7 @@ - - - - false - - - - Do Not Affect - - - - - Apply Initially - - - - - Remember - - - - - Force - - - - - Apply Now - - - - - Force Temporarily - - - - - + false @@ -583,93 +553,7 @@ - - - - false - - - width,height - - - 0123456789-+,xX: - - - - - - - false - - - - Do Not Affect - - - - - Force - - - - - Force Temporarily - - - - - - - - Sh&aded - - - - - - - M&inimized - - - - - - - false - - - - Do Not Affect - - - - - Apply Initially - - - - - Remember - - - - - Force - - - - - Apply Now - - - - - Force Temporarily - - - - - + false @@ -706,7 +590,339 @@ - + + + + false + + + width,height + + + 0123456789-+,xX: + + + + + + + Qt::Horizontal + + + + + + + Maximized &horizontally + + + + + + + false + + + + Do Not Affect + + + + + Apply Initially + + + + + Remember + + + + + Force + + + + + Apply Now + + + + + Force Temporarily + + + + + + + + false + + + + + + + Maximized &vertically + + + + + + + false + + + + Do Not Affect + + + + + Apply Initially + + + + + Remember + + + + + Force + + + + + Apply Now + + + + + Force Temporarily + + + + + + + + false + + + + + + + Qt::Horizontal + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + &Desktop + + + + + + + false + + + + Do Not Affect + + + + + Apply Initially + + + + + Remember + + + + + Force + + + + + Apply Now + + + + + Force Temporarily + + + + + + + + false + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Activit&y + + + + + + + false + + + + Do Not Affect + + + + + Apply Initially + + + + + Remember + + + + + Force + + + + + Apply Now + + + + + Force Temporarily + + + + + + + + false + + + + + + + false + + + 1 + + + + + + + Qt::Horizontal + + + + + + + &Fullscreen + + + + + + + false + + + + Do Not Affect + + + + + Apply Initially + + + + + Remember + + + + + Force + + + + + Apply Now + + + + + Force Temporarily + + + + + + + + false + + + + + + + M&inimized + + + + false @@ -743,21 +959,94 @@ - + false - - + + + + Sh&aded + + + + + + + false + + + + Do Not Affect + + + + + Apply Initially + + + + + Remember + + + + + Force + + + + + Apply Now + + + + + Force Temporarily + + + + + + false - + + + + Qt::Horizontal + + + + + + + false + + + + Do Not Affect + + + + + Force + + + + + Force Temporarily + + + + + false @@ -814,34 +1103,7 @@ - - - - false - - - width,height - - - 0123456789-+,xX: - - - - - - - M&aximum size - - - - - - - Qt::Horizontal - - - - + @@ -851,193 +1113,7 @@ - - - - false - - - - - - - false - - - - - - - Qt::Horizontal - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Eg. terminals or video players can ask to keep a certain aspect ratio -or only grow by values larger than one -(eg. by the dimensions of one character). -This may be pointless and the restriction prevents arbitrary dimensions -like your complete screen area. - - - Qt::LeftToRight - - - Obey geometry restrictions - - - - - - - - - - false - - - - Do Not Affect - - - - - Force - - - - - Force Temporarily - - - - - - - - Qt::Horizontal - - - - - - - false - - - - Do Not Affect - - - - - Apply Initially - - - - - Remember - - - - - Force - - - - - Apply Now - - - - - Force Temporarily - - - - - - - - false - - - - Do Not Affect - - - - - Apply Initially - - - - - Remember - - - - - Force - - - - - Apply Now - - - - - Force Temporarily - - - - - - - - false - - - - Do Not Affect - - - - - Force - - - - - Force Temporarily - - - - - - - - false - - - - + Windows can ask to appear in a certain position. @@ -1050,48 +1126,7 @@ to unconditionally popup in the middle of your screen. - - - - Maximized &horizontally - - - - - - - &Fullscreen - - - - - - - false - - - - - - - false - - - - - - - false - - - width,height - - - 0123456789-+,xX: - - - - + false @@ -1113,22 +1148,22 @@ to unconditionally popup in the middle of your screen. - - - - &Position - - - - - + + false - - + + + + Qt::Horizontal + + + + + false @@ -1137,26 +1172,11 @@ to unconditionally popup in the middle of your screen. Do Not Affect - - - Apply Initially - - - - - Remember - - Force - - - Apply Now - - Force Temporarily @@ -1164,48 +1184,89 @@ to unconditionally popup in the middle of your screen. - - - - Maximized &vertically - - - - - - - &Desktop - - - - + M&inimum size - - - - Qt::Horizontal + + + + false - - - 40 - 20 - + + width,height - - - - - - Qt::Horizontal + + 0123456789-+,xX: - + + + + M&aximum size + + + + + + + false + + + + Do Not Affect + + + + + Force + + + + + Force Temporarily + + + + + + + + false + + + width,height + + + 0123456789-+,xX: + + + + + + + Eg. terminals or video players can ask to keep a certain aspect ratio +or only grow by values larger than one +(eg. by the dimensions of one character). +This may be pointless and the restriction prevents arbitrary dimensions +like your complete screen area. + + + Qt::LeftToRight + + + Obey geometry restrictions + + + + + + + false @@ -1227,14 +1288,14 @@ to unconditionally popup in the middle of your screen. - - - - Qt::Horizontal + + + + false - + Qt::Vertical @@ -1250,15 +1311,8 @@ to unconditionally popup in the middle of your screen. - - - - Activit&y - - - - - + + false @@ -1294,10 +1348,10 @@ to unconditionally popup in the middle of your screen. - - - - false + + + + Screen @@ -2472,7 +2526,9 @@ but this may sometimes fail or superact. + description detect + detection_delay wmclass_match wmclass edit_reg_wmclass @@ -2494,13 +2550,22 @@ but this may sometimes fail or superact. rule_size size enable_maximizehoriz + rule_maximizehoriz enable_maximizevert rule_maximizevert - enable_fullscreen enable_desktop rule_desktop desktop + enable_activity + rule_activity + activity + enable_screen + rule_screen + screen + enable_fullscreen + rule_fullscreen enable_minimize + rule_minimize enable_shade rule_shade enable_placement @@ -2508,26 +2573,61 @@ but this may sometimes fail or superact. placement enable_ignoreposition rule_ignoreposition + enable_minsize + rule_minsize + minsize enable_maxsize rule_maxsize maxsize + enable_strictgeometry + rule_strictgeometry enable_above rule_above enable_below rule_below enable_autogroup + rule_autogroup enable_autogroupfg rule_autogroupfg enable_autogroupid rule_autogroupid + autogroupid + enable_skiptaskbar + rule_skiptaskbar + enable_skippager + rule_skippager + enable_skipswitcher + rule_skipswitcher + enable_shortcut + rule_shortcut + shortcut + shortcut_edit enable_noborder rule_noborder enable_opacityactive + rule_opacityactive opacityactive enable_opacityinactive rule_opacityinactive opacityinactive - description + enable_moveresizemode + rule_moveresizemode + moveresizemode + enable_fsplevel + rule_fsplevel + fsplevel + enable_acceptfocus + rule_acceptfocus + enable_disableglobalshortcuts + rule_disableglobalshortcuts + enable_closeable + rule_closeable + enable_type + rule_type + type + enable_blockcompositing + rule_blockcompositing + tabs @@ -2538,8 +2638,8 @@ but this may sometimes fail or superact. detectClicked() - 247 - 89 + 321 + 124 20 @@ -2554,8 +2654,8 @@ but this may sometimes fail or superact. wmclassMatchChanged() - 164 - 134 + 301 + 196 20 @@ -2570,8 +2670,8 @@ but this may sometimes fail or superact. roleMatchChanged() - 164 - 188 + 301 + 254 20 diff --git a/manage.cpp b/manage.cpp index ddeca11416..616f6b8902 100644 --- a/manage.cpp +++ b/manage.cpp @@ -232,6 +232,7 @@ bool Client::manage(Window w, bool isMapped) area = workspace()->clientArea(FullArea, geom.center(), desktop()); else { int screen = asn_data.xinerama() == -1 ? workspace()->activeScreen() : asn_data.xinerama(); + screen = rules()->checkScreen(screen, !isMapped); area = workspace()->clientArea(PlacementArea, workspace()->screenGeometry(screen).center(), desktop()); } diff --git a/rules.cpp b/rules.cpp index 5b94e76d1c..406c76962d 100644 --- a/rules.cpp +++ b/rules.cpp @@ -28,6 +28,7 @@ along with this program. If not, see . #include #ifndef KCMRULES +#include #include "client.h" #include "workspace.h" #endif @@ -52,6 +53,7 @@ Rules::Rules() , opacityinactiverule(UnusedForceRule) , ignorepositionrule(UnusedForceRule) , desktoprule(UnusedSetRule) + , screenrule(UnusedSetRule) , activityrule(UnusedSetRule) , typerule(UnusedForceRule) , maximizevertrule(UnusedSetRule) @@ -157,6 +159,7 @@ void Rules::readFromCfg(const KConfigGroup& cfg) opacityinactive = 100; READ_FORCE_RULE(ignoreposition, , false); READ_SET_RULE(desktop, , 0); + READ_SET_RULE(screen, , 0); READ_SET_RULE(activity, , QString()); type = readType(cfg, "type"); typerule = type != NET::Unknown ? readForceRule(cfg, "typerule") : UnusedForceRule; @@ -246,6 +249,7 @@ void Rules::write(KConfigGroup& cfg) const WRITE_FORCE_RULE(opacityinactive,); WRITE_FORCE_RULE(ignoreposition,); WRITE_SET_RULE(desktop,); + WRITE_SET_RULE(screen,); WRITE_SET_RULE(activity,); WRITE_FORCE_RULE(type, int); WRITE_SET_RULE(maximizevert,); @@ -287,6 +291,7 @@ bool Rules::isEmpty() const && opacityinactiverule == UnusedForceRule && ignorepositionrule == UnusedForceRule && desktoprule == UnusedSetRule + && screenrule == UnusedSetRule && activityrule == UnusedSetRule && typerule == UnusedForceRule && maximizevertrule == UnusedSetRule @@ -459,6 +464,10 @@ bool Rules::update(Client* c, int selection) updated = updated || desktop != c->desktop(); desktop = c->desktop(); } + if NOW_REMEMBER(Screen, screen) { + updated = updated || screen != c->screen(); + screen = c->screen(); + } if NOW_REMEMBER(Activity, activity) { // TODO: ivan - multiple activities support const QString & joinedActivities = c->activities().join(","); @@ -581,6 +590,7 @@ bool Rules::applyIgnoreGeometry(bool& ignore) const } APPLY_RULE(desktop, Desktop, int) +APPLY_RULE(screen, Screen, int) APPLY_RULE(activity, Activity, QString) APPLY_FORCE_RULE(type, Type, NET::WindowType) @@ -671,6 +681,7 @@ void Rules::discardUsed(bool withdrawn) DISCARD_USED_FORCE_RULE(opacityinactive); DISCARD_USED_FORCE_RULE(ignoreposition); DISCARD_USED_SET_RULE(desktop); + DISCARD_USED_SET_RULE(screen); DISCARD_USED_SET_RULE(activity); DISCARD_USED_FORCE_RULE(type); DISCARD_USED_SET_RULE(maximizevert); @@ -798,6 +809,20 @@ KDecorationDefines::MaximizeMode WindowRules::checkMaximize(MaximizeMode mode, b return static_cast< MaximizeMode >((vert ? MaximizeVertical : 0) | (horiz ? MaximizeHorizontal : 0)); } +int WindowRules::checkScreen(int screen, bool init) const +{ + if ( rules.count() == 0 ) + return screen; + int ret = screen; + for ( QVector< Rules* >::ConstIterator it = rules.constBegin(); it != rules.constEnd(); ++it ) { + if ( (*it)->applyScreen( ret, init )) + break; + } + if (ret >= QApplication::desktop()->screenCount()) + ret = screen; + return ret; +} + CHECK_RULE(Minimize, bool) CHECK_RULE(Shade, ShadeMode) CHECK_RULE(SkipTaskbar, bool) @@ -843,6 +868,7 @@ void Client::applyWindowRules() // MinSize, MaxSize handled by Geometry // IgnorePosition setDesktop(desktop()); + workspace()->sendClientToScreen(this, screen()); setOnActivities(activities()); // Type maximize(maximizeMode()); diff --git a/rules.h b/rules.h index bf299f0a14..418311efc9 100644 --- a/rules.h +++ b/rules.h @@ -63,6 +63,7 @@ public: int checkOpacityInactive(int s) const; bool checkIgnoreGeometry(bool ignore) const; int checkDesktop(int desktop, bool init = false) const; + int checkScreen(int screen, bool init = false) const; QString checkActivity(QString activity, bool init = false) const; NET::WindowType checkType(NET::WindowType type) const; MaximizeMode checkMaximize(MaximizeMode mode, bool init = false) const; @@ -106,7 +107,7 @@ public: Shade = 1<<6, SkipTaskbar = 1<<7, SkipPager = 1<<8, SkipSwitcher = 1<<9, Above = 1<<10, Below = 1<<11, Fullscreen = 1<<12, NoBorder = 1<<13, OpacityActive = 1<<14, OpacityInactive = 1<<15, - Activity = 1<<16, All = 0xffffffff + Activity = 1<<16, Screen = 1<<17, All = 0xffffffff }; Q_DECLARE_FLAGS(Types, Type) void write(KConfigGroup&) const; @@ -128,6 +129,7 @@ public: bool applyOpacityInactive(int& s) const; bool applyIgnoreGeometry(bool& ignore) const; bool applyDesktop(int& desktop, bool init) const; + bool applyScreen(int& desktop, bool init) const; bool applyActivity(QString& activity, bool init) const; bool applyType(NET::WindowType& type) const; bool applyMaximizeVert(MaximizeMode& mode, bool init) const; @@ -225,6 +227,8 @@ private: ForceRule ignorepositionrule; int desktop; SetRule desktoprule; + int screen; + SetRule screenrule; QString activity; SetRule activityrule; NET::WindowType type; // type for setting diff --git a/workspace.cpp b/workspace.cpp index 258a237534..5b37aee2bc 100644 --- a/workspace.cpp +++ b/workspace.cpp @@ -1744,6 +1744,7 @@ int Workspace::screenNumber(const QPoint& pos) const void Workspace::sendClientToScreen(Client* c, int screen) { + screen = c->rules()->checkScreen(screen); if (c->screen() == screen) // Don't use isOnScreen(), that's true even when only partially return; GeometryUpdatesBlocker blocker(c);