Skip to content

Commit 26a03aa

Browse files
authored
Merge pull request #5 from kbkozlev/development
Development
2 parents 7fba57d + 2cd6033 commit 26a03aa

File tree

3 files changed

+108
-74
lines changed

3 files changed

+108
-74
lines changed

app/settings/helpers/functions.py

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22
import logging
33
import ctypes
44
import time
5+
import os
56
from threading import Event
67
from multiprocess import Process
7-
8+
import subprocess
89

910
logging.basicConfig(filename='./app/settings/log.log', encoding='utf-8', level=logging.INFO,
1011
format='%(asctime)s | %(message)s', datefmt='%Y/%m/%d %I:%M:%S %p')
1112

12-
1313
keys_list = ['ALT', 'CTRL', 'SHIFT', 'WINDOWS',
1414
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
1515
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
@@ -37,9 +37,23 @@ def get_hotkey(conf):
3737
return hot_key
3838

3939

40-
def is_capslock_on(pag):
41-
if ctypes.WinDLL("User32.dll").GetKeyState(0x14):
42-
pag.press('capslock')
40+
def is_capslock_on(pag, os_name):
41+
capslock_state = False
42+
try:
43+
if os_name == "windows":
44+
capslock_state = ctypes.WinDLL("User32.dll").GetKeyState(0x14) & 1
45+
elif os_name == "linux":
46+
output = subprocess.run(['xset', 'q'], capture_output=True, text=True, check=True).stdout
47+
if "Caps Lock: on" in output:
48+
capslock_state = True
49+
else:
50+
raise NotImplementedError("Unsupported platform")
51+
52+
if capslock_state:
53+
pag.press('capslock')
54+
55+
except Exception as e:
56+
logging.error(e)
4357

4458

4559
def graceful_exit(event, window, pag):
@@ -48,7 +62,8 @@ def graceful_exit(event, window, pag):
4862
except Exception as e:
4963
logging.error(e)
5064
finally:
51-
is_capslock_on(pag)
65+
os_name = os_check()
66+
is_capslock_on(pag,os_name=os_name)
5267
window.write_event_value('Exit', True)
5368

5469

@@ -110,3 +125,12 @@ def get_latest_version():
110125

111126
def create_process(args, *kwargs):
112127
return Process(target=args, args=kwargs)
128+
129+
130+
def os_check():
131+
if os.name == 'nt':
132+
return "windows"
133+
elif os.name == 'posix':
134+
return "linux"
135+
else:
136+
return "unknown"

main.pyw

Lines changed: 78 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import time
2-
import sys
32
import multiprocess
43
import webbrowser
5-
import PySimpleGUI as sg
4+
import PySimpleGUI as Sg
65
import pyautogui as pag
76
import keyboard
87
import logging
9-
from app.settings.helpers.functions import (get_latest_version, create_process, countdown, graceful_exit, get_hotkey, correct_key,
10-
is_capslock_on, terminate)
8+
from app.settings.helpers.functions import (get_latest_version, create_process, countdown, graceful_exit, get_hotkey,
9+
correct_key,
10+
is_capslock_on, terminate, os_check)
1111
from threading import Thread, Event
1212
from app.settings.helpers.mouse_jiggler import jiggler
1313
from app.settings.helpers.configurator import Configurator
@@ -17,48 +17,49 @@ logging.basicConfig(filename='app/settings/helpers/log.log', encoding='utf-8', l
1717

1818

1919
def about_window():
20-
layout = [[sg.T(s=40)],
21-
[sg.Push(), sg.T(str(WINDOW_TITLE), font=(FONT_FAMILY, 12, "bold")), sg.Push()],
22-
[sg.Push(), sg.T("Prevent your PC from sleeping with - 'Don't sleep' \nor X-Sleep for short.",
23-
font=(FONT_FAMILY, 9, "italic"), justification='c', text_color='grey'), sg.Push()],
24-
[sg.T()],
25-
[sg.Push(), sg.T(github_url['name'], enable_events=True, font=(FONT_FAMILY, 10, "underline"),
20+
layout = [[Sg.T(s=40)],
21+
[Sg.Push(), Sg.T(str(WINDOW_TITLE), font=(FONT_FAMILY, 12, "bold")), Sg.Push()],
22+
[Sg.Push(), Sg.T("Prevent your PC from sleeping with - 'Don't sleep' \nor X-Sleep for short.",
23+
font=(FONT_FAMILY, 9, "italic"), justification='c', text_color='grey'), Sg.Push()],
24+
[Sg.T()],
25+
[Sg.Push(), Sg.T(github_url['name'], enable_events=True, font=(FONT_FAMILY, 10, "underline"),
2626
justification='l', text_color='#0066CC',
27-
auto_size_text=True, key='-LINK-'), sg.Push()],
28-
[sg.Push(), sg.T("License: GPL-3.0", justification='c'), sg.Push()],
29-
[sg.T()],
30-
[sg.Push(), sg.T("Copyright © 2023 Kaloian Kozlev", text_color='light grey'), sg.Push()]]
27+
auto_size_text=True, key='-LINK-'), Sg.Push()],
28+
[Sg.Push(), Sg.T("License: GPL-3.0", justification='c'), Sg.Push()],
29+
[Sg.T()],
30+
[Sg.Push(), Sg.T("Copyright © 2023 Kaloian Kozlev", text_color='light grey'), Sg.Push()]]
3131

32-
window = sg.Window("About", layout, icon=ICON)
32+
window = Sg.Window("About", layout, icon=ICON)
3333

3434
while True:
3535
event, values = window.read()
3636

3737
match event:
38-
case sg.WIN_CLOSED:
38+
case Sg.WIN_CLOSED:
3939
break
4040

4141
case '-LINK-':
4242
webbrowser.open(github_url['url'])
4343
window.close()
44+
break
4445

4546

46-
def new_version_check(c_release, c_release_name, l_release, l_release_name, down_url):
47+
def new_version_window(c_release, c_release_name, l_release, l_release_name, down_url):
4748
global update_check
48-
layout = [[sg.T(s=40)],
49-
[sg.T(font=(FONT_FAMILY, 10), justification='l', key="-INFO-")],
50-
[sg.T()],
51-
[sg.T('Current Version is :', justification='l', font=(FONT_FAMILY, 10)),
52-
sg.T(f'{c_release_name}', font=(FONT_FAMILY, 10))],
53-
[sg.T('Available Version is:', justification='l', font=(FONT_FAMILY, 10)),
54-
sg.T(f'{l_release_name}', font=(FONT_FAMILY, 10))],
55-
[sg.T()],
56-
[sg.Push(),
57-
sg.B('Yes', key='-DOWNLOAD-', s=8, button_color='#93b7a6'),
58-
sg.B(key='-EXIT-', s=8, button_color='#db5656'),
59-
sg.Push()]]
60-
61-
window = sg.Window("Update Available", layout, icon=ICON, keep_on_top=True, finalize=True)
49+
layout = [[Sg.T(s=40)],
50+
[Sg.T(font=(FONT_FAMILY, 10), justification='l', key="-INFO-")],
51+
[Sg.T()],
52+
[Sg.T('Current Version is :', justification='l', font=(FONT_FAMILY, 10)),
53+
Sg.T(f'{c_release_name}', font=(FONT_FAMILY, 10))],
54+
[Sg.T('Available Version is:', justification='l', font=(FONT_FAMILY, 10)),
55+
Sg.T(f'{l_release_name}', font=(FONT_FAMILY, 10))],
56+
[Sg.T()],
57+
[Sg.Push(),
58+
Sg.B('Yes', key='-DOWNLOAD-', s=8, button_color='#93b7a6'),
59+
Sg.B(key='-EXIT-', s=8, button_color='#db5656'),
60+
Sg.Push()]]
61+
62+
window = Sg.Window("Update Available", layout, icon=ICON, keep_on_top=True, finalize=True)
6263

6364
if l_release is None:
6465
message = "Cannot fetch version data! \nPlease check your network connection."
@@ -85,7 +86,7 @@ def new_version_check(c_release, c_release_name, l_release, l_release_name, down
8586
event, values = window.read()
8687

8788
match event:
88-
case sg.WIN_CLOSED:
89+
case Sg.WIN_CLOSED:
8990
break
9091

9192
case '-DOWNLOAD-':
@@ -103,50 +104,54 @@ def main_window():
103104

104105
app_menu = [['Help', ['About', 'Check for Updates']]]
105106

106-
layout = [[sg.Menubar(app_menu)],
107-
[sg.Frame('Hotkey',
108-
[[sg.I(disabled=True, default_text=hot_key, justification='c',
107+
layout = [[Sg.Menubar(app_menu)],
108+
[Sg.Frame('Hotkey',
109+
[[Sg.I(disabled=True, default_text=hot_key, justification='c',
109110
disabled_readonly_text_color='grey', disabled_readonly_background_color='#dae0e6',
110111
key='-HT_KEY-', tooltip="ALT, CTRL, SHIFT, WINDOWS, A-Z, 0-9, F1-F12")],
111-
[sg.Checkbox('Change', key='-CHANGE-', enable_events=True), sg.Push(),
112-
sg.B('Reset', size=8, key='-RESET-'),
113-
sg.B('Apply', size=8, disabled=True, disabled_button_color='light grey', key='-APPLY-')]
112+
[Sg.Checkbox('Change', key='-CHANGE-', enable_events=True, disabled=True), Sg.Push(),
113+
Sg.B('Reset', size=8, key='-RESET-', disabled_button_color='light grey', disabled=True),
114+
Sg.B('Apply', size=8, disabled=True, disabled_button_color='light grey', key='-APPLY-')]
114115
], expand_x=True)],
115-
[sg.Frame('Timer',
116-
[[sg.T('Hours:'), sg.DropDown(HOURS, default_value=' 00', key='-H-', disabled=True,
116+
[Sg.Frame('Timer',
117+
[[Sg.T('Hours:'), Sg.DropDown(HOURS, default_value=' 00', key='-H-', disabled=True,
117118
readonly=True, button_background_color='#93b7a6', s=(3, 1)),
118-
sg.T('Minutes:'), sg.DropDown(MINUTES, default_value=' 00', key='-M-', disabled=True,
119+
Sg.T('Minutes:'), Sg.DropDown(MINUTES, default_value=' 00', key='-M-', disabled=True,
119120
readonly=True, button_background_color='#93b7a6', s=(3, 1)),
120-
sg.T('Seconds:'), sg.DropDown(SECONDS, default_value=' 00', key='-S-', disabled=True,
121+
Sg.T('Seconds:'), Sg.DropDown(SECONDS, default_value=' 00', key='-S-', disabled=True,
121122
readonly=True, button_background_color='#93b7a6', s=(3, 1))
122123
],
123-
[sg.Radio('Off', 'timer', default=True, enable_events=True, key='-OFF-'),
124-
sg.Radio('On', 'timer', enable_events=True, key='-ON-'), sg.Push(),
125-
sg.I(background_color='#dae0e6', size=8, key='-LOG_TIME-', justification='c',
124+
[Sg.Radio('Off', 'timer', default=True, enable_events=True, key='-OFF-'),
125+
Sg.Radio('On', 'timer', enable_events=True, key='-ON-'), Sg.Push(),
126+
Sg.I(background_color='#dae0e6', size=8, key='-LOG_TIME-', justification='c',
126127
default_text='00:00:00', disabled=True, disabled_readonly_text_color='grey',
127128
disabled_readonly_background_color='#dae0e6', readonly=True)]
128129
], expand_x=True)],
129-
[sg.Frame('Log',
130-
[[sg.Input(background_color='#dae0e6', size=45, key='-LOG-', justification='c',
130+
[Sg.Frame('Log',
131+
[[Sg.Input(background_color='#dae0e6', size=45, key='-LOG-', justification='c',
131132
text_color='white')]], expand_x=True)],
132-
[sg.Button('Start', size=8, button_color='#93b7a6', disabled_button_color='light grey',
133+
[Sg.Button('Start', size=8, button_color='#93b7a6', disabled_button_color='light grey',
133134
key='-START-'),
134-
sg.Button('Stop', size=8, button_color='#ffcf61', disabled=True,
135+
Sg.Button('Stop', size=8, button_color='#ffcf61', disabled=True,
135136
disabled_button_color='light grey', key='-STOP-'),
136-
sg.Button('Exit', size=8, button_color='#db5656')]
137+
Sg.Button('Exit', size=8, button_color='#db5656')]
137138
]
138139

139-
window = sg.Window(WINDOW_TITLE, layout, keep_on_top=False)
140+
window = Sg.Window(WINDOW_TITLE, layout, keep_on_top=False)
141+
142+
if update_check:
143+
new_version_window(RELEASE, RELEASE_NAME, latest_release, latest_release_name, download_url)
140144

141145
while True:
142146
event, values = window.read(timeout=10)
143147

144-
if update_check:
145-
new_version_check(RELEASE, RELEASE_NAME, latest_release, latest_release_name, download_url)
148+
if hot_key_active:
149+
window['-CHANGE-'].update(disabled=False)
150+
window['-RESET-'].update(disabled=False)
146151

147-
keyboard.add_hotkey(hot_key, lambda: graceful_exit(thread_event, window, pag))
152+
keyboard.add_hotkey(hot_key, lambda: graceful_exit(thread_event, window, pag))
148153

149-
if event in ('Exit', sg.WIN_CLOSED):
154+
if event in ('Exit', Sg.WIN_CLOSED):
150155
break
151156

152157
if event == '-START-':
@@ -169,7 +174,7 @@ def main_window():
169174
window['-LOG-'].update('Application running', background_color='#5fad65')
170175

171176
elif event == '-STOP-':
172-
is_capslock_on(pag)
177+
is_capslock_on(pag, os_name=os_name)
173178

174179
if values['-ON-'] and values['-LOG_TIME-'] != '00:00:00':
175180
thread_event.set()
@@ -231,16 +236,28 @@ def main_window():
231236
about_window()
232237

233238
if event == 'Check for Updates':
234-
new_version_check(RELEASE, RELEASE_NAME, latest_release, latest_release_name, download_url)
239+
new_version_window(RELEASE, RELEASE_NAME, latest_release, latest_release_name, download_url)
235240

236241
graceful_exit(thread_event, window, pag)
237242

238243

239244
if __name__ == '__main__':
240-
if sys.platform.startswith('win'):
245+
hot_key_active = False
246+
thread_event = Event()
247+
conf = Configurator()
248+
conf.create_on_start()
249+
hot_key = get_hotkey(conf)
250+
update_check = False
251+
bgp = None
252+
os_name = os_check()
253+
254+
if os_name == "windows":
241255
multiprocess.freeze_support()
256+
hot_key_active = True
257+
else:
258+
hot_key = 'Not Supported on this platform'
242259

243-
RELEASE_NAME = '2.0.2'
260+
RELEASE_NAME = '3.0.0'
244261
RELEASE = int(''.join(filter(lambda x: x.isdigit(), RELEASE_NAME)))
245262
WINDOW_TITLE = "X-Sleep"
246263
FONT_FAMILY = "Arial"
@@ -252,15 +269,8 @@ if __name__ == '__main__':
252269
github_url = {'name': 'Official GitHub Page',
253270
'url': 'https://github.com/kbkozlev/x-sleepGUI'}
254271

255-
sg.theme("Reddit")
256-
sg.set_options(force_modal_windows=True, dpi_awareness=True, use_ttk_buttons=True, icon=ICON)
257-
258-
thread_event = Event()
259-
conf = Configurator()
260-
conf.create_on_start()
261-
hot_key = get_hotkey(conf)
262-
update_check = False
263-
bgp = None
272+
Sg.theme("Reddit")
273+
Sg.set_options(force_modal_windows=True, dpi_awareness=True, use_ttk_buttons=True, icon=ICON)
264274

265275
latest_release, latest_release_name, download_url = get_latest_version()
266276
if latest_release is not None and latest_release > RELEASE:

requirements.txt

0 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)