Files
timka123 77b26757bf refactor: enhance TimerPage layout and functionality; update theme and tokens for improved design consistency
- Refactored TimerPage component to improve layout and user experience.
- Updated theme configuration to utilize design tokens for better maintainability.
- Introduced new tokens for colors and typography to align with design principles.
- Simplified state management and improved timer functionality.
- Enhanced accessibility and responsiveness of UI elements.
2026-10-18 23:57:36 +03:00

79 lines
2.2 KiB
Python

"""Where the mini timer appears.
Two mechanisms, because one is not enough:
* **X11** — the application may place its own window, so the computed point is
applied directly.
* **Wayland** — it may not: a client cannot position an xdg-toplevel, and
setting `x`/`y` is quietly ignored. KWin *can* place it, through the same
window rule that already forces "keep above", so the point is written there.
The geometry maths is a pure function so it can be checked without a screen.
"""
from __future__ import annotations
from dataclasses import dataclass
CORNERS = (
"top-left",
"top-centre",
"top-right",
"bottom-left",
"bottom-centre",
"bottom-right",
"centre",
"remember",
)
# What the settings page shows, in the order it shows them.
CORNER_LABELS = {
"top-left": "Top left",
"top-centre": "Top centre",
"top-right": "Top right",
"bottom-left": "Bottom left",
"bottom-centre": "Bottom centre",
"bottom-right": "Bottom right",
"centre": "Centre of the screen",
"remember": "Where I last dragged it",
}
@dataclass(frozen=True, slots=True)
class Rect:
"""A screen's usable area — panels and docks already taken off."""
x: int
y: int
width: int
height: int
def point_for(corner: str, screen: Rect, size: tuple[int, int], margin: int = 24) -> tuple[int, int]:
"""Top-left point that puts a `size` window in `corner` of `screen`."""
width, height = size
margin = max(0, margin)
vertical, _, horizontal = corner.partition("-")
if corner == "centre":
vertical, horizontal = "centre", "centre"
if horizontal == "left":
x = screen.x + margin
elif horizontal == "right":
x = screen.x + screen.width - width - margin
else: # centre
x = screen.x + (screen.width - width) // 2
if vertical == "top":
y = screen.y + margin
elif vertical == "bottom":
y = screen.y + screen.height - height - margin
else: # centre
y = screen.y + (screen.height - height) // 2
# Never place it off-screen, however small the screen or large the margin.
x = max(screen.x, min(x, screen.x + max(screen.width - width, 0)))
y = max(screen.y, min(y, screen.y + max(screen.height - height, 0)))
return int(x), int(y)