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* ); };