release v0.0.1

This commit is contained in:
Asger Geel Weirsøe
2020-09-05 10:15:39 +02:00
parent 709e60cc80
commit 62038963df
9 changed files with 144 additions and 20 deletions

1
.idea/.name generated Normal file
View File

@@ -0,0 +1 @@
pi3-smart-workspace

2
.idea/modules.xml generated
View File

@@ -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
View 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
View 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
View File

View 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
View 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
View 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",
],
)