diff --git a/client.h b/client.h index fdc6655fd8..0e30000baf 100644 --- a/client.h +++ b/client.h @@ -72,6 +72,7 @@ class Client : public QObject, public KDecorationDefines QRect geometry() const; QSize size() const; QSize minSize() const; + QSize maxSize() const; QPoint pos() const; QRect rect() const; int x() const; @@ -753,11 +754,6 @@ inline QSize Client::size() const return frame_geometry.size(); } -inline QSize Client::minSize() const - { - return QSize( xSizeHint.min_width, xSizeHint.min_height ); - } - inline QPoint Client::pos() const { return frame_geometry.topLeft(); diff --git a/geometry.cpp b/geometry.cpp index 4215a06888..e7d9ac9cd3 100644 --- a/geometry.cpp +++ b/geometry.cpp @@ -27,6 +27,7 @@ License. See the file "COPYING" for the exact licensing terms. #include "placement.h" #include "notifications.h" #include "geometrytip.h" +#include "rules.h" extern Time qt_x_time; @@ -818,8 +819,8 @@ QSize Client::sizeForClientSize( const QSize& wsize, Sizemode mode ) const // basesize, minsize, maxsize, paspect and resizeinc have all values defined, // even if they're not set in flags - see getWmNormalHints() - QSize min_size( xSizeHint.min_width, xSizeHint.min_height ); - QSize max_size( xSizeHint.max_width, xSizeHint.max_height ); + QSize min_size = minSize(); + QSize max_size = maxSize(); if( decoration != NULL ) { QSize decominsize = decoration->minimumSize(); @@ -1024,6 +1025,16 @@ void Client::getWmNormalHints() updateAllowedActions(); // affects isResizeable() } +QSize Client::minSize() const + { + return rules()->checkMinSize( QSize( xSizeHint.min_width, xSizeHint.min_height )); + } + +QSize Client::maxSize() const + { + return rules()->checkMaxSize( QSize( xSizeHint.max_width, xSizeHint.max_height )); + } + /*! Auxiliary function to inform the client about the current window configuration. @@ -1287,10 +1298,9 @@ bool Client::isResizable() const if ( !isMovable() || !motif_may_resize || isSplash()) return FALSE; - if ( ( xSizeHint.flags & PMaxSize) == 0 || (xSizeHint.flags & PMinSize ) == 0 ) - return TRUE; - return ( xSizeHint.min_width < xSizeHint.max_width ) || - ( xSizeHint.min_height < xSizeHint.max_height ); + QSize min = minSize(); + QSize max = maxSize(); + return min.width() < max.width() || min.height() < max.height(); } /* @@ -1302,7 +1312,8 @@ bool Client::isMaximizable() const return TRUE; if( !isResizable() || isToolbar()) // SELI isToolbar() ? return false; - if( xSizeHint.max_height < 32767 || xSizeHint.max_width < 32767 ) // sizes are 16bit with X + QSize max = maxSize(); + if( max.width() < 32767 || max.height() < 32767 ) // sizes are 16bit with X return false; return true; } diff --git a/manage.cpp b/manage.cpp index 26946bcb29..960bff219f 100644 --- a/manage.cpp +++ b/manage.cpp @@ -252,9 +252,11 @@ bool Client::manage( Window w, bool isMapped ) } if (xSizeHint.flags & PMaxSize) - geom.setSize( geom.size().boundedTo( QSize(xSizeHint.max_width, xSizeHint.max_height ) ) ); + geom.setSize( geom.size().boundedTo( + rules()->checkMaxSize( QSize(xSizeHint.max_width, xSizeHint.max_height ) ) ) ); if (xSizeHint.flags & PMinSize) - geom.setSize( geom.size().expandedTo( QSize(xSizeHint.min_width, xSizeHint.min_height ) ) ); + geom.setSize( geom.size().expandedTo( + rules()->checkMinSize( QSize(xSizeHint.min_width, xSizeHint.min_height ) ) ) ); if( isMovable()) { diff --git a/rules.cpp b/rules.cpp index 0ad9a53533..fd5390ebc6 100644 --- a/rules.cpp +++ b/rules.cpp @@ -30,6 +30,8 @@ WindowRules::WindowRules() , clientmachineregexp( false ) , types( NET::AllTypesMask ) , placementrule( DontCareRule ) + , minsizerule( DontCareRule ) + , maxsizerule( DontCareRule ) , desktoprule( DontCareRule ) , typerule( DontCareRule ) , aboverule( DontCareRule ) @@ -53,6 +55,10 @@ WindowRules::WindowRules( KConfig& cfg ) types = cfg.readUnsignedLongNumEntry( "types", NET::AllTypesMask ); placement = Placement::policyFromString( cfg.readEntry( "placement" ), false ); placementrule = readRule( cfg, "placementrule" ); + minsize = cfg.readSizeEntry( "minsize" ); + minsizerule = readRule( cfg, "minsizerule" ); + maxsize = cfg.readSizeEntry( "maxsize" ); + maxsizerule = readRule( cfg, "maxsizerule" ); desktop = cfg.readNumEntry( "desktop" ); desktoprule = readRule( cfg, "desktoprule" ); type = readType( cfg, "type" ); @@ -107,6 +113,8 @@ void WindowRules::write( KConfig& cfg ) const WRITE_MATCH_STRING( clientmachine, (const char*) ); WRITE_WITH_DEFAULT( types, NET::AllTypesMask ); WRITE_SET_RULE( placement, Placement::policyToString ); + WRITE_SET_RULE( minsize, ); + WRITE_SET_RULE( maxsize, ); WRITE_SET_RULE( desktop, ); WRITE_SET_RULE( type, ); WRITE_SET_RULE( above, ); @@ -203,6 +211,16 @@ Placement::Policy WindowRules::checkPlacement( Placement::Policy placement ) con return checkForceRule( placementrule ) ? this->placement : placement; } +QSize WindowRules::checkMinSize( const QSize& s ) const + { + return checkForceRule( minsizerule ) ? this->minsize : s; + } + +QSize WindowRules::checkMaxSize( const QSize& s ) const + { + return checkForceRule( maxsizerule ) ? this->maxsize : s; + } + int WindowRules::checkDesktop( int req_desktop, bool init ) const { // TODO chaining? diff --git a/rules.h b/rules.h index a873e0dd00..a68394b659 100644 --- a/rules.h +++ b/rules.h @@ -13,6 +13,7 @@ License. See the file "COPYING" for the exact licensing terms. #include #include +#include #include "placement.h" @@ -41,6 +42,8 @@ class WindowRules void update( Client* ); bool match( const Client* c ) const; Placement::Policy checkPlacement( Placement::Policy placement ) const; + QSize checkMinSize( const QSize& s ) const; + QSize checkMaxSize( const QSize& s ) const; int checkDesktop( int desktop, bool init = false ) const; NET::WindowType checkType( NET::WindowType type ) const; bool checkKeepAbove( bool above, bool init = false ) const; @@ -65,6 +68,10 @@ class WindowRules unsigned long types; // types for matching Placement::Policy placement; SettingRule placementrule; + QSize minsize; + SettingRule minsizerule; + QSize maxsize; + SettingRule maxsizerule; int desktop; SettingRule desktoprule; NET::WindowType type; // type for setting