diff --git a/client.h b/client.h
index 2d15ff558e..2e020a0fe5 100644
--- a/client.h
+++ b/client.h
@@ -348,7 +348,7 @@ class Client : public QObject, public KDecorationDefines
bool isNormalState() const;
bool isManaged() const; // returns false if this client is not yet managed
void updateAllowedActions( bool force = false );
- QSize sizeForClientSize( const QSize&, Sizemode mode = SizemodeAny ) const;
+ QSize sizeForClientSize( const QSize&, Sizemode mode = SizemodeAny, bool noframe = false ) const;
void changeMaximize( bool horizontal, bool vertical, bool adjust );
void checkMaximizeGeometry();
bool checkFullScreenHack( const QRect& geom ) const;
diff --git a/geometry.cpp b/geometry.cpp
index 47e83e497e..3aba5d589b 100644
--- a/geometry.cpp
+++ b/geometry.cpp
@@ -1003,7 +1003,7 @@ QSize Client::adjustedSize( const QSize& frame, Sizemode mode ) const
QSize wsize( frame.width() - ( border_left + border_right ),
frame.height() - ( border_top + border_bottom ));
- return sizeForClientSize( wsize, mode );
+ return sizeForClientSize( wsize, mode, false );
}
/*!
@@ -1014,7 +1014,7 @@ QSize Client::adjustedSize( const QSize& frame, Sizemode mode ) const
maximum and incremental size changes).
*/
-QSize Client::sizeForClientSize( const QSize& wsize, Sizemode mode ) const
+QSize Client::sizeForClientSize( const QSize& wsize, Sizemode mode, bool noframe ) const
{
int w = wsize.width();
int h = wsize.height();
@@ -1164,17 +1164,23 @@ QSize Client::sizeForClientSize( const QSize& wsize, Sizemode mode ) const
w += xSizeHint.base_width;
h += xSizeHint.base_height;
}
- // disobey increments and aspect when maximized
- if( maximizeMode() & MaximizeHorizontal )
- w = w1;
- if( maximizeMode() & MaximizeVertical )
- h = h1;
+ if( !rules()->checkStrictGeometry( false ))
+ {
+ // disobey increments and aspect when maximized
+ if( maximizeMode() & MaximizeHorizontal )
+ w = w1;
+ if( maximizeMode() & MaximizeVertical )
+ h = h1;
+ }
- w += border_left + border_right;
- h += border_top + border_bottom;
+ if( !noframe )
+ {
+ w += border_left + border_right;
+ h += border_top + border_bottom;
+ }
QSize ret = rules()->checkSize( QSize( w, h ));
if ( mode == SizemodeShaded && wsize.height() == 0 )
- ret.setHeight( border_top + border_bottom );
+ ret.setHeight( noframe ? 0 : border_top + border_bottom );
return ret;
}
@@ -1919,14 +1925,23 @@ bool Client::isFullScreenable( bool fullscreen_hack ) const
return false;
if( fullscreen_hack )
return isNormalWindow() || isOverride();
- else // don't check size constrains - some apps request fullscreen despite requesting fixed size
- return !isSpecialWindow(); // also better disallow only weird types to go fullscreen
+ if( rules()->checkStrictGeometry( false ))
+ {
+ // the app wouldn't fit exactly fullscreen geometry due its strict geometry requirements
+ QRect fsarea = workspace()->clientArea( FullScreenArea, this );
+ if( sizeForClientSize( fsarea.size(), SizemodeAny, true ) != fsarea.size())
+ return false;
+ }
+ // don't check size constrains - some apps request fullscreen despite requesting fixed size
+ return !isSpecialWindow(); // also better disallow only weird types to go fullscreen
}
bool Client::userCanSetFullScreen() const
{
if( fullscreen_mode == FullScreenHack )
return false;
+ if( !isFullScreenable( false ))
+ return false;
// isMaximizable() returns false if fullscreen
TemporaryAssign< FullScreenMode > tmp( fullscreen_mode, FullScreenNone );
return isNormalWindow() && isMaximizable();
diff --git a/kcmkwin/kwinrules/ruleswidget.cpp b/kcmkwin/kwinrules/ruleswidget.cpp
index 24f558bf71..e148fdba96 100644
--- a/kcmkwin/kwinrules/ruleswidget.cpp
+++ b/kcmkwin/kwinrules/ruleswidget.cpp
@@ -96,6 +96,7 @@ RulesWidget::RulesWidget( QWidget* parent, const char* name )
SETUP( ignoreposition, force );
SETUP( minsize, force );
SETUP( maxsize, force );
+ SETUP( strictgeometry, force );
KWinModule module;
int i;
for( i = 1;
@@ -141,6 +142,7 @@ UPDATE_ENABLE_SLOT( type )
UPDATE_ENABLE_SLOT( ignoreposition )
UPDATE_ENABLE_SLOT( minsize )
UPDATE_ENABLE_SLOT( maxsize )
+UPDATE_ENABLE_SLOT( strictgeometry )
#undef UPDATE_ENABLE_SLOT
@@ -395,6 +397,7 @@ void RulesWidget::setRules( Rules* rules )
CHECKBOX_FORCE_RULE( ignoreposition, );
LINEEDIT_FORCE_RULE( minsize, sizeToStr );
LINEEDIT_FORCE_RULE( maxsize, sizeToStr );
+ CHECKBOX_FORCE_RULE( strictgeometry, );
}
#undef GENERIC_RULE
@@ -482,6 +485,7 @@ Rules* RulesWidget::rules() const
CHECKBOX_FORCE_RULE( ignoreposition, );
LINEEDIT_FORCE_RULE( minsize, strToSize );
LINEEDIT_FORCE_RULE( maxsize, strToSize );
+ CHECKBOX_FORCE_RULE( strictgeometry, );
return rules;
}
@@ -596,6 +600,7 @@ void RulesWidget::prefillUnusedValues( const KWin::WindowInfo& info )
//CHECKBOX_PREFILL( ignoreposition, );
LINEEDIT_PREFILL( minsize, sizeToStr, info.frameGeometry().size() );
LINEEDIT_PREFILL( maxsize, sizeToStr, info.frameGeometry().size() );
+ //CHECKBOX_PREFILL( strictgeometry, );
}
#undef GENERIC_PREFILL
diff --git a/kcmkwin/kwinrules/ruleswidget.h b/kcmkwin/kwinrules/ruleswidget.h
index 637dcd0bd9..00bc9d48bc 100644
--- a/kcmkwin/kwinrules/ruleswidget.h
+++ b/kcmkwin/kwinrules/ruleswidget.h
@@ -78,6 +78,7 @@ class RulesWidget
void updateEnableignoreposition();
void updateEnableminsize();
void updateEnablemaxsize();
+ void updateEnablestrictgeometry();
// internal
void detected( bool );
private:
diff --git a/kcmkwin/kwinrules/ruleswidgetbase.ui b/kcmkwin/kwinrules/ruleswidgetbase.ui
index 7ad6e6a1a0..f5a92380a0 100644
--- a/kcmkwin/kwinrules/ruleswidgetbase.ui
+++ b/kcmkwin/kwinrules/ruleswidgetbase.ui
@@ -1913,43 +1913,6 @@
0123456789-+,xX:
-
-
- ignoreposition
-
-
- false
-
-
-
-
-
-
-
- enable_ignoreposition
-
-
- Ignore requested &position
-
-
-
- -
-
- Do Not Affect
-
-
- -
-
- Force
-
-
-
- rule_ignoreposition
-
-
- false
-
-
enable_minsize
@@ -2013,7 +1976,33 @@
false
-
+
+
+ enable_ignoreposition
+
+
+ Ignore requested &position
+
+
+
+ -
+
+ Do Not Affect
+
+
+ -
+
+ Force
+
+
+
+ rule_ignoreposition
+
+
+ false
+
+
+
spacer35
@@ -2026,10 +2015,61 @@
20
- 90
+ 190
+
+
+ ignoreposition
+
+
+ false
+
+
+
+
+
+
+
+ enable_strictgeometry
+
+
+ Strictly obey geometry
+
+
+
+
+
+
+ -
+
+ Do Not Affect
+
+
+ -
+
+ Force
+
+
+
+ rule_strictgeometry
+
+
+ false
+
+
+
+
+ strictgeometry
+
+
+ false
+
+
+
+
+
@@ -2222,8 +2262,9 @@
kcombobox.h
krestrictedline.h
kcombobox.h
- kcombobox.h
krestrictedline.h
kcombobox.h
+ kcombobox.h
+ kcombobox.h
diff --git a/rules.cpp b/rules.cpp
index 8326b012da..247b2803f0 100644
--- a/rules.cpp
+++ b/rules.cpp
@@ -58,6 +58,7 @@ Rules::Rules()
, acceptfocusrule( UnusedForceRule )
, moveresizemoderule( UnusedForceRule )
, closeablerule( UnusedForceRule )
+ , strictgeometry( UnusedForceRule )
{
}
@@ -157,6 +158,7 @@ void Rules::readFromCfg( KConfig& cfg )
READ_FORCE_RULE( acceptfocus, Bool, );
READ_FORCE_RULE( moveresizemode, , Options::stringToMoveResizeMode );
READ_FORCE_RULE( closeable, Bool, );
+ READ_FORCE_RULE( strictgeometry, Bool, );
}
#undef READ_MATCH_STRING
@@ -243,6 +245,7 @@ void Rules::write( KConfig& cfg ) const
WRITE_FORCE_RULE( acceptfocus, );
WRITE_FORCE_RULE( moveresizemode, Options::moveResizeModeToString );
WRITE_FORCE_RULE( closeable, );
+ WRITE_FORCE_RULE( strictgeometry, );
}
#undef WRITE_MATCH_STRING
@@ -276,7 +279,8 @@ bool Rules::isEmpty() const
&& fsplevelrule == UnusedForceRule
&& acceptfocusrule == UnusedForceRule
&& moveresizemoderule == UnusedForceRule
- && closeablerule == UnusedForceRule );
+ && closeablerule == UnusedForceRule
+ && strictgeometryrule == UnusedForceRule );
}
Rules::SetRule Rules::readSetRule( KConfig& cfg, const QString& key )
@@ -593,6 +597,7 @@ APPLY_FORCE_RULE( fsplevel, FSP, int )
APPLY_FORCE_RULE( acceptfocus, AcceptFocus, bool )
APPLY_FORCE_RULE( moveresizemode, MoveResizeMode, Options::MoveResizeMode )
APPLY_FORCE_RULE( closeable, Closeable, bool )
+APPLY_FORCE_RULE( strictgeometry, StrictGeometry, bool )
#undef APPLY_RULE
#undef APPLY_FORCE_RULE
@@ -722,6 +727,7 @@ CHECK_FORCE_RULE( FSP, int )
CHECK_FORCE_RULE( AcceptFocus, bool )
CHECK_FORCE_RULE( MoveResizeMode, Options::MoveResizeMode )
CHECK_FORCE_RULE( Closeable, bool )
+CHECK_FORCE_RULE( StrictGeometry, bool )
#undef CHECK_RULE
#undef CHECK_FORCE_RULE
@@ -773,6 +779,9 @@ void Client::setupWindowRules( bool ignore_temporary )
workspace()->activateNextClient( this );
// MoveResizeMode
// Closeable
+ QSize s = adjustedSize( size());
+ if( s != size())
+ resizeWithChecks( s );
}
}
diff --git a/rules.h b/rules.h
index c40ef7d23b..e8f1e46f47 100644
--- a/rules.h
+++ b/rules.h
@@ -65,6 +65,7 @@ class WindowRules
bool checkAcceptFocus( bool focus ) const;
Options::MoveResizeMode checkMoveResizeMode( Options::MoveResizeMode mode ) const;
bool checkCloseable( bool closeable ) const;
+ bool checkStrictGeometry( bool strict ) const;
private:
MaximizeMode checkMaximizeVert( MaximizeMode mode, bool init ) const;
MaximizeMode checkMaximizeHoriz( MaximizeMode mode, bool init ) const;
@@ -112,6 +113,7 @@ class Rules
bool applyAcceptFocus( bool& focus ) const;
bool applyMoveResizeMode( Options::MoveResizeMode& mode ) const;
bool applyCloseable( bool& closeable ) const;
+ bool applyStrictGeometry( bool& strict ) const;
private:
#endif
bool matchType( NET::WindowType match_type ) const;
@@ -219,6 +221,8 @@ class Rules
ForceRule moveresizemoderule;
bool closeable;
ForceRule closeablerule;
+ bool strictgeometry;
+ ForceRule strictgeometryrule;
friend kdbgstream& operator<<( kdbgstream& stream, const Rules* );
};