Skip to content

Commit 9fb09c6

Browse files
committed
MACOS: Tested OK in multi-monitor setup
1 parent b04c057 commit 9fb09c6

File tree

8 files changed

+25
-14
lines changed

8 files changed

+25
-14
lines changed

CHANGES.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
0.5, 2023/09/06 -- MACOS: Tested OK in multi-monitor setup
12
0.4, 2023/08/25 -- Reorganized to avoid IDEs showing external and / or private elements
23
0.3, 2023/08/21 -- Linux: Improved window geometry (thanks to elraymond - https://github.com/elraymond)
34
ALL: Improved default onQuery/onSet methods

README.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@
77
Cross-Platform and multi-monitor module which allows to manage window areas (position and
88
size) and all their properties, as well as any rectangular area.
99

10-
**WARNING: Multi-monitor support is still experimental and not fully tested in macOS.**
11-
1210
## Rectangular areas
1311

1412
You just need to instantiate the PyWinBox class, passing custom callbacks to be called when any property is

src/pywinbox/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"version", "PyWinBox", "Box", "Rect", "Point", "Size", "pointInBox"
66
]
77

8-
__version__ = "0.4"
8+
__version__ = "0.5"
99

1010

1111
def version(numberOnly: bool = True) -> str:

src/pywinbox/_main.py

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -83,22 +83,33 @@ def __init__(self, onQuery: Optional[Callable[[], Box]] = None, onSet: Optional[
8383
In this case, if your custom functions do not properly retrieve or set the actual window position and size, the
8484
information contained in the PyWinBox class, and returned by all properties, will likely become obsolete.
8585
86-
It can raise ValueError if no parameters are passed.
86+
It can raise ValueError if no parameters or not valid window handle are passed
8787
"""
88-
self._box: Box = Box(0, 0, 0, 0)
89-
if handle is not None:
90-
self._handle = _getHandle(handle) if handle is not None else None
91-
elif onSet is None and onQuery is None:
88+
self._handle = _getHandle(handle) if handle is not None else None
89+
if self._handle is None and (onSet is None or onQuery is None):
9290
raise ValueError
9391
self._onQuery: Callable[[], Box] = onQuery or self.onQuery
9492
self._onSet: Callable[[Box], None] = onSet or self.onSet
93+
self._box: Box = Box(0, 0, 0, 0)
9594

9695
def onQuery(self) -> Box:
96+
"""
97+
Default method to retrieve current window position and size values when a property is queried.
98+
It requires to pass valid window handle when instantiating the main class (PyWinBox class)
99+
100+
:return: window Box struct (x, y, width, height)
101+
"""
97102
if self._handle is not None:
98103
self._box = _getWindowBox(self._handle)
99104
return self._box
100105

101106
def onSet(self, newBox: Box):
107+
"""
108+
Default method to actually place / resize the window when a property is changed.
109+
It requires to pass valid window handle when instantiating the main class (PyWinBox class)
110+
111+
:param newBox: target position and or size in Box struct format (x, y, width, height)
112+
"""
102113
if self._handle is not None:
103114
_moveResizeWindow(self._handle, newBox)
104115

@@ -114,7 +125,7 @@ def __repr__(self):
114125

115126
def __str__(self):
116127
"""Return a string representation of this Box object."""
117-
return "(%s, %s, w=%s, h=%s)" % (
128+
return "(%s, %s, %s, %s)" % (
118129
self._box.left,
119130
self._box.top,
120131
self._box.width,

src/pywinbox/_pywinbox_macos.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ def _unflipTop(window: AppKit.NSWindow, box: Box) -> int:
154154

155155
def _NSgetWindowBox(window: AppKit.NSWindow, flipValues: bool = False) -> Box:
156156
# frame = window.frame()
157-
frame = window.screen().convertRectToBacking_(window.frame())
157+
frame = window.frame()
158158
x = int(frame.origin.x)
159159
y = int(frame.origin.y)
160160
w = int(frame.size.width)

tests/test_MacNSBox.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ def applicationDidFinishLaunching_(self, aNotification: None):
5050

5151
if win:
5252
print("ACTIVE WINDOW:", win.title)
53-
5453
myPyBox = pywinbox.PyWinBox(onQuery=None, onSet=None, handle=win.getHandle())
5554

5655
else:
@@ -59,6 +58,8 @@ def applicationDidFinishLaunching_(self, aNotification: None):
5958

6059
timelap = 0.3
6160

61+
print("INIT", myPyBox.box, myPyBox._handle.window.frame())
62+
6263
print("MOVE left = 200", myPyBox.box, myPyBox.rect)
6364
myPyBox.left = 200
6465
time.sleep(timelap)
@@ -175,7 +176,7 @@ def demo():
175176
a.setDelegate_(delegate)
176177

177178
# Now we can start to create the window ...
178-
frame = NSMakeRect(400, 400, 250, 100)
179+
frame = NSMakeRect(400, 400, 250, 128)
179180
# (Don't worry about these parameters for the moment. They just specify
180181
# the type of window, its size and position etc)
181182
mask = NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | NSWindowStyleMaskResizable

tests/test_pywinbox.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,10 +141,10 @@ def test_basic():
141141
print(npw.box, npw.rect)
142142
assert npw.height == 500
143143

144-
myPyBox.size = (801, 601)
144+
myPyBox.size = (301, 301)
145145
time.sleep(timelap)
146146
print(npw.box, npw.rect)
147-
assert npw.size == (801, 601)
147+
assert npw.size == (301, 301)
148148

149149
# Test closing
150150
npw.close()

0 commit comments

Comments
 (0)