release v0.0.1
This commit is contained in:
1
.idea/.name
generated
Normal file
1
.idea/.name
generated
Normal file
@@ -0,0 +1 @@
|
|||||||
|
pi3-smart-workspace
|
||||||
2
.idea/modules.xml
generated
2
.idea/modules.xml
generated
@@ -2,7 +2,7 @@
|
|||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="ProjectModuleManager">
|
<component name="ProjectModuleManager">
|
||||||
<modules>
|
<modules>
|
||||||
<module fileurl="file://$PROJECT_DIR$/.idea/PyOutputHandler.iml" filepath="$PROJECT_DIR$/.idea/PyOutputHandler.iml" />
|
<module fileurl="file://$PROJECT_DIR$/../pi3-smart-workspace/.idea/pi3-smart-workspace.iml" filepath="$PROJECT_DIR$/../pi3-smart-workspace/.idea/pi3-smart-workspace.iml" />
|
||||||
</modules>
|
</modules>
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
64
README.rst
Normal file
64
README.rst
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
About
|
||||||
|
-----
|
||||||
|
|
||||||
|
Simple program that looks through the i3 config and finds the bound workspaces for each output, and then opening that workspace on the output, that the mouse is currently on.
|
||||||
|
|
||||||
|
Allowing for a more seameless interaction with how workspaces are openend.
|
||||||
|
|
||||||
|
Usage
|
||||||
|
-----
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
usage: pi3-smar-switch [-h] [-f] [-p | -m | -s] WORKSPACE_NAME
|
||||||
|
|
||||||
|
Moves selected i3 workspace to the current output (by default determined by
|
||||||
|
cursor location) and focuses it.
|
||||||
|
|
||||||
|
positional arguments:
|
||||||
|
workspace name of the i3 workspace
|
||||||
|
|
||||||
|
optional arguments:
|
||||||
|
-h, --help show this help message and exit
|
||||||
|
-f, --focus use focused window instead of cursor position to determine the
|
||||||
|
current output
|
||||||
|
-p, --push moves replaced workspace to the second output (works only if
|
||||||
|
there are two outputs, ignored otherwise)
|
||||||
|
-m, --master same as 'push' but will only move from primary output to the
|
||||||
|
secondary
|
||||||
|
-s, --swap (NOT IMPLEMENTED YET) behaves like xmonad, swaps workspaces if
|
||||||
|
they are on a different output
|
||||||
|
|
||||||
|
Installation
|
||||||
|
------------
|
||||||
|
|
||||||
|
Install using `pipsi`_ (recommended) or pip:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
pipsi install pi3-switch
|
||||||
|
|
||||||
|
Add keybindings to ~/.config/i3/config and reload i3 (remember to modify flags to your liking):
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
bindsym $mod+1 exec pi3-switch -p 1
|
||||||
|
bindsym $mod+2 exec pi3-switch -p 2
|
||||||
|
bindsym $mod+3 exec pi3-switch -p 3
|
||||||
|
bindsym $mod+4 exec pi3-switch -p 4
|
||||||
|
bindsym $mod+5 exec pi3-switch -p 5
|
||||||
|
bindsym $mod+6 exec pi3-switch -p 6
|
||||||
|
bindsym $mod+7 exec pi3-switch -p 7
|
||||||
|
bindsym $mod+8 exec pi3-switch -p 8
|
||||||
|
bindsym $mod+9 exec pi3-switch -p 9
|
||||||
|
bindsym $mod+0 exec pi3-switch -p 10
|
||||||
|
|
||||||
|
Credits
|
||||||
|
-------
|
||||||
|
|
||||||
|
Thanks to Travis Finkenauer for an inspiration (`i3-wk-switch`_) and
|
||||||
|
Tony Crisci for an easy-to-use i3 python library (`i3ipc-python`_).
|
||||||
|
|
||||||
|
.. _pipsi: https://github.com/mitsuhiko/pipsi
|
||||||
|
.. _i3-wk-switch: https://github.com/tmfink/i3-wk-switch
|
||||||
|
.. _i3ipc-python: https://github.com/acrisci/i3ipc-python
|
||||||
0
pi3/__init__.py
Normal file
0
pi3/__init__.py
Normal file
@@ -1,15 +1,9 @@
|
|||||||
from i3ipc import connection, Connection
|
from i3ipc import Connection
|
||||||
import logging
|
|
||||||
import sys
|
import sys
|
||||||
from pprint import pprint
|
from pprint import pprint
|
||||||
import pynput
|
import pynput
|
||||||
import re
|
import re
|
||||||
import asyncio
|
import argparse
|
||||||
|
|
||||||
"""import argparse
|
|
||||||
"""
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
class WorkSpacer:
|
class WorkSpacer:
|
||||||
@@ -17,32 +11,48 @@ class WorkSpacer:
|
|||||||
def __init__(self, args):
|
def __init__(self, args):
|
||||||
self.i3 = None
|
self.i3 = None
|
||||||
self.args = args
|
self.args = args
|
||||||
self.workspaces_on_outputs = None
|
self.workspaces_on_outputs = {}
|
||||||
self.workspaces = None
|
self.workspaces = None
|
||||||
self.outputs = None
|
self.outputs = None
|
||||||
|
self.config = None
|
||||||
self.mouse = pynput.mouse.Controller()
|
self.mouse = pynput.mouse.Controller()
|
||||||
|
|
||||||
self.mouse_position = None
|
self.mouse_position = None
|
||||||
self.current_output_name = None
|
self.current_output_name = None
|
||||||
|
|
||||||
def _connect(self):
|
def _connect(self):
|
||||||
try:
|
try:
|
||||||
self.i3 = Connection()
|
self.i3 = Connection()
|
||||||
re.compile(r'')
|
self.config = self.i3.get_config().__dict__['config']
|
||||||
self.workspaces_on_outputs = [ws for ws in self.i3.get_config().__dict__['config'].split('\n') if ws]
|
config_outputs = {}
|
||||||
|
for matchNo, match in enumerate(
|
||||||
|
re.finditer(r'set (\$[a-zA-Z]+) ((HDMI|DP|VGA)-\d)', self.config, re.MULTILINE), start=1
|
||||||
|
):
|
||||||
|
config_outputs[match.group(1)] = match.group(2)
|
||||||
|
pprint(config_outputs)
|
||||||
|
config_workspace_names = {}
|
||||||
|
for matchNum, match in enumerate(
|
||||||
|
re.finditer(r'set (\$.*) (\d.*)', self.config, re.MULTILINE)
|
||||||
|
):
|
||||||
|
config_workspace_names[match.group(1)] = match.group(2)
|
||||||
|
pprint(config_workspace_names)
|
||||||
|
for matchNum, match in enumerate(
|
||||||
|
re.finditer(r'workspace (\$.*) output (\$.*)', self.config, re.MULTILINE)
|
||||||
|
):
|
||||||
|
if not self.workspaces_on_outputs.keys().__contains__(config_outputs[match.group(2)]):
|
||||||
|
self.workspaces_on_outputs[config_outputs[match.group(2)]] = []
|
||||||
|
self.workspaces_on_outputs[config_outputs[match.group(2)]].append(config_workspace_names[match.group(1)])
|
||||||
|
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
logger.error(f"Could not load i3: {exc}", exc_info=exc)
|
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
self.workspaces = [workspaces for workspaces in self.i3.get_workspaces()]
|
self.workspaces = [workspaces for workspaces in self.i3.get_workspaces()]
|
||||||
outputs = self.i3.get_outputs()
|
outputs = self.i3.get_outputs()
|
||||||
#pprint(outputs[1].__dict__)
|
|
||||||
self.outputs = [output for output in outputs if output.__dict__["active"] is True]
|
self.outputs = [output for output in outputs if output.__dict__["active"] is True]
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
self._connect()
|
self._connect()
|
||||||
self.mouse_position = self.mouse.position
|
self.mouse_position = self.mouse.position
|
||||||
self.current_output_name = self._get_workspace_from_courser_position()
|
self.current_output_name = self._get_workspace_from_courser_position()
|
||||||
|
self.i3.command(f'workspace {self.workspaces_on_outputs[self.current_output_name][self.args]}')
|
||||||
|
|
||||||
def _get_workspace_from_courser_position(self):
|
def _get_workspace_from_courser_position(self):
|
||||||
for output in self.outputs:
|
for output in self.outputs:
|
||||||
@@ -68,12 +78,18 @@ class WorkSpacer:
|
|||||||
return [workspace for workspace in self.workspaces if workspace.__dict__['output'] == output]
|
return [workspace for workspace in self.workspaces if workspace.__dict__['output'] == output]
|
||||||
|
|
||||||
|
|
||||||
def tst():
|
def main():
|
||||||
ws = WorkSpacer('')
|
parser = argparse.ArgumentParser(
|
||||||
|
description="Dynamic changes the workspace, based on what output your cursoer is on."
|
||||||
|
)
|
||||||
|
parser.add_argument("-i", "--index", type=int,
|
||||||
|
help="the number index of the workspace that should be openend. 1 = workspace 1 etc.")
|
||||||
|
ws = WorkSpacer(parser.parse_args())
|
||||||
ws.run()
|
ws.run()
|
||||||
|
|
||||||
|
|
||||||
# Press the green button in the gutter to run the script.
|
# Press the green button in the gutter to run the script.
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
tst()
|
main()
|
||||||
|
|
||||||
|
|
||||||
5
requirements.txt
Normal file
5
requirements.txt
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
evdev==1.3.0
|
||||||
|
i3ipc==2.2.1
|
||||||
|
pynput==1.7.1
|
||||||
|
python-xlib==0.27
|
||||||
|
six==1.15.0
|
||||||
32
setup.py
Normal file
32
setup.py
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
from setuptools import setup
|
||||||
|
|
||||||
|
with open('README.rst', 'r') as fh:
|
||||||
|
long_description = fh.read()
|
||||||
|
with open('requirements.txt', 'r') as file:
|
||||||
|
required = []
|
||||||
|
for x in file.readline():
|
||||||
|
required.append(x)
|
||||||
|
|
||||||
|
|
||||||
|
setup(
|
||||||
|
name="pi3-smart-workspace",
|
||||||
|
description="A smart switcher for multiple workspaces.",
|
||||||
|
long_description=long_description,
|
||||||
|
version="0.0.1",
|
||||||
|
license="Apache License",
|
||||||
|
author="Asger Geel Weirsøe",
|
||||||
|
author_email="asger@weirsoe.dk",
|
||||||
|
url="https://github.com/GeneralDenmark/PyOutputHandler",
|
||||||
|
install_requires=required,
|
||||||
|
packages=["pi3"],
|
||||||
|
zip_safe=True,
|
||||||
|
entry_points={"console_scripts": ["pi3-smart-workspace = pi3.smart-workspace:main"]},
|
||||||
|
scripts=["pi3/smart-workspace.py"],
|
||||||
|
classifiers=[
|
||||||
|
"Development Status :: 2 - Pre-Alpha",
|
||||||
|
"License :: OSI Approved :: Apache Software License",
|
||||||
|
"Operating System :: POSIX :: Linux",
|
||||||
|
"Programming Language :: Python :: 3",
|
||||||
|
"Topic :: Desktop Environment :: Window Managers",
|
||||||
|
],
|
||||||
|
)
|
||||||
Reference in New Issue
Block a user