diff --git a/README.md b/README.md index 61c785c..84f4579 100644 --- a/README.md +++ b/README.md @@ -122,40 +122,41 @@ general { The plugin adds the following dispatchers: -| Dispatcher | Description | -|-----------------------------|----------------------------------------------------------------------------------------------------------------------------------| -| `scroller:movefocus` | An optional replacement for `movefocus`, takes a direction as argument. | -| `scroller:movewindow` | An optional replacement for `movewindow`, takes a direction as argument. | -| `scroller:setmode` | Set mode: `r/row` (default), `c/col/column`. Sets the working mode. Affects most dispatchers and new window creation. | -| `scroller:cyclesize` | Resize the focused column width (*row* mode), or the active window height (*column* mode). | -| `scroller:cyclewidth` | Resize the focused column width. | -| `scroller:cycleheight` | Resize the active window height. | -| `scroller:setsize` | Set the focused column width (*row* mode), or the active window height (*column* mode) to one of the standard sizes. | -| `scroller:setwidth` | Set the focused column width to one of `column_widths`. Takes an int value (0-based idx of the desired size in `column_widths`) | -| `scroller:setheight` | Set the active window height to one of `window_heights`. Parameter similar to `setwidth` | -| `scroller:alignwindow` | Align window on the screen, `l/left`, `c/center`, `r/right` (*row* mode), `c/center`, `u/up`, `d/down` (*col* mode), `m/middle` | -| `scroller:admitwindow` | Push the current window below the active one of the column to its left. | -| `scroller:expelwindow` | Pop the current window out of its column and place it on a new column to the right. | -| `scroller:fitsize` | Resize columns (*row* mode) or windows (*col* mode) so they fit on the screen: `active`, `visible`, `all`, `toend`, `tobeg` | -| `scroller:toggleoverview` | Toggle an overview of the workspace where all the windows are temporarily scaled to fit the monitor | -| `scroller:marksadd` | Add a named mark. Argument is the name of the mark | -| `scroller:marksdelete` | Delete a named mark. Argument is the name of the mark | -| `scroller:marksvisit` | Visit a named mark. Argument is the name of the mark | -| `scroller:marksreset` | Delete all marks | -| `scroller:pin` | Toggle pin a column to its current position. The rest will adapt when changing focus etc. | -| `scroller:selectiontoggle` | Toggle on/off the selection status of a window | -| `scroller:selectionreset` | Resets selection (deselects all windows) | -| `scroller:selectionmove` | Moves the selected windows/columns to the current workspace and location, takes a direction as argument (keeps sizes etc.) | -| `scroller:trailnew` | Creates a new trail | -| `scroller:traildelete` | Deletes the active trail | -| `scroller:trailclear` | Clears all the trailmarks of the current trail | -| `scroller:trailnext` | Moves to next trail | -| `scroller:trailprevious` | Moves to previous trail | -| `scroller:trailtoselection` | Creates a selection from all the windows in the current trail | -| `scroller:trailmarktoggle` | Toggles a trailmark for the current window in the active trail | -| `scroller:trailmarknext` | Moves to next trailmark in the current trail | -| `scroller:trailmarkprevious`| Moves to previous trailmark in the current trail | -| `scroller:jump` | Shows every window on the active monitors for a shortcut-based, quick focus mode | +| Dispatcher | Description | +|-------------------------------|----------------------------------------------------------------------------------------------------------------------------------| +| `scroller:movefocus` | An optional replacement for `movefocus`, takes a direction as argument. | +| `scroller:movewindow` | An optional replacement for `movewindow`, takes a direction as argument. | +| `scroller:setmode` | Set mode: `r/row` (default), `c/col/column`. Sets the working mode. Affects most dispatchers and new window creation. | +| `scroller:cyclesize` | Resize the focused column width (*row* mode), or the active window height (*column* mode). | +| `scroller:cyclewidth` | Resize the focused column width. | +| `scroller:cycleheight` | Resize the active window height. | +| `scroller:setsize` | Set the focused column width (*row* mode), or the active window height (*column* mode) to one of the standard sizes. | +| `scroller:setwidth` | Set the focused column width to one of `column_widths`. Takes an int value (0-based idx of the desired size in `column_widths`) | +| `scroller:setheight` | Set the active window height to one of `window_heights`. Parameter similar to `setwidth` | +| `scroller:alignwindow` | Align window on the screen, `l/left`, `c/center`, `r/right` (*row* mode), `c/center`, `u/up`, `d/down` (*col* mode), `m/middle` | +| `scroller:admitwindow` | Push the current window below the active one of the column to its left. | +| `scroller:expelwindow` | Pop the current window out of its column and place it on a new column to the right. | +| `scroller:fitsize` | Resize columns (*row* mode) or windows (*col* mode) so they fit on the screen: `active`, `visible`, `all`, `toend`, `tobeg` | +| `scroller:toggleoverview` | Toggle an overview of the workspace where all the windows are temporarily scaled to fit the monitor | +| `scroller:marksadd` | Add a named mark. Argument is the name of the mark | +| `scroller:marksdelete` | Delete a named mark. Argument is the name of the mark | +| `scroller:marksvisit` | Visit a named mark. Argument is the name of the mark | +| `scroller:marksreset` | Delete all marks | +| `scroller:pin` | Toggle pin a column to its current position. The rest will adapt when changing focus etc. | +| `scroller:selectiontoggle` | Toggle on/off the selection status of a window | +| `scroller:selectionworkspace` | Select every window in the current workspace | +| `scroller:selectionreset` | Resets selection (deselects all windows) | +| `scroller:selectionmove` | Moves the selected windows/columns to the current workspace and location, takes a direction as argument (keeps sizes etc.) | +| `scroller:trailnew` | Creates a new trail | +| `scroller:traildelete` | Deletes the active trail | +| `scroller:trailclear` | Clears all the trailmarks of the current trail | +| `scroller:trailnext` | Moves to next trail | +| `scroller:trailprevious` | Moves to previous trail | +| `scroller:trailtoselection` | Creates a selection from all the windows in the current trail | +| `scroller:trailmarktoggle` | Toggles a trailmark for the current window in the active trail | +| `scroller:trailmarknext` | Moves to next trailmark in the current trail | +| `scroller:trailmarkprevious` | Moves to previous trailmark in the current trail | +| `scroller:jump` | Shows every window on the active monitors for a shortcut-based, quick focus mode | ## Modes @@ -382,6 +383,12 @@ Once you have made a selection, you can move those windows to a different workspace or location in the same workspace using `scroller:selectionmove`. The selection order and column/window configuration will be maintained. +`scroller:selectionworkspace` will add every window of the current workspace +to the selection. You can use this when you want to move one workspace to a +different one, but keeping windows positions and sizes. Use +`scroller:selectionworkspace`, and then `scroller:selectionmove` where you +want the windows to appear. + `scroller:selectionmove` accepts a direction as parameter. Valid directions are: @@ -1134,6 +1141,7 @@ bind = $mainMod, P, scroller:pin, bind = $mainMod, Insert, scroller:selectiontoggle, bind = $mainMod CTRL, Insert, scroller:selectionreset, bind = $mainMod SHIFT, Insert, scroller:selectionmove, right +bind = $mainMod CTRL SHIFT, Insert, scroller:selectionworkspace, # Trails and Trailmarks bind = $mainMod SHIFT, semicolon, submap, trail diff --git a/hypr.conf b/hypr.conf index 6976023..e46b7c5 100644 --- a/hypr.conf +++ b/hypr.conf @@ -233,6 +233,7 @@ bindm = $mainMod, mouse:273, resizewindow bind = $mainMod, Insert, scroller:selectiontoggle, bind = $mainMod CTRL, Insert, scroller:selectionreset, bind = $mainMod SHIFT, Insert, scroller:selectionmove, right +bind = $mainMod CTRL SHIFT, Insert, scroller:selectionworkspace, bind = $mainMod SHIFT, semicolon, submap, trail submap = trail diff --git a/src/column.cpp b/src/column.cpp index 6d8ba79..229bdf9 100644 --- a/src/column.cpp +++ b/src/column.cpp @@ -554,6 +554,13 @@ void Column::selection_set(PHLWINDOWREF window) } } +void Column::selection_all() +{ + for (auto w = windows.first(); w != nullptr; w = w->next()) { + w->data()->selection_set(); + } +} + void Column::selection_reset() { for (auto win = windows.first(); win != nullptr; win = win->next()) { diff --git a/src/column.h b/src/column.h index a453964..5325d72 100644 --- a/src/column.h +++ b/src/column.h @@ -114,6 +114,7 @@ class Column { void resize_active_window(const Vector2D &gap_x, double gap, const Vector2D &delta); void selection_toggle(); void selection_set(PHLWINDOWREF window); + void selection_all(); void selection_reset(); Column *selection_get(const Row *row); bool selection_exists() const; diff --git a/src/dispatchers.cpp b/src/dispatchers.cpp index 5a868f0..74d2ece 100644 --- a/src/dispatchers.cpp +++ b/src/dispatchers.cpp @@ -280,6 +280,13 @@ namespace dispatchers { g_ScrollerLayout->selection_reset(); } + void dispatch_selectionworkspace(std::string) { + auto workspace = workspace_for_action(); + if (workspace == -1) + return; + + g_ScrollerLayout->selection_workspace(workspace); + } void dispatch_selectionmove(std::string arg) { auto workspace = workspace_for_action(); if (workspace == -1) @@ -373,6 +380,7 @@ namespace dispatchers { HyprlandAPI::addDispatcher(PHANDLE, "scroller:pin", dispatch_pin); HyprlandAPI::addDispatcher(PHANDLE, "scroller:selectiontoggle", dispatch_selectiontoggle); HyprlandAPI::addDispatcher(PHANDLE, "scroller:selectionreset", dispatch_selectionreset); + HyprlandAPI::addDispatcher(PHANDLE, "scroller:selectionworkspace", dispatch_selectionworkspace); HyprlandAPI::addDispatcher(PHANDLE, "scroller:selectionmove", dispatch_selectionmove); HyprlandAPI::addDispatcher(PHANDLE, "scroller:trailnew", dispatch_trailnew); HyprlandAPI::addDispatcher(PHANDLE, "scroller:trailnext", dispatch_trailnext); diff --git a/src/row.cpp b/src/row.cpp index 25b5935..bec1a83 100644 --- a/src/row.cpp +++ b/src/row.cpp @@ -362,6 +362,13 @@ void Row::selection_set(PHLWINDOWREF window) } } +void Row::selection_all() +{ + for (auto col = columns.first(); col != nullptr; col = col->next()) { + col->data()->selection_all(); + } +} + void Row::selection_reset() { for (auto col = columns.first(); col != nullptr; col = col->next()) { diff --git a/src/row.h b/src/row.h index 5ade722..c5ef22b 100644 --- a/src/row.h +++ b/src/row.h @@ -50,6 +50,7 @@ class Row { void pin(); void selection_toggle(); void selection_set(PHLWINDOWREF window); + void selection_all(); void selection_reset(); void selection_move(const List &columns, Direction direction); void selection_get(const Row *row, List &selection); diff --git a/src/scroller.cpp b/src/scroller.cpp index 9a6e2ff..3f3a643 100644 --- a/src/scroller.cpp +++ b/src/scroller.cpp @@ -1060,6 +1060,18 @@ void ScrollerLayout::selection_reset() { } } +void ScrollerLayout::selection_workspace(WORKSPACEID workspace) { + auto s = getRowForWorkspace(workspace); + if (s == nullptr) { + return; + } + + s->selection_all(); + + // Re-render that monitor to render decorations + g_pHyprRenderer->damageMonitor(g_pCompositor->m_pLastMonitor.lock()); +} + // Move all selected columns/windows to workspace, and locate them in direction wrt // the active column. Valid directiona are left, right, beginning, end, other // defaults to right. diff --git a/src/scroller.h b/src/scroller.h index 66bb1c6..34597b3 100644 --- a/src/scroller.h +++ b/src/scroller.h @@ -66,6 +66,7 @@ class ScrollerLayout : public IHyprLayout { void selection_toggle(WORKSPACEID workspace); void selection_set(PHLWINDOWREF window); void selection_reset(); + void selection_workspace(WORKSPACEID workspace); void selection_move(WORKSPACEID workspace, Direction direction = Direction::End); void trail_new();