From e4d35cab44f278b3f3a82906a55c06a150da0ae5 Mon Sep 17 00:00:00 2001 From: Mavridis Philippe Date: Thu, 22 Jun 2023 19:34:06 +0300 Subject: TWin: Add active corner support to quick tiling Signed-off-by: Mavridis Philippe (cherry picked from commit 5b1934dd5dc3245fcfd4a771fd45ed30dcaace54) --- twin/client.h | 3 + twin/geometry.cpp | 73 +++++++++++++++------ twin/kcmtwin/twinoptions/windows.cpp | 79 +++++++++++++++-------- twin/kcmtwin/twinoptions/windows.h | 3 + twin/options.cpp | 6 ++ twin/options.h | 3 + twin/utils.h | 8 +-- twin/workspace.cpp | 121 +++++++++++++++++------------------ 8 files changed, 180 insertions(+), 116 deletions(-) (limited to 'twin') diff --git a/twin/client.h b/twin/client.h index 332501f88..ae90fb619 100644 --- a/twin/client.h +++ b/twin/client.h @@ -233,7 +233,9 @@ class Client : public TQObject, public KDecorationDefines void resizeWithChecks( const TQSize& s, ForceGeometry_t force = NormalGeometrySet ); void keepInArea( TQRect area, bool partial = false ); void setActiveBorderMode( ActiveMaximizingMode mode ); + void setActiveBorder( ActiveBorder border); ActiveMaximizingMode activeBorderMode() const; + ActiveBorder activeBorder() const; void setActiveBorderMaximizing(bool maximizing); bool isActiveBorderMaximizing() const; TQRect activeBorderMaximizeGeometry(); @@ -609,6 +611,7 @@ class Client : public TQObject, public KDecorationDefines bool activeTiled; TQRect activeTiledOrigGeom; ActiveMaximizingMode activeMode; + ActiveBorder currentActiveBorder; friend bool performTransiencyCheck(); bool minimized_before_suspend; diff --git a/twin/geometry.cpp b/twin/geometry.cpp index 7dd38bee2..fc5f919cf 100644 --- a/twin/geometry.cpp +++ b/twin/geometry.cpp @@ -2718,6 +2718,14 @@ ActiveMaximizingMode Client::activeBorderMode() const return activeMode; } +void Client::setActiveBorder(ActiveBorder border) { + currentActiveBorder = border; +} + +ActiveBorder Client::activeBorder() const { + return currentActiveBorder; +} + bool Client::isActiveBorderMaximizing() const { return activeMaximizing; @@ -2740,7 +2748,7 @@ TQRect Client::activeBorderMaximizeGeometry() { TQRect ret; TQRect max = workspace()->clientArea(MaximizeArea, TQCursor::pos(), workspace()->currentDesktop()); - switch (activeMode) + switch (activeBorderMode()) { case ActiveMaximizeMode: { @@ -2750,25 +2758,52 @@ TQRect Client::activeBorderMaximizeGeometry() ret = max; break; } - case ActiveLeftMode: - { - ret = TQRect( max.x(), max.y(), max.width()/2, max.height() ); - break; - } - case ActiveRightMode: - { - ret = TQRect( max.x() + max.width()/2, max.y(), max.width()/2, max.height() ); - break; - } - case ActiveTopMode: - { - ret = TQRect( max.x(), max.y(), max.width(), max.height()/2 ); - break; - } - case ActiveBottomMode: + + case ActiveTilingMode: { - ret = TQRect( max.x(), max.y() + max.height()/2, max.width(), max.height()/2 ); - break; + switch (activeBorder()) + { + case ActiveLeft: + { + ret = TQRect( max.x(), max.y(), max.width()/2, max.height() ); + break; + } + case ActiveRight: + { + ret = TQRect( max.x() + max.width()/2, max.y(), max.width()/2, max.height() ); + break; + } + case ActiveTop: + { + ret = TQRect( max.x(), max.y(), max.width(), max.height()/2 ); + break; + } + case ActiveBottom: + { + ret = TQRect( max.x(), max.y() + max.height()/2, max.width(), max.height()/2 ); + break; + } + case ActiveTopLeft: + { + ret = TQRect( max.x(), max.y(), max.width()/2, max.height()/2 ); + break; + } + case ActiveTopRight: + { + ret = TQRect( max.x() + max.width()/2, max.y(), max.width()/2, max.height()/2 ); + break; + } + case ActiveBottomLeft: + { + ret = TQRect( max.x(), max.y() + max.height()/2, max.width()/2, max.height()/2 ); + break; + } + case ActiveBottomRight: + { + ret = TQRect( max.x() + max.width()/2, max.y() + max.height()/2, max.width()/2, max.height()/2); + break; + } + } } } return ret; diff --git a/twin/kcmtwin/twinoptions/windows.cpp b/twin/kcmtwin/twinoptions/windows.cpp index 3610eb443..f675ed1c4 100644 --- a/twin/kcmtwin/twinoptions/windows.cpp +++ b/twin/kcmtwin/twinoptions/windows.cpp @@ -56,33 +56,34 @@ // twin config keywords -#define KWIN_FOCUS "FocusPolicy" -#define KWIN_PLACEMENT "Placement" -#define KWIN_MOVE "MoveMode" -#define KWIN_MINIMIZE_ANIM "AnimateMinimize" -#define KWIN_MINIMIZE_ANIM_SPEED "AnimateMinimizeSpeed" -#define KWIN_RESIZE_OPAQUE "ResizeMode" -#define KWIN_GEOMETRY "GeometryTip" -#define KWIN_AUTORAISE_INTERVAL "AutoRaiseInterval" -#define KWIN_AUTORAISE "AutoRaise" -#define KWIN_DELAYFOCUS_INTERVAL "DelayFocusInterval" -#define KWIN_DELAYFOCUS "DelayFocus" -#define KWIN_CLICKRAISE "ClickRaise" -#define KWIN_ANIMSHADE "AnimateShade" -#define KWIN_MOVE_RESIZE_MAXIMIZED "MoveResizeMaximizedWindows" -#define KWIN_RESET_MAX_WIN_GEOM "ResetMaximizedWindowGeometry" -#define KWIN_ALTTABMODE "AltTabStyle" -#define KWIN_TRAVERSE_ALL "TraverseAll" -#define KWIN_SHOW_POPUP "ShowPopup" -#define KWIN_ROLL_OVER_DESKTOPS "RollOverDesktops" -#define KWIN_SHADEHOVER "ShadeHover" -#define KWIN_SHADEHOVER_INTERVAL "ShadeHoverInterval" -#define KWIN_FOCUS_STEALING "FocusStealingPreventionLevel" -#define KWIN_HIDE_UTILITY "HideUtilityWindowsForInactive" -#define KWIN_SEPARATE_SCREEN_FOCUS "SeparateScreenFocus" -#define KWIN_ACTIVE_MOUSE_SCREEN "ActiveMouseScreen" -#define KWIN_ACTIVE_BORDERS "ActiveBorders" -#define KWIN_ACTIVE_BORDER_DELAY "ActiveBorderDelay" +#define KWIN_FOCUS "FocusPolicy" +#define KWIN_PLACEMENT "Placement" +#define KWIN_MOVE "MoveMode" +#define KWIN_MINIMIZE_ANIM "AnimateMinimize" +#define KWIN_MINIMIZE_ANIM_SPEED "AnimateMinimizeSpeed" +#define KWIN_RESIZE_OPAQUE "ResizeMode" +#define KWIN_GEOMETRY "GeometryTip" +#define KWIN_AUTORAISE_INTERVAL "AutoRaiseInterval" +#define KWIN_AUTORAISE "AutoRaise" +#define KWIN_DELAYFOCUS_INTERVAL "DelayFocusInterval" +#define KWIN_DELAYFOCUS "DelayFocus" +#define KWIN_CLICKRAISE "ClickRaise" +#define KWIN_ANIMSHADE "AnimateShade" +#define KWIN_MOVE_RESIZE_MAXIMIZED "MoveResizeMaximizedWindows" +#define KWIN_RESET_MAX_WIN_GEOM "ResetMaximizedWindowGeometry" +#define KWIN_ALTTABMODE "AltTabStyle" +#define KWIN_TRAVERSE_ALL "TraverseAll" +#define KWIN_SHOW_POPUP "ShowPopup" +#define KWIN_ROLL_OVER_DESKTOPS "RollOverDesktops" +#define KWIN_SHADEHOVER "ShadeHover" +#define KWIN_SHADEHOVER_INTERVAL "ShadeHoverInterval" +#define KWIN_FOCUS_STEALING "FocusStealingPreventionLevel" +#define KWIN_HIDE_UTILITY "HideUtilityWindowsForInactive" +#define KWIN_SEPARATE_SCREEN_FOCUS "SeparateScreenFocus" +#define KWIN_ACTIVE_MOUSE_SCREEN "ActiveMouseScreen" +#define KWIN_ACTIVE_BORDERS "ActiveBorders" +#define KWIN_ACTIVE_BORDER_DELAY "ActiveBorderDelay" +#define KWIN_ACTIVE_BORDER_DISTANCE "ActiveBorderDistance" // legacy options #define KWIN_OLD_ACTIVE_BORDERS "ElectricBorders" @@ -700,6 +701,16 @@ KAdvancedConfig::KAdvancedConfig (bool _standAlone, TDEConfig *_config, TQWidget " active borders feature. The selected action will be performed after the mouse " " has been pushed against a screen border for the specified number of milliseconds.") ); + distance = new KIntNumInput(10, active_box); + distance->setRange(1, 100, 1, true); + distance->setSuffix(i18n(" px")); + distance->setLabel(i18n("Border &activation distance:")); + TQWhatsThis::add( distance, i18n("The distance from which an active border can" + " be activated. A lower value requires you to push repeatedly into the edge." + " Setting this to a higher value (e.g. 30) activates the borders when the" + " mouse is close enough, making them easier to activate but also more prone" + " to false activations.")); + active_vbox->addSpacing(10); active_vbox->addWidget(active_func_label); active_vbox->addWidget(active_disable); @@ -709,6 +720,7 @@ KAdvancedConfig::KAdvancedConfig (bool _standAlone, TDEConfig *_config, TQWidget active_vbox->addWidget(active_tile_conf); active_vbox->addSpacing(15); active_vbox->addWidget(delays); + active_vbox->addWidget(distance); connect(active_box, TQT_SIGNAL(clicked(int)), this, TQT_SLOT(setEBorders())); @@ -716,7 +728,8 @@ KAdvancedConfig::KAdvancedConfig (bool _standAlone, TDEConfig *_config, TQWidget connect(active_box, TQT_SIGNAL(clicked(int)), this, TQT_SLOT(changed())); connect(active_move, TQT_SIGNAL(clicked()), this, TQT_SLOT(changed())); connect(active_maximize, TQT_SIGNAL(clicked()), this, TQT_SLOT(changed())); - connect(delays, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(changed())); + connect(delays, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(changed())); + connect(distance, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(changed())); lay->addWidget(active_box); @@ -781,6 +794,7 @@ void KAdvancedConfig::load( void ) setActiveBorders(active_borders); setActiveBorderDelay(active_borders_delay); + setActiveBorderDistance(config->readNumEntry(KWIN_ACTIVE_BORDER_DISTANCE, 10)); setHideUtilityWindowsForInactive( config->readBoolEntry( KWIN_HIDE_UTILITY, true )); @@ -804,6 +818,7 @@ void KAdvancedConfig::save( void ) config->writeEntry(KWIN_ACTIVE_BORDERS, getActiveBorders()); config->writeEntry(KWIN_ACTIVE_BORDER_DELAY, getActiveBorderDelay()); + config->writeEntry(KWIN_ACTIVE_BORDER_DISTANCE, getActiveBorderDistance()); config->writeEntry(KWIN_HIDE_UTILITY, hideUtilityWindowsForInactive->isChecked()); @@ -828,6 +843,7 @@ void KAdvancedConfig::defaults() setShadeHoverInterval(250); setActiveBorders(0); setActiveBorderDelay(150); + setActiveBorderDistance(10); setHideUtilityWindowsForInactive( true ); emit TDECModule::changed(true); } @@ -858,6 +874,10 @@ int KAdvancedConfig::getActiveBorderDelay() return delays->value(); } +int KAdvancedConfig::getActiveBorderDistance() { + return distance->value(); +} + void KAdvancedConfig::setActiveBorders(int i){ switch(i) { @@ -883,6 +903,9 @@ void KAdvancedConfig::setActiveBorderDelay(int delay) delays->setValue(delay); } +void KAdvancedConfig::setActiveBorderDistance(int d) { + distance->setValue(d); +} KMovingConfig::~KMovingConfig () { diff --git a/twin/kcmtwin/twinoptions/windows.h b/twin/kcmtwin/twinoptions/windows.h index 435bd0521..63bf75331 100644 --- a/twin/kcmtwin/twinoptions/windows.h +++ b/twin/kcmtwin/twinoptions/windows.h @@ -228,8 +228,10 @@ private: int getActiveBorders( void ); int getActiveBorderDelay(); + int getActiveBorderDistance(); void setActiveBorders( int ); void setActiveBorderDelay( int ); + void setActiveBorderDistance( int ); TQButtonGroup *active_box; TQRadioButton *active_disable; @@ -238,6 +240,7 @@ private: TQRadioButton *active_tile; TQCheckBox *active_maximize; KIntNumInput *delays; + KIntNumInput *distance; TQWidget *active_desktop_conf; TQWidget *active_tile_conf; diff --git a/twin/options.cpp b/twin/options.cpp index 3d237255b..6a0963910 100644 --- a/twin/options.cpp +++ b/twin/options.cpp @@ -136,6 +136,7 @@ unsigned long Options::updateSettings() if (active_border_delay == -1) { active_border_delay = config->readNumEntry("ElectricBorderDelay", 150); } + active_border_distance = config->readNumEntry("ActiveBorderDistance", 10); OpTitlebarDblClick = windowOperation( config->readEntry("TitlebarDoubleClickCommand", "Shade"), true ); d->OpMaxButtonLeftClick = windowOperation( config->readEntry("MaximizeButtonLeftClickCommand", "Maximize"), true ); @@ -397,6 +398,11 @@ int Options::activeBorderDelay() return active_border_delay; } +int Options::borderActivationDistance() + { + return active_border_distance; + } + bool Options::checkIgnoreFocusStealing( const Client* c ) { return ignoreFocusStealingClasses.contains(TQString::fromLatin1(c->resourceClass())); diff --git a/twin/options.h b/twin/options.h index 55183e6bd..3227e57d7 100644 --- a/twin/options.h +++ b/twin/options.h @@ -326,6 +326,8 @@ class Options : public KDecorationOptions */ int activeBorders(); + int borderActivationDistance(); + /** * @returns the activation delay for active borders in milliseconds. */ @@ -386,6 +388,7 @@ class Options : public KDecorationOptions int active_borders; int active_border_delay; + int active_border_distance; bool show_geometry_tip; bool reset_maximized_window_geometry; bool topmenus; diff --git a/twin/utils.h b/twin/utils.h index 65c766690..e2e6e2a31 100644 --- a/twin/utils.h +++ b/twin/utils.h @@ -124,11 +124,9 @@ enum ActiveBorder enum ActiveMaximizingMode { - ActiveMaximizeMode, - ActiveLeftMode, - ActiveRightMode, - ActiveTopMode, - ActiveBottomMode + ActiveNoMode, + ActiveTilingMode, + ActiveMaximizeMode }; class Shape diff --git a/twin/workspace.cpp b/twin/workspace.cpp index 03a2e4e50..b8e6a2731 100644 --- a/twin/workspace.cpp +++ b/twin/workspace.cpp @@ -2524,54 +2524,65 @@ void Workspace::checkActiveBorder(const TQPoint &pos, Time now) Time treshold_set = options->activeBorderDelay(); // set timeout Time treshold_trigger = 250; // Minimum time between triggers Time treshold_reset = 250; // reset timeout - int distance_reset = 30; // Mouse should not move more than this many pixels + int activation_distance = options->borderActivationDistance(); - if ((pos.x() > activeLeft + distance_reset) && - (pos.x() < activeRight - distance_reset) && - (pos.y() > activeTop + distance_reset) && - (pos.y() < activeBottom - distance_reset)) + bool have_borders = false; + for (int i = 0; i < ACTIVE_BORDER_COUNT; ++i) + { + if (active_windows[ i ] != None) + { + have_borders = true; + } + } + if( !have_borders ) + return; + + // Mouse should not move more than this many pixels + int distance_reset = activation_distance + 10; + + // Leave active maximizing mode when window moved away + if (active_current_border != ActiveNone && + (pos.x() > activeLeft + distance_reset) && + (pos.x() < activeRight - distance_reset) && + (pos.y() > activeTop + distance_reset) && + (pos.y() < activeBottom - distance_reset)) { if (movingClient && (options->activeBorders() == Options::ActiveTileMaximize || options->activeBorders() == Options::ActiveTileOnly)) { movingClient->setActiveBorderMaximizing(false); + return; } } - if ((pos.x() != activeLeft) && - (pos.x() != activeRight) && - (pos.y() != activeTop) && - (pos.y() != activeBottom)) + bool active_left = pos.x() < activeLeft + activation_distance, + active_right = pos.x() > activeRight - activation_distance, + active_top = pos.y() < activeTop + activation_distance, + active_bottom = pos.y() > activeBottom - activation_distance; + + if (!active_left && !active_right && !active_top && !active_bottom) return; - bool have_borders = false; - for (int i = 0; i < ACTIVE_BORDER_COUNT; ++i) - { - if (active_windows[ i ] != None) - { - have_borders = true; - } - } - if( !have_borders ) - return; + kdDebug() << "active border activated " + << pos.x() << ":" << pos.y() << endl; - ActiveBorder border; - if( pos.x() == activeLeft && pos.y() == activeTop ) + ActiveBorder border = ActiveNone; + if (active_left && active_top) border = ActiveTopLeft; - else if( pos.x() == activeRight && pos.y() == activeTop ) + else if (active_right && active_top) border = ActiveTopRight; - else if( pos.x() == activeLeft && pos.y() == activeBottom ) + else if (active_left && active_bottom) border = ActiveBottomLeft; - else if( pos.x() == activeRight && pos.y() == activeBottom ) + else if (active_right && active_bottom) border = ActiveBottomRight; - else if( pos.x() == activeLeft ) + else if (active_left) border = ActiveLeft; - else if( pos.x() == activeRight ) + else if (active_right) border = ActiveRight; - else if( pos.y() == activeTop ) + else if (active_top) border = ActiveTop; - else if( pos.y() == activeBottom ) + else if (active_bottom) border = ActiveBottom; else abort(); @@ -2586,6 +2597,9 @@ void Workspace::checkActiveBorder(const TQPoint &pos, Time now) { active_time_last = now; + kdDebug() << "time diff between first time and now is: " + << timestampDiff(active_time_first, now) + << " vs threshold " << treshold_set << endl; if (timestampDiff(active_time_first, now) > treshold_set) { active_time_last_trigger = now; @@ -2608,43 +2622,19 @@ void Workspace::checkActiveBorder(const TQPoint &pos, Time now) border == ActiveTop && movingClient->isMaximizable()) { if (!movingClient->isResizable()) return; - bool enable = !movingClient->isActiveBorderMaximizing(); movingClient->setActiveBorderMode(ActiveMaximizeMode); - movingClient->setActiveBorderMaximizing(enable); + movingClient->setActiveBorder(ActiveNone); + movingClient->setActiveBorderMaximizing(true); } // Tiling else if ((options->activeBorders() == Options::ActiveTileMaximize || - options->activeBorders() == Options::ActiveTileOnly) && isSide) + options->activeBorders() == Options::ActiveTileOnly)) { if (!movingClient->isResizable()) return; - bool enable = !movingClient->isActiveBorderMaximizing(); - bool activate = false; - if (border == ActiveLeft) - { - movingClient->setActiveBorderMode( ActiveLeftMode ); - activate = true; - } - else if (border == ActiveRight) - { - movingClient->setActiveBorderMode( ActiveRightMode ); - activate = true; - } - else if (border == ActiveTop) - { - movingClient->setActiveBorderMode( ActiveTopMode ); - activate = true; - } - else if (border == ActiveBottom) - { - movingClient->setActiveBorderMode( ActiveBottomMode ); - activate = true; - } - - if (activate) - { - movingClient->setActiveBorderMaximizing(enable); - } + movingClient->setActiveBorderMode(ActiveTilingMode); + movingClient->setActiveBorder(border); + movingClient->setActiveBorderMaximizing(true); } else @@ -2671,13 +2661,16 @@ void Workspace::checkActiveBorder(const TQPoint &pos, Time now) active_push_point = pos; } - // reset the pointer to find out wether the user is really pushing - // (the direction back from which it came, starting from top clockwise) - const int xdiff[ ACTIVE_BORDER_COUNT ] = { 0, -1, -1, -1, 0, 1, 1, 1 }; - const int ydiff[ ACTIVE_BORDER_COUNT ] = { 1, 1, 0, -1, -1, -1, 0, 1 }; - TQCursor::setPos(pos.x() + xdiff[border], pos.y() + ydiff[border]); - + if ((options->activeBorders() == Options::ActiveSwitchAlways && !movingClient) || + activation_distance < 2) + { + // reset the pointer to find out whether the user is really pushing + // (the direction back from which it came, starting from top clockwise) + const int xdiff[ ACTIVE_BORDER_COUNT ] = { 0, -1, -1, -1, 0, 1, 1, 1 }; + const int ydiff[ ACTIVE_BORDER_COUNT ] = { 1, 1, 0, -1, -1, -1, 0, 1 }; + TQCursor::setPos(pos.x() + xdiff[border], pos.y() + ydiff[border]); } +} void Workspace::activeBorderSwitchDesktop(ActiveBorder border, const TQPoint& _pos) { -- cgit v1.2.1