Skip to content

Commit

Permalink
Summer24, bump to 1.6.3 (#25)
Browse files Browse the repository at this point in the history
* testing mouse actions in unimacroutils.py... work in progress...
* unimacroutils.py set_mouse_position added
* bump to 1.6.3

---------

Co-authored-by: Doug Ransom <[email protected]>
  • Loading branch information
quintijn and dougransom authored Aug 22, 2024
1 parent eb53571 commit d577abc
Show file tree
Hide file tree
Showing 11 changed files with 279 additions and 158 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -152,3 +152,4 @@ cython_debug/
.vscode
/documentation/.#*
.rst
*.orig
2 changes: 1 addition & 1 deletion src/dtactions/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
"""
## version to be updated when a new release is sent to pypi:
__version__ = '1.6.2'
__version__ = '1.6.3'
##----------------------
import sys
import os
Expand Down
12 changes: 5 additions & 7 deletions src/dtactions/autohotkeyactions.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
This module contains actions via AutoHotkey
Note: most are sucking and not tested. Working are two important functions `getProgInfo` and `getModInfo`,
which give the wanted information also when Dragon is not running. (And of course the workflow functions
described below).
(see autohotkey.com)
1. the ahkexe and ahkscriptfolder are checked for at the bottom of the import procedure.
Expand All @@ -24,13 +28,7 @@
5. When scripts want information back into python, write this information into a file eg "INFOfromAHK.txt".
Scripts that use this feature, should have a function in this module, in order to read the data from this file.
See getProgInfo and getCurrentModule below.
timing results:
1 0.000 0.000 0.401 0.401 autohotkeyactions.py:456(killWindow)
4 0.000 0.000 0.261 0.065 autohotkeyactions.py:91(getProgInfo)
1 0.000 0.000 0.234 0.234 autohotkeyactions.py:209(ahkBringup)
1 0.000 0.000 0.052 0.052 autohotkeyactions.py:323(GetForegroundWindow)
"""
import subprocess
import shutil
Expand Down
13 changes: 8 additions & 5 deletions src/dtactions/monitorfunctions.py
Original file line number Diff line number Diff line change
Expand Up @@ -1198,7 +1198,10 @@ def test_mouse_to_other_monitor():
# canBeResized = window_can_be_resized(winHndle)
mon = get_nearest_monitor_window(winHndle)
others = get_other_monitors(mon)
moninfo = MONITOR_INFO[others[0]]
try:
moninfo = MONITOR_INFO[others[0]]
except IndexError:
print('test_mouse_to_other_monitor, you have only one monitor')
mousefour = moninfo['Monitor']
x, y = mousefour[0] + int((mousefour[2] - mousefour[0])/2.0), mousefour[1] + int((mousefour[3] - mousefour[1])/2.0)
print('middle of other monitor:', x, y)
Expand Down Expand Up @@ -1758,13 +1761,13 @@ def do_doctest():
#print 'ra: %s'% _get_restore_area(winHndle)
test_basic_values()
test_taskbar_position()
test_mouse_to_other_monitor()
#restore_window(winHndle)
# test_mouse_to_other_monitor()
# restore_window(win_hndle)
#test_get_nearest_monitors()
#test_individual_points()
test_individual_points()

# test_move_to_other_monitor()
#test_move_around_monitor_fixed_size()
test_move_around_monitor_fixed_size()
#test_center_different_sizes()
#test_default_restore()
# test_minimize_maximize_restore()
Expand Down
46 changes: 7 additions & 39 deletions src/dtactions/unimacro/extenvvars.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,39 +121,6 @@ def getFolderFromLibraryName(self, name):
if name in ['LOCAL_APPDATA']:
return platformdirs.windows.get_win_folder("CSIDL_LOCAL_APPDATA")

# # General case, try via shellcon! TODO: QH
# try:
# CSIDL_variable = 'CSIDL_%s'% name
# shellnumber = getattr(shellcon,CSIDL_variable, -1)
# print(f'getFolderFromLibraryName, shellnumber of "{CSIDL_variable}": {shellnumber}')
# except:
# print('getExtendedEnv, cannot find CSIDL_variable for: "%s"'% name)
# return ''
# if shellnumber < 0:
# # on some systems have SYSTEMROOT instead of SYSTEM:
# print('getExtendedEnv, cannot find CSIDL_variable for (returns -1): "%s"'% name)
# try:
# csidl_const = shellnumber
# # copied from platformdirs/windows.py:
# buf = ctypes.create_unicode_buffer(1024)
# windll = getattr(ctypes, "windll") # noqa: B009 # using getattr to avoid false positive with mypy type checker
# windll.shell32.SHGetFolderPathW(None, csidl_const, None, 0, buf)
# result = buf.value
# # # result = shell.SHGetFolderPath (0, shellnumber, 0, 0)
# # result = ctypes.windll.shell32.SHGetFolderPathW(0, shellnumber, 0, 0)
# print(f'result from SHGetFolderPathW: {result}')
# except:
# print('getFolderFromLibraryName, cannot path for CSIDL: "%s"'% name)
# return ''


## extra cases:
# if name in ['Quick access', 'Snelle toegang']:
# templatesfolder =self. getExtendedEnv('TEMPLATES')
# if isdir(templatesfolder):
# QuickAccess = normpath(join(templatesfolder, "..", "Libraries"))
# if isdir(QuickAccess):
# return QuickAccess
if name.upper() == 'DROPBOX':
return self.getDropboxFolder()
if name.upper() in ['ONEDRIVE']:
Expand Down Expand Up @@ -316,7 +283,7 @@ def getExtendedEnv(self, var, noCache=False, displayMessage=True):
result = buf.value
# # result = shell.SHGetFolderPath (0, shellnumber, 0, 0)
# result = ctypes.windll.shell32.SHGetFolderPathW(0, shellnumber, 0, 0)
print(f'result from SHGetFolderPathW: {result}')
# print(f'result for "{var}" via SHGetFolderPathW: {result}')
except:
if displayMessage:
print('getExtendedEnv, cannot find in os.environ or CSIDL: "%s"'% var)
Expand All @@ -337,11 +304,12 @@ def getDirectoryFromNatlinkstatus(self, envvar):
# try if function in natlinkstatus:
if not status:
return None
for extra in ('', 'Directory', 'Dir'):
var2 = envvar + extra
if var2 in status.__dict__:
funcName = f'get{var2}'
func = getattr(status, funcName)
envvar_capped = envvar.lower()
for extra in ('', 'directory', 'dir'):
var2 = envvar_capped + extra
funcName = f'get{var2}'
func = getattr(status, funcName, None)
if func:
result = func()
if result:
return result
Expand Down
77 changes: 58 additions & 19 deletions src/dtactions/unimacro/unimacroutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"""
#pylint:disable=C0302, C0116, C0321, R0912, R0913, R0914, R0915, W0613, C0209, W0602, W0621, R1715, W0702
#pylint:disable=E1101
#pylint:disable=E1101, R1735
import time
import re
import os
Expand Down Expand Up @@ -639,6 +639,10 @@ def doMouse(absorrel, screenorwindow, xpos, ypos, mouse='left', nClick=1, modifi
other actions are performed.
Therefore the mouse state is remembered in the variable mouseState.
2024: because of Dragon 16, with playEvents not working any more, this function restricts to
movements and clicking, not dragging any more.
"""
#pylint:disable=W0603
global mouseState
Expand Down Expand Up @@ -736,10 +740,11 @@ def doMouse(absorrel, screenorwindow, xpos, ypos, mouse='left', nClick=1, modifi
print('btn: %s, nClick: %s, current mouseState: %s'% (btn, nClick, mouseState))
if onlyMove:
print('onlyMove to %s, %x'% (xp, yp))
natlink.playEvents([(natlinkutils.wm_mousemove, xp, yp)])
set_mouse_position(xp, yp) # absolute
elif not mouseState: # ongecompliceerd
if nClick > 0:
natlink.playEvents([(natlinkutils.wm_mousemove, xp, yp)])
set_mouse_position(xp, yp)
# natlink.playEvents([(natlinkutils.wm_mousemove, xp, yp)])
if btn:
if debugMode == -1:
print('ButtonClick %s, %s' % (btn, nClick))
Expand All @@ -753,7 +758,8 @@ def doMouse(absorrel, screenorwindow, xpos, ypos, mouse='left', nClick=1, modifi
## Wait(0.01)

elif nClick == 0:
natlink.playEvents([(natlinkutils.wm_mousemove, xp, yp)])
set_mouse_position(xp, yp)
# natlink.playEvents([(natlinkutils.wm_mousemove, xp, yp)])
elif nClick == -1:
if btn:
if (xold,yold) != (xp, yp):
Expand Down Expand Up @@ -786,7 +792,8 @@ def doMouse(absorrel, screenorwindow, xpos, ypos, mouse='left', nClick=1, modifi
mouseState = 0
else:
# no btn, but mouseState, simply move:
natlink.playEvents([(natlinkutils.wm_mousemove, xp, yp)])
set_mouse_position(xp, yp)
# natlink.playEvents([(natlinkutils.wm_mousemove, xp, yp)])

def catchClick(mouse):
"""return reduced mouse command and nClick
Expand Down Expand Up @@ -826,11 +833,33 @@ def buttonClick(button='left', nclick=1, modifiers=None):
script = 'ButtonClick'
else:
script = f'ButtonClick {button},{nclick}'
print(f'buttonClick via execScript: "{script}"')
# print(f'buttonClick via execScript: "{script}"')
natlink.execScript(script)



# script = f'ButtonClick {button},{nclick}'
# # print(f'buttonClick via execScript: "{script}"')
# natlink.execScript(script)

def set_mouse_position(xp, yp):
"""set to absolute position
when Dragon is running, with playEvents for version <= 15,
via execScript if version >= 16
when Dragon is NOT running, try via Autohotkey (to be done)
"""
xp, yp = int(xp), int(yp)
if natlink.isNatSpeakRunning():
if natlink.getDNSVersion() <= 15:
natlink.playEvents( [(natlinkutils.wm_mousemove, xp, yp)])
else:
script = f'SetMousePosition 1, {xp},{yp}'
print(f'set_mouse_position via execScript: "{script}"')
natlink.execScript(script)
else:
print('future: attempt set_mouse_position via autohotkey')

def releaseMouse():
"""restores the default mouseState
"""
Expand Down Expand Up @@ -966,33 +995,39 @@ def getMousePositionActionString(absorrel, which, position):
return "MP(%s, %s, %s)"% (which, x, y)

def printMousePosition(absorrel, printAll = 0):
"""printing function for printing the mouse positions
result = getMousePositions(absorrel, printAll=printAll)
print(result)

def getMousePositions(absorrel, printAll = 0):
"""get output for printing the mouse positions
this function can be invoked by PMP and PRMP and PALLMP.
these positions are recognised by the Unimacro Shorthand Commands MP and RMP
"""
L = []
if printAll:
print('-'*80)
L.append('-'*80)
cornerRange = list(range(4))
else:
cornerRange = list(range(1))
if absorrel: # 1: relative:
print('RELATIVE MOUSE POSITIONS:')
L.append('RELATIVE MOUSE POSITIONS:')
else:
print('ABSOLUTE MOUSE POSITIONS:')
for _, which in whichDict.items():
print('---related to %s:'% which.upper())
L.append('ABSOLUTE MOUSE POSITIONS:')
for whichnum, which in whichDict.items():
L.append('---related to %s:'% which.upper())
for cornerPos in cornerRange:
print("%s: %s"% (cornerDict[cornerPos], getMousePositionActionString(absorrel, which, cornerPos)))
L.append("%s: %s"% (cornerDict[cornerPos], getMousePositionActionString(absorrel, whichnum, cornerPos)))
if printAll:
print('-'*20)
L.append('-'*20)
return '\n'.join(L)

def getMousePosition(absorrel=0, which=0, position=0):
"""get the parameters for doMouse
absorrel: 0 abs, 1 rel
which: 1: active window, 5: client area, 0: whole screen
which: 1: active window, 3: active monitor, 5: client area, 0: whole screen
position: 0: topleft, 1: topright, 2: bottomleft, 3: bottomright
result:
Expand All @@ -1004,6 +1039,7 @@ def getMousePosition(absorrel=0, which=0, position=0):
#pylint:disable=R0912, W0612
x, y = currentPos = natlink.getCursorPos()
_hndle = natlink.getCurrentModule()[2]
print(f'which: {which}')
if which == 0:
# complete screen
width, height, xMin, yMin, xMax, yMax = monitorfunctions.getScreenRectData()
Expand All @@ -1024,6 +1060,8 @@ def getMousePosition(absorrel=0, which=0, position=0):
x, y = win32gui.ScreenToClient(_hndle, currentPos)
rect = win32gui.GetClientRect(_hndle)
width, height, xMin, yMin, xMax, yMax = getRectData(rect)
else:
raise ValueError(f'getMousePosition, variable "which" should be in (0, 1, 3, 5), not: {which}')

# now test for boundaries and abs or rel:
if x < xMin or x > xMax or y < yMin or y > yMax:
Expand Down Expand Up @@ -1062,6 +1100,7 @@ def isTopWindow(hndle):
"""returns 1 if window is top,
behaviour changed in python 2.3.4, parent = 0, no exception any more
TODO QH: is this correct?
"""
#pylint:disable=W0702
try:
Expand Down Expand Up @@ -1404,8 +1443,8 @@ def addWordIfNecessary(w):
print('invalid character in word to add: %s'% w)
return

isInVoc = (natlink.getWordInfo(w,1) is not None)
isInActiveVoc = (natlink.getWordInfo(w,0) is not None)
isInVoc = natlink.getWordInfo(w,1) is not None
isInActiveVoc = natlink.getWordInfo(w,0) is not None
if isInActiveVoc:
return
try:
Expand All @@ -1426,7 +1465,7 @@ def deleteWordIfNecessary(w):
"""
if not w:
return
isInActiveVoc = (natlink.getWordInfo(w,0) is not None)
isInActiveVoc = natlink.getWordInfo(w,0) is not None
if isInActiveVoc:
natlink.deleteWord(w)

Expand Down
15 changes: 15 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
"""common fixtures for the dtactions project
"""
import pytest
import natlink
from natlinkcore import natlinkstatus

@pytest.fixture(scope="module")
def nl_stat():
status = natlinkstatus.NatlinkStatus()
return status

@pytest.fixture(scope="module")
def nat_conn():
yield natlink.natConnect()
natlink.natDisconnect()
Loading

0 comments on commit d577abc

Please sign in to comment.