Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
gmikhail committed May 9, 2021
0 parents commit 810598b
Show file tree
Hide file tree
Showing 12 changed files with 193 additions and 0 deletions.
42 changes: 42 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Hotkey Manager

Utility that provides additional functionality for keyboards without the FN function key.

![Preview](docs/preview.gif)

## Hotkeys

**Note:** FN by default is the Right Windows key.

Hotkey | Action
--- | ---
FN + F5 | Launch Spotify (if possible)
FN + F6 | Previous Track
FN + F7 | Play/Pause
FN + F8 | Next Track
FN + F9 | Mute/Unmute
FN + F10 | Volume Down
FN + F11 | Volume Up
FN + F12 | Launch Calculator

## For Users

Download the latest executable from [Github Releases](/releases/latest) page.

## For Developers

Install packages required for building:

`pip install pyinstaller pyinstaller-versionfile pynput pystray`

Update version in file `metadata/version.txt`

Generate version metadata file:

`create-version-file metadata/metadata.yml --outfile metadata/version_metadata.txt`

Build the executable:

`pyinstaller source/main.py --onefile --windowed --hidden-import pystray._win32 --hidden-import pynput.keyboard._win32 --hidden-import pynput.mouse._win32 --add-data 'resources;resources'--icon 'resources/icon.ico' --name HotkeyManager --version-file metadata/version_metadata.txt`

If you have any requests or fixes, feel free to change the source code.
Binary file added docs/preview.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions metadata/metadata.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Version: version.txt
CompanyName: Mikhail Gribanov
FileDescription: Hotkey Manager
InternalName: Hotkey Manager
LegalCopyright: © Mikhail Gribanov. All rights reserved.
OriginalFilename: HotkeyManager.exe
ProductName: Hotkey Manager
1 change: 1 addition & 0 deletions metadata/version.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1.0.0.0
44 changes: 44 additions & 0 deletions metadata/version_metadata.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# UTF-8
#
# For more details about fixed file info 'ffi' see:
# http://msdn.microsoft.com/en-us/library/ms646997.aspx

VSVersionInfo(
ffi=FixedFileInfo(
# filevers and prodvers should be always a tuple with four items: (1, 2, 3, 4)
# Set not needed items to zero 0. Must always contain 4 elements.
filevers=(1,0,0,0),
prodvers=(1,0,0,0),
# Contains a bitmask that specifies the valid bits 'flags'r
mask=0x3f,
# Contains a bitmask that specifies the Boolean attributes of the file.
flags=0x0,
# The operating system for which this file was designed.
# 0x4 - NT and there is no need to change it.
OS=0x40004,
# The general type of file.
# 0x1 - the file is an application.
fileType=0x1,
# The function of the file.
# 0x0 - the function is not defined for this fileType
subtype=0x0,
# Creation date and time stamp.
date=(0, 0)
),
kids=[
StringFileInfo(
[
StringTable(
u'040904B0',
[StringStruct(u'CompanyName', u'Mikhail Gribanov'),
StringStruct(u'FileDescription', u'Hotkey Manager'),
StringStruct(u'FileVersion', u'1.0.0.0'),
StringStruct(u'InternalName', u'Hotkey Manager'),
StringStruct(u'LegalCopyright', u'© Mikhail Gribanov. All rights reserved.'),
StringStruct(u'OriginalFilename', u'HotkeyManager.exe'),
StringStruct(u'ProductName', u'Hotkey Manager'),
StringStruct(u'ProductVersion', u'1.0.0.0')])
]),
VarFileInfo([VarStruct(u'Translation', [1033, 1200])])
]
)
Binary file added resources/icon-off.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added resources/icon.ico
Binary file not shown.
Binary file added resources/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
48 changes: 48 additions & 0 deletions source/hotkeys.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
from pynput.keyboard import Key, Listener, Controller, KeyCode
from subprocess import Popen
from os import path
from tray import get_state as state

FN = Key.cmd_r# Functional key
isFN = False
keyboard = Controller()

def on_press(key):
#print('on_press {}'.format(key))
global FN, isFN, keyboard
if key == FN: isFN = True
if isFN and state():
# Media
if key == Key.f5:
try: Popen(path.expandvars(r'%AppData%\Spotify\Spotify.exe'))
except: print('App not found')
elif key == Key.f6: press_key(key.media_previous)
elif key == Key.f7: press_key(key.media_play_pause)
elif key == Key.f8: press_key(key.media_next)
# Volume
elif key == Key.f9: press_key(key.media_volume_mute)
elif key == Key.f10: press_key(key.media_volume_down)
elif key == Key.f11: press_key(key.media_volume_up)
# Other
elif key == Key.f12: Popen(('calc'))
#elif key == Key.f12: press_key(KeyCode.from_vk(0xA9))
# https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes

def on_release(key):
#print('on_release {}'.format(key))
global FN, isFN
if key == FN: isFN = False

def press_key(key):
keyboard.press(key)
keyboard.release(key)
print('Key press: {}'.format(key))

def start_listener():
with Listener(on_press=on_press, on_release=on_release) as listener:
listener.join()

if __name__ == '__main__':
start_listener()

# https://pynput.readthedocs.io/en/latest/keyboard.html
7 changes: 7 additions & 0 deletions source/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from hotkeys import start_listener
from tray import run_icon_tray
from threading import Thread

if __name__ == "__main__":
Thread(target=start_listener).start()
Thread(target=run_icon_tray).start()
35 changes: 35 additions & 0 deletions source/tray.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from PIL import Image
from pystray import Icon as icon, Menu as menu, MenuItem as item
from os import _exit
from utils import absolute_path

def menu_exit():
icon_tray.visible = False
icon_tray.stop()
_exit(0)

state = True

def get_state():
return state

def on_clicked(icon, item):
global state
state = not item.checked
icon_tray.icon = Image.open(absolute_path(r'resources\icon.png')) if state else Image.open(absolute_path(r'resources\icon-off.png'))

def run_icon_tray():
global icon_tray
icon_tray = icon(
name = 'name',
icon = Image.open(absolute_path(r'resources\icon.png')),
title = 'Hotkey Manager',
menu = menu(
item('Active', on_clicked, default=True, checked=lambda item: state),
item('Exit', menu_exit)
)
)
icon_tray.run()

if __name__ == '__main__':
run_icon_tray()
9 changes: 9 additions & 0 deletions source/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import os, sys

def absolute_path(path):
try:
# PyInstaller creates a temp folder and stores path in _MEIPASS
base_path = sys._MEIPASS
except AttributeError:
base_path = os.getcwd()
return os.path.join(base_path, path)

0 comments on commit 810598b

Please sign in to comment.