Skip to content

Commit

Permalink
ALL: Added getAllWindowsDict() general function. Added getPID() method.
Browse files Browse the repository at this point in the history
LINUX: Added bad window filter to check for window.id == 0
  • Loading branch information
Kalmat committed Sep 23, 2024
1 parent 3a04edf commit 8f09ab3
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 33 deletions.
15 changes: 14 additions & 1 deletion src/pywinctl/_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import time
from abc import ABC, abstractmethod
from collections.abc import Callable
from typing import Any, cast, List, Tuple, Union
from typing import Any, cast, List, Tuple, Union, TypedDict

from pymonctl import findMonitorsAtPoint, getAllMonitors, getAllMonitorsDict, getMousePos as getMouse
from pywinbox import PyWinBox, Box, Rect, Point, Size
Expand Down Expand Up @@ -992,6 +992,19 @@ def displayWindowsUnderMouse(xOffset: int = 0, yOffset: int = 0) -> None:
sys.stdout.flush()


class _WINDATA(TypedDict):
id: Union[int, tuple[str, str]]
display: list[str]
position: tuple[int, int]
size: tuple[int, int]
status: int


class _WINDICT(TypedDict):
pid: int
windows: dict[str, _WINDATA]


if sys.platform == "darwin":
from ._pywinctl_macos import (MacOSWindow as Window, checkPermissions, getActiveWindow,
getActiveWindowTitle, getAllAppsNames, getAllAppsWindowsTitles,
Expand Down
19 changes: 9 additions & 10 deletions src/pywinctl/_pywinctl_linux.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
import Xlib.ext
from Xlib.xobject.drawable import Window as XWindow

from ._main import BaseWindow, Re, _WatchDog, _findMonitorName
from ._main import BaseWindow, Re, _WatchDog, _findMonitorName, _WINDATA, _WINDICT
from ewmhlib import EwmhWindow, EwmhRoot, defaultEwmhRoot, Props
from ewmhlib._ewmhlib import _xlibGetAllWindows

Expand Down Expand Up @@ -264,7 +264,7 @@ def getAllAppsWindowsTitles():
return result


def getAllWindowsDict(tryToFilter: bool = False) -> dict[str, int | dict[str, int | dict[str, str | dict[str, int | Point | Size | str]]]]:
def getAllWindowsDict(tryToFilter: bool = False) -> dict[str, _WINDICT]:
"""
Get all visible apps and windows info
Expand All @@ -284,7 +284,7 @@ def getAllWindowsDict(tryToFilter: bool = False) -> dict[str, int | dict[str, in
:param tryToFilter: Windows ONLY. Set to ''True'' to try to get User (non-system) apps only (may skip real user apps)
:return: python dictionary
"""
result: dict[str, int | dict[str, int | dict[str, str | dict[str, int | Point | Size | str]]]] = {}
result: dict[str, _WINDICT] = {}
for win in getAllWindows():
winId = win.getHandle()
appName = win.getAppName()
Expand All @@ -294,18 +294,17 @@ def getAllWindowsDict(tryToFilter: bool = False) -> dict[str, int | dict[str, in
status = 1
elif win.isMaximized:
status = 2
winDict = {
pos = win.position
size = win.size
winDict: _WINDATA = {
"id": winId,
"display": win.getDisplay(),
"position": win.position,
"size": win.size,
"position": (pos.x, pos.y),
"size": (size.width, size.height),
"status": status
}
if appName not in result.keys():
result[appName] = {}
result[appName]["pìd"] = appPID
if "windows" not in result[appName].keys():
result[appName]["windows"] = {}
result[appName] = {"pid": appPID, "windows": {}}
result[appName]["windows"][win.title] = winDict
return result

Expand Down
19 changes: 8 additions & 11 deletions src/pywinctl/_pywinctl_macos.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import AppKit
import Quartz

from ._main import BaseWindow, Re, _WatchDog, _findMonitorName
from ._main import BaseWindow, Re, _WatchDog, _findMonitorName, _WINDATA, _WINDICT
from pywinbox import Size, Point, Rect, pointInBox


Expand Down Expand Up @@ -311,7 +311,7 @@ def getAllAppsWindowsTitles():
return result


def getAllWindowsDict(tryToFilter: bool = False) -> dict[str, int | dict[str, int | dict[str, str | dict[str, int | Point | Size | str]]]]:
def getAllWindowsDict(tryToFilter: bool = False) -> dict[str, _WINDICT]:
"""
Get all visible apps and windows info
Expand Down Expand Up @@ -343,7 +343,7 @@ def getAllWindowsDict(tryToFilter: bool = False) -> dict[str, int | dict[str, in
.replace('missing value', '"missing value"') \
.replace("{", "[").replace("}", "]")
res = ast.literal_eval(ret)
result: dict[str, int | dict[str, int | dict[str, str | dict[str, int | Point | Size | str]]]] = {}
result: dict[str, _WINDICT] = {}
if len(res) > 0:
pids = res[0]
apps = res[1]
Expand All @@ -362,19 +362,16 @@ def getAllWindowsDict(tryToFilter: bool = False) -> dict[str, int | dict[str, in
status = 1
elif win.isMaximized:
status = 2
display = win.getDisplay()
if appName not in result.keys():
result[appName] = {}
result[appName]["pid"] = pID
if "windows" not in result[appName].keys():
result[appName]["windows"] = {}
result[appName]["windows"][title] = {
winDict: _WINDATA = {
"id": winId,
"display": display,
"display": win.getDisplay(),
"position": pos[j],
"size": sizes[j],
"status": status
}
if appName not in result.keys():
result[appName] = {"pid": pID, "windows": {}}
result[appName]["windows"][title] = winDict
break
return result

Expand Down
23 changes: 12 additions & 11 deletions src/pywinctl/_pywinctl_win.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
import win32api
import win32gui

from ._main import BaseWindow, Re, _WatchDog, _findMonitorName
from ._main import BaseWindow, Re, _WatchDog, _findMonitorName, _WINDATA, _WINDICT
from pywinbox import Size, Point, Rect, pointInBox

# WARNING: Changes are not immediately applied, specially for hide/show (unmap/map)
Expand Down Expand Up @@ -231,7 +231,7 @@ def getAllAppsWindowsTitles() -> dict[str, List[str]]:
return result


def getAllWindowsDict(tryToFilter: bool = False) -> dict[str, int | dict[str, int | dict[str, str | dict[str, int | Point | Size | str]]]]:
def getAllWindowsDict(tryToFilter: bool = False) -> dict[str, _WINDICT]:
"""
Get all visible apps and windows info
Expand All @@ -241,7 +241,9 @@ def getAllWindowsDict(tryToFilter: bool = False) -> dict[str, int | dict[str, in
Values:
"pid": app PID
"windows": subdictionary of all app windows
"title": subdictionary of window info
Key: window title
Values:
"id": window handle
"display": display in which window is mostly visible
"position": window position (x, y) within display
Expand All @@ -252,7 +254,7 @@ def getAllWindowsDict(tryToFilter: bool = False) -> dict[str, int | dict[str, in
:return: python dictionary
"""
process_list = _getAllApps(tryToFilter)
result: dict[str, int | dict[str, int | dict[str, str | dict[str, int | Point | Size | str]]]] = {}
result: dict[str, _WINDICT] = {}
for win in getAllWindows():
winId = win.getHandle()
pID = win32process.GetWindowThreadProcessId(winId)
Expand All @@ -265,18 +267,17 @@ def getAllWindowsDict(tryToFilter: bool = False) -> dict[str, int | dict[str, in
status = 1
elif win.isMaximized:
status = 2
winDict = {
pos = win.position
size = win.size
winDict: _WINDATA = {
"id": winId,
"display": win.getDisplay(),
"position": win.position,
"size": win.size,
"position": (pos.x, pos.y),
"size": (size.width, size.height),
"status": status
}
if appName not in result.keys():
result[appName] = {}
result[appName]["pìd"] = appPID
if "windows" not in result[appName].keys():
result[appName]["windows"] = {}
result[appName] = {"pid": appPID, "windows": {}}
result[appName]["windows"][win.title] = winDict
break
return result
Expand Down

0 comments on commit 8f09ab3

Please sign in to comment.