Skip to content

Commit

Permalink
Merge pull request #24 from gerritdevriese/test
Browse files Browse the repository at this point in the history
Merge the test branch
  • Loading branch information
gerritdevriese authored Jul 22, 2023
2 parents 24c21b4 + b306f3d commit bbaf4e2
Show file tree
Hide file tree
Showing 10 changed files with 770 additions and 1,040 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1 @@
.project/
contents/ui/config_ui.py
Binary file modified KZones.kwinscript
Binary file not shown.
69 changes: 47 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,39 @@
# KZones

KDE KWin Script for snapping windows into zones. Handy when using a (super) ultrawide monitor.
An alternative to PowerToys FancyZones.

## Features

### Drag & Drop

Dragging windows to a zone
![](./media/dragdrop.gif)

### Multiple Layouts

Create multiple layouts and cycle between them
![](./media/layouts.gif)

### Shortcuts

Snap windows using shortcuts (full list below)
![](./media/shortcuts.gif)

### Zone Selector

Show a zone selector when dragging a window to the top of the screen
![](./media/selector.jpg)

## Installation

Install via KDE Store or clone this repo and run the `./build` script.

### KDE Store

Under System Settings / KWin Scripts / Get New Scripts, search for KZones and install it.
https://store.kde.org/p/1909220

### Build it yourself
Make sure you have "zip" installed on your system before building.
```
Expand All @@ -26,8 +42,21 @@ cd kzones && ./build
```

## Setup

### General

#### Show zones when I start moving a window

While moving a window you will have the option to snap it to a zone. Either by dragging it to it's indicator or the full zone.

#### Show zone selector when I drag a windo to the top of the screen

When enabled, a zone selector will appear when you drag a window to the top of the screen. Which allows you to snap the window to a zone. The selector displays all zones from all layouts.

### Layouts

You can define layouts by putting them in the **Layouts** tab in the script settings, here are some examples to get you started:

#### Examples
<details open>
<summary>Single layout</summary>
Expand Down Expand Up @@ -145,6 +174,7 @@ You can define layouts by putting them in the **Layouts** tab in the script sett
</details>

#### Explanation

The main array can contain as many layouts as you want:

Each **layout** object needs the following keys:
Expand Down Expand Up @@ -183,46 +213,41 @@ This example will move the indicator 100 pixels to the right and 50 pixels up.

#### Determine zone

###### Target
The Target can be set to **Indicator** or **Zone**. **Indicator** is the default and will snap the window to the zone if the chosen method is inside the zone indicator. Choose **Zone** if you want to always snap the window to the zone it's dropped in. (you can cancel the snap with the "Toggle OSD" shortcut)

###### Method
By default the script will use the **Titlebar** method to determine which zone a window should snap to. This means that the window will snap when the target contains the titlebar of the window. You can change this behaviour by setting the method to **Cursor** or **Window**. (mind the caveats below)

###### Size
Change the size of the chosen method, for example when using the **Titlebar** method you can decrease the size of the "handle" to make it easier to snap windows to the correct zone. You can temporarily enable debug mode to see the exact size of the "handle".

#### Filtering

You can block certain windows from snapping by adding their class name to the exclude list. Or you can only allow certain windows to snap by adding their class name to the include list. You can find the class name of a window by running `xprop` in a terminal and clicking on the window. The class name will be in the `WM_CLASS` property.

#### Polling rate

The polling rate is the amount of time between each zone check when dragging a window. The default is 100ms, a faster polling rate is more accurate but will use more CPU. You can change this to your liking.

#### Inverted mode

When enabled, moving windows will not trigger the osd. Instead you'll have to use the "Toggle OSD" shortcut to show the osd.

## Shortcuts

List of all available shortcuts:
| Shortcut | Default Binding |
|-----------------------------------------------|---------------------------|
| Move active window to zone | `Ctrl+Alt+[0-9]` |
| Move active window to previous zone | `Ctrl+Alt+Left` |
| Move active window to next zone | `Ctrl+Alt+Right` |
| Switch to previous window in current zone | `Ctrl+Alt+Down` |
| Switch to next window in current zone | `Ctrl+Alt+Up` |
| Cycle between layouts | `Ctrl+Alt+D` |
| Toggle OSD | `Ctrl+Alt+C` |

| Shortcut | Default Binding |
| ----------------------------------------- | ---------------- |
| Move active window to zone | `Ctrl+Alt+[0-9]` |
| Move active window to previous zone | `Ctrl+Alt+Left` |
| Move active window to next zone | `Ctrl+Alt+Right` |
| Switch to previous window in current zone | `Ctrl+Alt+Down` |
| Switch to next window in current zone | `Ctrl+Alt+Up` |
| Cycle between layouts | `Ctrl+Alt+D` |
| Toggle OSD | `Ctrl+Alt+C` |

*To change the default bindings, go to System Settings / Shortcuts and search for KZones*

## Troubleshooting

### The script doesn't work
- Check if your KDE version is up to date.

- Check if your KDE version is at 5.27 or higher.
- Make sure there is at least one layout defined in the script settings and that it contains at least one zone.

### My settings are not saved
- After changing settings, you need to reload the script by disabling, saving and enabling it again. (or by restarting KWin)

## Caveats
When selecting **Cursor** as the "determine zone method" you'll need to have xdotool installed, sadly this doesn't work on Wayland. So if you're using Wayland you'll need to use the **Titlebar** or **Window** method instead.
- After changing settings, you need to reload the script by disabling, saving and enabling it again. (or by restarting KWin)
78 changes: 43 additions & 35 deletions contents/config/main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,57 +11,69 @@
</entry>

<entry name="layoutsJson" type="String">
<default>[
<default>
[
{
&quot;name&quot;: &quot;Layout 1&quot;,
&quot;name&quot;: &quot;Priority Grid&quot;,
&quot;padding&quot;: 0,
&quot;zones&quot;: [
{
&quot;name&quot;: &quot;1&quot;,
&quot;x&quot;: 0,
&quot;y&quot;: 0,
&quot;height&quot;: 100,
&quot;width&quot;: 25
},
{
&quot;name&quot;: &quot;2&quot;,
&quot;x&quot;: 25,
&quot;y&quot;: 0,
&quot;height&quot;: 100,
&quot;width&quot;: 50
},
{
&quot;name&quot;: &quot;3&quot;,
&quot;x&quot;: 75,
&quot;y&quot;: 0,
&quot;height&quot;: 100,
&quot;width&quot;: 25
}
]
},
{
&quot;name&quot;: &quot;Quadrant Grid&quot;,
&quot;zones&quot;: [
{
&quot;x&quot;: 0,
&quot;y&quot;: 0,
&quot;height&quot;: 50,
&quot;width&quot;: 50
},
{
&quot;x&quot;: 0,
&quot;y&quot;: 50,
&quot;height&quot;: 50,
&quot;width&quot;: 50
},
{
&quot;x&quot;: 50,
&quot;y&quot;: 50,
&quot;height&quot;: 50,
&quot;width&quot;: 50
},
{
&quot;x&quot;: 50,
&quot;y&quot;: 0,
&quot;height&quot;: 50,
&quot;width&quot;: 50
}
]
}
]</default>
]
</default>
</entry>

<entry name="pollingRate" type="Int">
<default>100</default>
</entry>

<entry name="targetMethod" type="String">
<default>0</default>
</entry>

<entry name="handleUnitPercent" type="Bool">
<default>true</default>
</entry>

<entry name="handleUnitPixels" type="Bool">
<default>false</default>
</entry>

<entry name="handleSize" type="Int">
<default>100</default>
</entry>

<entry name="enableDebugMode" type="Bool">
<default>false</default>
</entry>
Expand All @@ -74,28 +86,24 @@
<default></default>
</entry>

<entry name="zoneTarget" type="Int">
<default></default>
</entry>

<entry name="fadeDuration" type="Int">
<default></default>
<entry name="invertedMode" type="Bool">
<default>false</default>
</entry>

<entry name="osdTimeout" type="Int">
<default></default>
<entry name="indicatorIsTarget" type="Bool">
<default>true</default>
</entry>

<entry name="alwaysShowLayoutName" type="Bool">
<entry name="zoneIsTarget" type="Bool">
<default>false</default>
</entry>

<entry name="alternateIndicatorStyle" type="Bool">
<default>false</default>
<entry name="enableZoneSelector" type="Bool">
<default>true</default>
</entry>

<entry name="invertedMode" type="Bool">
<default>false</default>
<entry name="enableZoneIndicators" type="Bool">
<default>true</default>
</entry>

</group>
Expand Down
49 changes: 49 additions & 0 deletions contents/ui/components/Indicator.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import QtGraphicalEffects 1.0
import QtQuick 2.15
import org.kde.kirigami 2.15 as Kirigami

Rectangle {
id: indicator
property int activeZone: 0
property bool hovering: false
property var zones: []
width: parent.width
height: parent.height
color: "transparent"
opacity: 1

Repeater {
id: indicators
model: zones

Rectangle {
id: zone
x: ((modelData.x / 100) * (indicator.width))
y: ((modelData.y / 100) * (indicator.height))
width: ((modelData.width / 100) * (indicator.width))
height: ((modelData.height / 100) * (indicator.height))
color: "transparent"

Rectangle {
property int padding: 2
anchors.fill: parent
anchors.margins: padding
Kirigami.Theme.colorSet: Kirigami.Theme.View
Kirigami.Theme.inherit: false
color: (activeZone == index) ? Kirigami.Theme.hoverColor : Kirigami.ColorUtils.tintWithAlpha( Kirigami.Theme.backgroundColor, Qt.rgba(1,1,1), 0.1)
border.color: Kirigami.ColorUtils.tintWithAlpha(color, Kirigami.Theme.textColor, 0.2)
border.width: 1
radius: 5

Behavior on color {
ColorAnimation {
duration: 150
}
}
}

}

}

}
18 changes: 18 additions & 0 deletions contents/ui/components/Shadow.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import QtQuick 2.15
import QtGraphicalEffects 1.0

DropShadow {
property Item target : null
anchors.fill: target
visible: target.visible
opacity: target.opacity
scale: target.scale
cached: true
horizontalOffset: 0
verticalOffset: 0
radius: 32
samples: (radius*2)+1
color: '#69000000'
smooth: true
source: target
}
Loading

0 comments on commit bbaf4e2

Please sign in to comment.