13 Commits

Author SHA1 Message Date
Asger Geel Weirsøe
f4ec4385b2 v0.1.2 2020-09-05 12:36:16 +02:00
Asger Geel Weirsøe
184832d805 updates readme 2020-09-05 12:29:38 +02:00
Asger Geel Weirsøe
d6015c5576 adds build script for deploying to pypi.org and smaller changes to the setup script 2020-09-05 12:25:33 +02:00
Asger Geel Weirsøe
4646f1c230 final fixes for v0.1.1 2020-09-05 11:59:07 +02:00
Asger Geel Weirsøe
34bfc4dea3 V0.1.0 2020-09-05 11:28:45 +02:00
Asger Geel Weirsøe
71f066f775 Updates ignore to ignore eggs generated by pip 2020-09-05 11:23:35 +02:00
Asger Geel Weirsøe
a056463fec cleanup 2020-09-05 11:21:18 +02:00
Asger Geel Weirsøe
1bd2a3bb7b Updates the git ignore file 2020-09-05 11:20:29 +02:00
Asger Geel Weirsøe
85ec3cd1d2 Demos the move of active container to workspace based on mouse cursor 2020-09-05 11:18:25 +02:00
Asger Geel Weirsøe
6dc86952db Merge branch 'master' of github.com:GeneralDenmark/PyOutputHandler into master 2020-09-05 10:59:53 +02:00
Asger Geel Weirsøe
8715e681ab fixes problems with installing the pacage with pip 2020-09-05 10:59:46 +02:00
Asger Geel Weirsøe
39f384e64b Update README.rst 2020-09-05 10:27:35 +02:00
Asger Geel Weirsøe
f848e2f746 Fixes a problem with args parse and updates the readme 2020-09-05 10:26:59 +02:00
13 changed files with 185 additions and 108 deletions

6
.gitignore vendored Normal file
View File

@@ -0,0 +1,6 @@
**__pycache__/
.idea
**.egg-info/
build/
dist/
.pypirc

8
.idea/.gitignore generated vendored
View File

@@ -1,8 +0,0 @@
# Default ignored files
/shelf/
/workspace.xml
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
# Editor-based HTTP Client requests
/httpRequests/

1
.idea/.name generated
View File

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

View File

@@ -1,5 +0,0 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
</state>
</component>

View File

@@ -1,6 +0,0 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>

4
.idea/misc.xml generated
View File

@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.8 (PyOutputHandler)" project-jdk-type="Python SDK" />
</project>

8
.idea/modules.xml generated
View File

@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<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>
</component>
</project>

View File

@@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="jdk" jdkName="Python 3.8 (PyOutputHandler)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="TestRunnerService">
<option name="PROJECT_TEST_RUNNER" value="Twisted Trial" />
</component>
</module>

6
.idea/vcs.xml generated
View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View File

@@ -10,55 +10,131 @@ Usage
:: ::
usage: pi3-smar-switch [-h] [-f] [-p | -m | -s] WORKSPACE_NAME usage: pi3-smart-switch [-h] -i num
Openens the [i] number of workspace assigned in the config, on the output the cursor is currently on.
Moves selected i3 workspace to the current output (by default determined by
cursor location) and focuses it.
positional arguments: requred arguments:
workspace name of the i3 workspace -i, --index the number index of the workspace that should be openend. 1 = first workspace in config etc.
Current limitations
--------------------
The way this script is set up, it is sending commands in strings. and thus we cannot keep track of each workspace other than by its name. This is a limmitiaion as there is no way for us to know if the workspace "1" is reffering to the workspace 1 assigned to output DS-1 or output HDMI-2..
So in order to differentiate between these, you need to name your workspaces new names for each output. See example configuration under #Installation.
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 Installation
------------ ------------
Install using `pipsi`_ (recommended) or pip: Install using pip (recommended):
:: ::
pipsi install pi3-switch pip install pi3-smart-workspace
Add keybindings to ~/.config/i3/config and reload i3 (remember to modify flags to your liking): Example config to be inserted into your i3 config.
:: ::
bindsym $mod+1 exec pi3-switch -p 1 # Displays
bindsym $mod+2 exec pi3-switch -p 2 set $primary DP-2
bindsym $mod+3 exec pi3-switch -p 3 set $left HDMI-0
bindsym $mod+4 exec pi3-switch -p 4 set $right HDMI-1
bindsym $mod+5 exec pi3-switch -p 5
bindsym $mod+6 exec pi3-switch -p 6 # Workspaces
bindsym $mod+7 exec pi3-switch -p 7 set $ws1 1:1:Code
bindsym $mod+8 exec pi3-switch -p 8 set $ws2 2:2:Code
bindsym $mod+9 exec pi3-switch -p 9 set $ws3 3:3:Code
bindsym $mod+0 exec pi3-switch -p 10 set $ws4 4:4:Code
set $ws5 5:5:Code
set $ws6 6:6:Code
set $ws7 7:7:Code
set $ws8 8:8:Code
set $LeftWs1 1:1:Browser
set $LeftWs2 2:2:Left
set $LeftWs3 3:3:Left
set $LeftWs4 4:4:Left
set $LeftWs5 5:5:Left
set $LeftWs6 6:6:Left
set $LeftWs7 7:7:Left
set $LeftWs8 8:8:Left
set $RightWs1 1:1:Right
set $RightWs2 2:2:Right
set $RightWs3 3:3:Right
set $RightWs4 4:4:Right
set $RightWs5 5:5:Right
set $RightWs6 6:6:Right
set $RightWs7 7:7:Right
set $RightWs8 8:8:Right
# Workspace assignments
workspace $ws1 output $primary
workspace $ws2 output $primary
workspace $ws3 output $primary
workspace $ws4 output $primary
workspace $ws5 output $primary
workspace $ws6 output $primary
workspace $ws7 output $primary
workspace $ws8 output $primary
workspace $LeftWs1 output $left
workspace $LeftWs2 output $left
workspace $LeftWs3 output $left
workspace $LeftWs4 output $left
workspace $LeftWs5 output $left
workspace $LeftWs6 output $left
workspace $LeftWs7 output $left
workspace $LeftWs8 output $left
workspace $RightWs1 output $right
workspace $RightWs2 output $right
workspace $RightWs3 output $right
workspace $RightWs4 output $right
workspace $RightWs5 output $right
workspace $RightWs6 output $right
workspace $RightWs7 output $right
workspace $RightWs8 output $right
# Shift workspace
bindsym $mod+1 exec pi3-smart-workspace -i 1
bindsym $mod+2 exec pi3-smart-workspace -i 2
bindsym $mod+3 exec pi3-smart-workspace -i 3
bindsym $mod+4 exec pi3-smart-workspace -i 4
bindsym $mod+5 exec pi3-smart-workspace -i 5
bindsym $mod+6 exec pi3-smart-workspace -i 6
bindsym $mod+7 exec pi3-smart-workspace -i 7
bindsym $mod+8 exec pi3-smart-workspace -i 8
# Move focused container to workspace
bindsym $mod+Ctrl+1 exec pi3-smart-workspace -i 1 -s
bindsym $mod+Ctrl+2 exec pi3-smart-workspace -i 2 -s
bindsym $mod+Ctrl+3 exec pi3-smart-workspace -i 3 -s
bindsym $mod+Ctrl+4 exec pi3-smart-workspace -i 4 -s
bindsym $mod+Ctrl+5 exec pi3-smart-workspace -i 5 -s
bindsym $mod+Ctrl+6 exec pi3-smart-workspace -i 6 -s
bindsym $mod+Ctrl+7 exec pi3-smart-workspace -i 7 -s
bindsym $mod+Ctrl+8 exec pi3-smart-workspace -i 8 -s
# Move to workspace with focused container
bindsym $mod+Shift+1 exec pi3-smart-workspace -i 1 -sk
bindsym $mod+Shift+2 exec pi3-smart-workspace -i 2 -sk
bindsym $mod+Shift+3 exec pi3-smart-workspace -i 3 -sk
bindsym $mod+Shift+4 exec pi3-smart-workspace -i 4 -sk
bindsym $mod+Shift+5 exec pi3-smart-workspace -i 5 -sk
bindsym $mod+Shift+6 exec pi3-smart-workspace -i 6 -sk
bindsym $mod+Shift+7 exec pi3-smart-workspace -i 7 -sk
bindsym $mod+Shift+8 exec pi3-smart-workspace -i 8 -sk
Credits Credits
------- -------
Thanks to Travis Finkenauer for an inspiration (`i3-wk-switch`_) and Thanks to Michał Wieluński for an inspiration (`pi3-switch`_) and
Tony Crisci for an easy-to-use i3 python library (`i3ipc-python`_). Tony Crisci for an easy-to-use i3 python library (`i3ipc-python`_).
.. _pipsi: https://github.com/mitsuhiko/pipsi .. _pipsi: https://github.com/mitsuhiko/pipsi
.. _i3-wk-switch: https://github.com/tmfink/i3-wk-switch .. _pi3-switch: https://github.com/landmaj/pi3-switch
.. _i3ipc-python: https://github.com/acrisci/i3ipc-python .. _i3ipc-python: https://github.com/acrisci/i3ipc-python

35
build.py Normal file
View File

@@ -0,0 +1,35 @@
import argparse
import subprocess
def main():
parser = argparse.ArgumentParser("Build script for pypi and pypi test")
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument(
'--test',
action='store_true',
help='Build to test.pypi.org'
)
group.add_argument(
'--re',
action='store_true',
help='Build to pypi.org'
)
group.add_argument(
'--check',
action='store_true',
help='Displays the twine check for dist'
)
args = parser.parse_args()
subprocess.call(['python3', 'setup.py', 'sdist', 'bdist_wheel'])
if args.test:
subprocess.call(['twine', 'upload', '--config-file', '.pypirc', '--repository', 'testpypi', 'dist/*'])
elif args.re:
subprocess.call(['twine', 'upload', '--config-file', '.pypirc', '--repository', 'pypi', 'dist/*'])
else:
subprocess.call(['twine', 'check', 'dist/*'])
if __name__ == '__main__':
main()

View File

@@ -1,6 +1,5 @@
from i3ipc import Connection from i3ipc import Connection
import sys import sys
from pprint import pprint
import pynput import pynput
import re import re
import argparse import argparse
@@ -28,13 +27,11 @@ class WorkSpacer:
re.finditer(r'set (\$[a-zA-Z]+) ((HDMI|DP|VGA)-\d)', self.config, re.MULTILINE), start=1 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) config_outputs[match.group(1)] = match.group(2)
pprint(config_outputs)
config_workspace_names = {} config_workspace_names = {}
for matchNum, match in enumerate( for matchNum, match in enumerate(
re.finditer(r'set (\$.*) (\d.*)', self.config, re.MULTILINE) re.finditer(r'set (\$.*) (\d.*)', self.config, re.MULTILINE)
): ):
config_workspace_names[match.group(1)] = match.group(2) config_workspace_names[match.group(1)] = match.group(2)
pprint(config_workspace_names)
for matchNum, match in enumerate( for matchNum, match in enumerate(
re.finditer(r'workspace (\$.*) output (\$.*)', self.config, re.MULTILINE) re.finditer(r'workspace (\$.*) output (\$.*)', self.config, re.MULTILINE)
): ):
@@ -52,7 +49,12 @@ class WorkSpacer:
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]}')
if self.args.shift:
self.i3.command(f'move container to workspace {self.workspaces_on_outputs[self.current_output_name][self.args.index - 1]}')
if not self.args.keep_with_it:
return
self.i3.command(f'workspace {self.workspaces_on_outputs[self.current_output_name][self.args.index - 1]}')
def _get_workspace_from_courser_position(self): def _get_workspace_from_courser_position(self):
for output in self.outputs: for output in self.outputs:
@@ -82,13 +84,20 @@ def main():
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
description="Dynamic changes the workspace, based on what output your cursoer is on." 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.") required_group = parser.add_argument_group('Required', '')
ws = WorkSpacer(parser.parse_args()) required_group.add_argument("-i", "--index", type=int, required=True,
ws.run() help="the number index of the workspace that should be openend. 1 = first workspace in config etc.")
shift_group = parser.add_argument_group('Shift', 'manipulate the active window')
shift_group.add_argument("-s", "--shift", action='store_true',
help="if present, moves the current active window to target workspace")
shift_group.add_argument('-k', '--keep-with-it', action='store_true',
help='if present, moves with the ')
WorkSpacer(parser.parse_args()).run()
# Press the green button in the gutter to run the script.
if __name__ == '__main__': if __name__ == '__main__':
main() main()

View File

@@ -1,29 +1,29 @@
from setuptools import setup from setuptools import setup
with open('README.rst', 'r') as fh: with open('README.rst', 'r') as fh:
long_description = fh.read() long_description = fh.read()
with open('requirements.txt', 'r') as file:
required = []
for x in file.readline():
required.append(x)
setup( setup(
name="pi3-smart-workspace", name='pi3-smart-workspace',
description="A smart switcher for multiple workspaces.", version='0.1.2',
packages=['pi3'],
url='https://github.com/GeneralDenmark/PyOutputHandler',
license='Apache-2.0 License ',
install_requires=[
"evdev==1.3.0",
"i3ipc==2.2.1",
"pynput==1.7.1",
"python-xlib==0.27",
"six==1.15.0"
],
entry_points={"console_scripts": ["pi3-smart-workspace=pi3.smart_workspace:main"]},
scripts=["pi3/smart_workspace.py"],
long_description=long_description, long_description=long_description,
version="0.0.1", long_description_content_type='text/x-rst',
license="Apache License", author='Asger Geel Weirsøe',
author="Asger Geel Weirsøe", author_email='asger@weirsoe.dk',
author_email="asger@weirsoe.dk", description='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.',
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=[ classifiers=[
"Development Status :: 2 - Pre-Alpha", "Development Status :: 3 - Alpha",
"License :: OSI Approved :: Apache Software License", "License :: OSI Approved :: Apache Software License",
"Operating System :: POSIX :: Linux", "Operating System :: POSIX :: Linux",
"Programming Language :: Python :: 3", "Programming Language :: Python :: 3",