summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMavridis Philippe <mavridisf@gmail.com>2024-11-13 17:48:10 +0200
committerMavridis Philippe <mavridisf@gmail.com>2024-11-19 19:10:45 +0200
commitc913d416f7102f9d091c39dfd32db9b802f32983 (patch)
tree8b5482a0f089a87d37fa204e724d2c78857b08f4
parent1afb78e598cc0d8c320e98c963cb98ab7935435f (diff)
downloadtdebase-feat/grid-tiling.tar.gz
tdebase-feat/grid-tiling.zip
TWin: add "Grid tiling" featurefeat/grid-tiling
Signed-off-by: Mavridis Philippe <mavridisf@gmail.com>
-rw-r--r--twin/client.cpp5
-rw-r--r--twin/client.h9
-rw-r--r--twin/events.cpp75
-rw-r--r--twin/geometry.cpp48
-rw-r--r--twin/kcmtwin/twinoptions/windows.cpp30
-rw-r--r--twin/kcmtwin/twinoptions/windows.h3
-rw-r--r--twin/options.cpp1
-rw-r--r--twin/options.h2
-rw-r--r--twin/workspace.cpp13
-rw-r--r--twin/workspace.h2
10 files changed, 174 insertions, 14 deletions
diff --git a/twin/client.cpp b/twin/client.cpp
index b8f00746e..5d831acec 100644
--- a/twin/client.cpp
+++ b/twin/client.cpp
@@ -123,7 +123,10 @@ Client::Client( Workspace *ws )
opacity_( 0 ),
demandAttentionKNotifyTimer( NULL ),
activeMaximizing(false),
- activeTiled(false)
+ activeTiled(false),
+ gridTilingMode(false),
+ hGridTiles(1),
+ vGridTiles(1)
// SELI do all as initialization
{
autoRaiseTimer = 0;
diff --git a/twin/client.h b/twin/client.h
index a59b20acd..c05e8f116 100644
--- a/twin/client.h
+++ b/twin/client.h
@@ -242,6 +242,11 @@ class Client : public TQObject, public KDecorationDefines
TQRect activeBorderMaximizeGeometry();
void tileToBorder(ActiveBorder border);
+ TQSize gridTileSize();
+ void handleGridTiling(TQRect geom);
+ void handleGridTilesChange(TQt::Orientation o, int delta);
+ bool isGridTiling() { return gridTilingMode; }
+
void growHorizontal();
void shrinkHorizontal();
void growVertical();
@@ -618,6 +623,10 @@ class Client : public TQObject, public KDecorationDefines
ActiveMaximizingMode activeMode;
ActiveBorder currentActiveBorder;
+ bool gridTilingMode;
+ int vGridTiles, hGridTiles;
+ TQRect gridTileGeom;
+
friend bool performTransiencyCheck();
bool minimized_before_suspend;
};
diff --git a/twin/events.cpp b/twin/events.cpp
index 3d3ba999c..11d621487 100644
--- a/twin/events.cpp
+++ b/twin/events.cpp
@@ -228,13 +228,30 @@ bool Workspace::workspaceEvent( XEvent * e )
{
was_user_interaction = true;
KKeyNative keyX( (XEvent*)e );
- uint keyQt = keyX.keyCodeQt();
+
kdDebug(125) << "Workspace::keyPress( " << keyX.key().toString() << " )" << endl;
if (movingClient)
+ {
+ uint keyQt = keyX.keyCodeQt();
+ keyQt = keyQt & TQt::SHIFT ? keyQt ^ TQt::SHIFT : keyQt;
+
+ // Check for grid tiling
+ if (options->gridTiling)
{
- movingClient->keyPressEvent(keyQt);
- return true;
+ if (keyQt == TQt::Key_BracketLeft || keyQt == TQt::Key_BracketRight)
+ {
+ movingClient->handleGridTilesChange(TQt::Horizontal, keyQt == Key_BracketRight ? 1 : -1);
+ return true;
+ }
+ else if (keyQt == TQt::Key_BraceLeft || keyQt == TQt::Key_BraceRight)
+ {
+ movingClient->handleGridTilesChange(TQt::Vertical, keyQt == Key_BraceRight ? 1 : -1);
+ return true;
+ }
}
+ movingClient->keyPressEvent(keyX.keyCodeQt());
+ return true;
+ }
if( tab_grab || control_grab )
{
tabBoxKeyPress( keyX );
@@ -1338,9 +1355,51 @@ bool Client::eventFilter( TQObject* o, TQEvent* e )
return false;
}
+void Client::handleGridTilesChange(TQt::Orientation o, int delta)
+{
+ if (!isMove() || !isResizable()) return;
+
+ int *gridTiles = (o == TQt::Horizontal ? &hGridTiles : &vGridTiles);
+ if (delta > 0)
+ {
+ if (!gridTilingMode)
+ {
+ gridTilingMode = true;
+ hGridTiles = 1;
+ vGridTiles = 1;
+ }
+ }
+
+ if ((*gridTiles) + delta > 0) (*gridTiles) += delta;
+
+ // Single big tile == cancel grid tiling
+ if (hGridTiles == 1 && vGridTiles == 1)
+ {
+ gridTilingMode = false;
+ }
+
+ // If the resulting tile is too small to accomodate the window,
+ // then undo the tile count change
+ TQSize tileSize = gridTileSize();
+ TQSize minWSize = minSize();
+ if (tileSize.width() < minWSize.width() ||
+ tileSize.height() < minWSize.height())
+ {
+ (*gridTiles) -= delta;
+ }
+
+ clearbound();
+}
+
// return value matters only when filtering events before decoration gets them
bool Client::buttonPressEvent( Window w, int button, int state, int x, int y, int x_root, int y_root )
{
+ if (options->gridTiling && button > 7 && button < 10)
+ {
+ handleGridTilesChange(state & ShiftMask ? TQt::Vertical : TQt::Horizontal,
+ button == 9 ? 1 : -1);
+ }
+
if (buttonDown)
{
if( w == wrapperId())
@@ -1353,6 +1412,7 @@ bool Client::buttonPressEvent( Window w, int button, int state, int x, int y, in
// FRAME something out of this would be processed before it gets decorations
updateUserTime();
workspace()->setWasUserInteraction();
+
uint keyModX = (options->keyCmdAllModKey() == TQt::Key_Meta) ?
KKeyNative::modX(KKey::WIN) :
KKeyNative::modX(KKey::ALT);
@@ -1502,7 +1562,7 @@ void Client::processMousePressEvent( TQMouseEvent* e )
}
// return value matters only when filtering events before decoration gets them
-bool Client::buttonReleaseEvent( Window w, int /*button*/, int state, int x, int y, int x_root, int y_root )
+bool Client::buttonReleaseEvent( Window w, int button, int state, int x, int y, int x_root, int y_root )
{
if( w == decorationId() && !buttonDown)
return false;
@@ -1511,6 +1571,13 @@ bool Client::buttonReleaseEvent( Window w, int /*button*/, int state, int x, int
XAllowEvents(tqt_xdisplay(), SyncPointer, CurrentTime ); //tqt_x_time);
return true;
}
+
+ // Grid tiling
+ if (isMove() && button > 7 && button < 10)
+ {
+ return true;
+ }
+
if( w != frameId() && w != decorationId() && w != moveResizeGrabWindow())
return true;
x = this->x(); // translate from grab window to local coords
diff --git a/twin/geometry.cpp b/twin/geometry.cpp
index 581c07ac1..e28a81f85 100644
--- a/twin/geometry.cpp
+++ b/twin/geometry.cpp
@@ -1360,6 +1360,20 @@ TQSize Client::maxSize() const
return rules()->checkMaxSize( TQSize( xSizeHint.max_width, xSizeHint.max_height ));
}
+TQSize Client::gridTileSize()
+{
+ TQRect max = workspace()->clientArea(MaximizeArea, TQCursor::pos(), workspace()->currentDesktop());
+ return TQSize(max.width() / hGridTiles, max.height() / vGridTiles);
+}
+
+void Client::handleGridTiling(TQRect geom)
+{
+ gridTileGeom = geom;
+ clearbound();
+ positionGeometryTip();
+ drawbound(geom);
+}
+
/*!
Auxiliary function to inform the client about the current window
configuration.
@@ -2273,7 +2287,7 @@ void Client::positionGeometryTip() {
}
// position of the frame, size of the window itself
- TQRect wgeom(isActiveBorderMaximizing() ? activeBorderMaximizeGeometry() : moveResizeGeom);
+ TQRect wgeom(gridTilingMode ? gridTileGeom : (isActiveBorderMaximizing() ? activeBorderMaximizeGeometry() : moveResizeGeom));
wgeom.setWidth(wgeom.width() - (width() - clientSize().width()));
wgeom.setHeight(isShade() ? 0 : wgeom.height() - (height() - clientSize().height()));
@@ -2402,11 +2416,15 @@ void Client::finishMoveResize( bool cancel )
{
leaveMoveResize();
- if (!isActiveBorderMaximizing()) {
- setGeometry(cancel ? initialMoveResizeGeom : moveResizeGeom);
+ if (gridTilingMode)
+ {
+ setGeometry(gridTileGeom);
+ gridTilingMode = false;
+ hGridTiles = 1;
+ vGridTiles = 1;
}
- else
+ else if (isActiveBorderMaximizing())
{
kdDebug() <<"finishing moveresize in active mode, cancel is " << cancel << endl;
activeMaximizing = false;
@@ -2428,6 +2446,10 @@ void Client::finishMoveResize( bool cancel )
activeTiledOrigGeom.moveTopLeft(rect().topLeft());
}
+ else {
+ setGeometry(cancel ? initialMoveResizeGeom : moveResizeGeom);
+ }
+
checkMaximizeGeometry();
// FRAME update();
Notify::raise( isResize() ? Notify::ResizeEnd : Notify::MoveEnd );
@@ -2690,13 +2712,21 @@ void Client::handleMoveResize(int x, int y, int x_root, int y_root) {
if (update)
{
+ if (gridTilingMode)
+ {
+ TQSize gridSize(hGridTiles, vGridTiles);
+ workspace()->checkGridTiling(globalPos, gridSize);
+ }
+
bool active = isActiveBorderMaximizing();
- auto mode = active ? options->tilingMode
- : isResize() ? options->resizeMode : options->moveMode;
+ auto mode = (gridTilingMode || active) ? options->tilingMode :
+ (isResize() ? options->resizeMode : options->moveMode);
+
+ TQRect geom = gridTilingMode ? gridTileGeom : (active ? activeBorderMaximizeGeometry() : moveResizeGeom);
if (rules()->checkMoveResizeMode(mode) == Options::Opaque)
{
- setGeometry(active ? activeBorderMaximizeGeometry() : moveResizeGeom);
+ setGeometry(geom);
positionGeometryTip();
}
else if (rules()->checkMoveResizeMode(mode) == Options::Transparent)
@@ -2708,10 +2738,10 @@ void Client::handleMoveResize(int x, int y, int x_root, int y_root) {
*/
clearbound();
positionGeometryTip();
- drawbound(active ? activeBorderMaximizeGeometry() : moveResizeGeom);
+ drawbound(geom);
}
}
- if (isMove()) {
+ if (isMove() && !gridTilingMode) {
workspace()->checkActiveBorder(globalPos, get_tqt_x_time());
}
}
diff --git a/twin/kcmtwin/twinoptions/windows.cpp b/twin/kcmtwin/twinoptions/windows.cpp
index 9d8e8d617..affc09532 100644
--- a/twin/kcmtwin/twinoptions/windows.cpp
+++ b/twin/kcmtwin/twinoptions/windows.cpp
@@ -85,6 +85,7 @@
#define KWIN_ACTIVE_BORDERS "ActiveBorders"
#define KWIN_ACTIVE_BORDER_DELAY "ActiveBorderDelay"
#define KWIN_ACTIVE_BORDER_DISTANCE "ActiveBorderDistance"
+#define KWIN_GRID_TILING "GridTiling"
// legacy options
#define KWIN_OLD_ACTIVE_BORDERS "ElectricBorders"
@@ -673,6 +674,18 @@ KActiveBorderConfig::KActiveBorderConfig(bool _standAlone, TDEConfig *_config, T
" mouse is close enough, making them easier to activate but also more prone"
" to false activations."));
+ gridTiling = new TQCheckBox(i18n("Enable grid tiling"), active_box);
+ TQWhatsThis::add(gridTiling, i18n("This feature allows you to easily place your windows "
+ "in a grid by using the bracket keys or the history "
+ "navigation buttons on your mouse to manipulate the "
+ "count of grid tiles (the Shift key, while pressed, "
+ "modifies the edited orientation). "
+ "Unlike traditional active borders tiling, to preview "
+ "window placement you only need to press a mouse button "
+ "while dragging the window and the decision is finalized "
+ "once you stop dragging the window. Reducing the grid "
+ "size to 1x1 cancels grid tiling."));
+
active_vbox->addSpacing(10);
active_vbox->addWidget(active_func_label);
active_vbox->addWidget(active_disable);
@@ -685,6 +698,8 @@ KActiveBorderConfig::KActiveBorderConfig(bool _standAlone, TDEConfig *_config, T
active_vbox->addWidget(distance);
active_vbox->addSpacing(15);
active_vbox->addWidget(tilingOpaque);
+ active_vbox->addSpacing(15);
+ active_vbox->addWidget(gridTiling);
connect(active_box, TQ_SIGNAL(clicked(int)), this, TQ_SLOT(updateActiveBorders()));
@@ -725,6 +740,8 @@ void KActiveBorderConfig::load() {
else if (tilingMode == "Transparent")
setTilingMode(TRANSPARENT);
+ setGridTiling(config->readBoolEntry(KWIN_GRID_TILING, false));
+
emit TDECModule::changed(false);
}
@@ -735,6 +752,8 @@ void KActiveBorderConfig::save() {
config->writeEntry(KWIN_ACTIVE_BORDER_DELAY, getActiveBorderDelay());
config->writeEntry(KWIN_ACTIVE_BORDER_DISTANCE, getActiveBorderDistance());
+ config->writeEntry(KWIN_GRID_TILING, getGridTiling());
+
// remove replaced legacy entries
config->deleteEntry(KWIN_OLD_ACTIVE_BORDERS);
config->deleteEntry(KWIN_OLD_ACTIVE_BORDER_DELAY);
@@ -760,6 +779,7 @@ void KActiveBorderConfig::defaults() {
setActiveBorderDelay(150);
setActiveBorderDistance(10);
setTilingMode(TRANSPARENT);
+ setGridTiling(false);
emit TDECModule::changed(true);
}
@@ -798,6 +818,11 @@ int KActiveBorderConfig::getActiveBorderDistance() {
return distance->value();
}
+bool KActiveBorderConfig::getGridTiling()
+{
+ return gridTiling->isChecked();
+}
+
void KActiveBorderConfig::setActiveBorders(int i) {
switch(i)
{
@@ -827,6 +852,11 @@ void KActiveBorderConfig::setActiveBorderDistance(int d) {
distance->setValue(d);
}
+void KActiveBorderConfig::setGridTiling(bool on)
+{
+ gridTiling->setChecked(on);
+}
+
KAdvancedConfig::~KAdvancedConfig ()
{
if (standAlone)
diff --git a/twin/kcmtwin/twinoptions/windows.h b/twin/kcmtwin/twinoptions/windows.h
index 80c9e76d7..90178e822 100644
--- a/twin/kcmtwin/twinoptions/windows.h
+++ b/twin/kcmtwin/twinoptions/windows.h
@@ -212,11 +212,13 @@ class KActiveBorderConfig : public TDECModule
int getActiveBorderDelay();
int getActiveBorderDistance();
int getTilingMode();
+ bool getGridTiling();
void setActiveBorders(int);
void setActiveBorderDelay(int);
void setActiveBorderDistance(int);
void setTilingMode(int);
+ void setGridTiling(bool);
TQButtonGroup *active_box;
TQRadioButton *active_disable;
@@ -229,6 +231,7 @@ class KActiveBorderConfig : public TDECModule
TQWidget *active_desktop_conf;
TQWidget *active_tile_conf;
TQCheckBox *tilingOpaque;
+ TQCheckBox *gridTiling;
TDEConfig *config;
bool standAlone;
diff --git a/twin/options.cpp b/twin/options.cpp
index 46c557b4a..1574cfa36 100644
--- a/twin/options.cpp
+++ b/twin/options.cpp
@@ -54,6 +54,7 @@ unsigned long Options::updateSettings()
moveMode = stringToMoveResizeMode(config->readEntry("MoveMode", "Opaque"));
resizeMode = stringToMoveResizeMode(config->readEntry("ResizeMode", "Opaque"));
tilingMode = stringToMoveResizeMode(config->readEntry("TilingMode", "Opaque"));
+ gridTiling = config->readBoolEntry("GridTiling", false);
show_geometry_tip = config->readBoolEntry("GeometryTip", false);
reset_maximized_window_geometry = config->readBoolEntry("ResetMaximizedWindowGeometry", false);
tabboxOutline = config->readBoolEntry("TabboxOutline", true);
diff --git a/twin/options.h b/twin/options.h
index 41d1340a7..67166f605 100644
--- a/twin/options.h
+++ b/twin/options.h
@@ -154,6 +154,8 @@ class Options : public KDecorationOptions
static MoveResizeMode stringToMoveResizeMode( const TQString& s );
static const char* moveResizeModeToString( MoveResizeMode mode );
+ bool gridTiling;
+
Placement::Policy placement;
bool focusPolicyIsReasonable()
diff --git a/twin/workspace.cpp b/twin/workspace.cpp
index 23661e6a0..26ff7c2b6 100644
--- a/twin/workspace.cpp
+++ b/twin/workspace.cpp
@@ -2519,6 +2519,19 @@ void Workspace::unreserveActiveBorder( ActiveBorder border )
TQTimer::singleShot(0, this, TQ_SLOT(updateActiveBorders()));
}
+void Workspace::checkGridTiling(const TQPoint &pos, TQSize &gridSize)
+{
+ TQSize tileSize = movingClient->gridTileSize();
+ TQRect area = clientArea(MaximizeArea, pos, currentDesktop());
+
+ // Compute target geometry based on current pos
+ int x = 0, y = 0;
+ while (x + tileSize.width() < pos.x() && x < area.width()) x += tileSize.width();
+ while (y + tileSize.height() < pos.y() && y < area.height()) y += tileSize.height();
+
+ movingClient->handleGridTiling(TQRect(x, y, tileSize.width(), tileSize.height()));
+}
+
void Workspace::checkActiveBorder(const TQPoint &pos, Time now)
{
Time treshold_set = options->activeBorderDelay(); // set timeout
diff --git a/twin/workspace.h b/twin/workspace.h
index 28da82ff0..44b03f677 100644
--- a/twin/workspace.h
+++ b/twin/workspace.h
@@ -161,6 +161,8 @@ class Workspace : public TQObject, public KWinInterface, public KDecorationDefin
void unreserveActiveBorder(ActiveBorder border);
void reserveActiveBorderSwitching(bool reserve);
+ void checkGridTiling(const TQPoint &pos, TQSize &gridSize);
+
/**
* Returns the current virtual desktop of this workspace
*/