Skip to content

Commit

Permalink
Merge branch 'beeware:main' into iOS_transparency_fix
Browse files Browse the repository at this point in the history
  • Loading branch information
proneon267 authored Dec 23, 2024
2 parents ae30d17 + b25b4e3 commit a71325c
Show file tree
Hide file tree
Showing 93 changed files with 2,881 additions and 3,480 deletions.
18 changes: 10 additions & 8 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ jobs:
mv core/.coverage core/.coverage.${{ matrix.platform }}.${{ matrix.python-version }}
- name: Store Coverage Data
uses: actions/upload-artifact@v4.4.3
uses: actions/upload-artifact@v4.5.0
with:
name: core-coverage-data-${{ matrix.platform }}-${{ matrix.python-version }}
path: "core/.coverage.*"
Expand Down Expand Up @@ -218,7 +218,7 @@ jobs:
run: tox -e coverage-html-fail-platform

- name: Upload HTML Coverage Report
uses: actions/upload-artifact@v4.4.3
uses: actions/upload-artifact@v4.5.0
if: failure()
with:
name: html-coverage-report
Expand Down Expand Up @@ -264,7 +264,7 @@ jobs:
- backend: "linux-x11"
platform: "linux"
runs-on: "ubuntu-24.04"
# The package list should be the same as in tutorial-0.rst, and the BeeWare
# The package list should be the same as in unix-prerequisites.rst, and the BeeWare
# tutorial, plus blackbox to provide a window manager. We need a window
# manager that is reasonably lightweight, honors full screen mode, and
# treats the window position as the top-left corner of the *window*, not the
Expand All @@ -275,7 +275,7 @@ jobs:
sudo apt update -y
sudo apt install -y --no-install-recommends \
blackbox pkg-config python3-dev libgirepository1.0-dev libcairo2-dev \
gir1.2-webkit2-4.1 gir1.2-xapp-1.0
gir1.2-webkit2-4.1 gir1.2-xapp-1.0 gir1.2-geoclue-2.0 gir1.2-flatpak-1.0
# Start Virtual X Server
echo "Start X server..."
Expand All @@ -293,13 +293,13 @@ jobs:
- backend: "linux-wayland"
platform: "linux"
runs-on: "ubuntu-24.04"
# The package list should be the same as in tutorial-0.rst, and the BeeWare
# The package list should be the same as in unix-prerequisites.rst, and the BeeWare
# tutorial, plus mutter to provide a window manager.
pre-command: |
sudo apt update -y
sudo apt install -y --no-install-recommends \
mutter pkg-config python3-dev libgirepository1.0-dev libcairo2-dev \
gir1.2-webkit2-4.1 gir1.2-xapp-1.0
gir1.2-webkit2-4.1 gir1.2-xapp-1.0 gir1.2-geoclue-2.0 gir1.2-flatpak-1.0
# Start Virtual X Server
echo "Start X server..."
Expand All @@ -323,6 +323,8 @@ jobs:
setup-python: false # Use the system Python packages
briefcase-run-args: --config 'requires=["../core","../textual"]' --config 'console_app=true'
app-user-data-path: "$HOME/.local/share/testbed"
# install the meta-package build-essential since Briefcase explicitly checks for it
pre-command: sudo apt update -y && sudo apt install -y build-essential

- backend: "textual-macOS"
platform: "macOS"
Expand Down Expand Up @@ -398,7 +400,7 @@ jobs:
briefcase run ${{ matrix.platform }} --log --test ${{ matrix.briefcase-run-args }} -- --ci
- name: Upload Logs
uses: actions/upload-artifact@v4.4.3
uses: actions/upload-artifact@v4.5.0
if: failure()
with:
name: testbed-failure-logs-${{ matrix.backend }}
Expand All @@ -411,7 +413,7 @@ jobs:
cp -r "${{ matrix.app-user-data-path }}" testbed/app_data/testbed-app_data-${{ matrix.backend }}
- name: Upload App Data
uses: actions/upload-artifact@v4.4.3
uses: actions/upload-artifact@v4.5.0
if: failure() && matrix.backend != 'android'
with:
name: testbed-failure-app-data-${{ matrix.backend }}
Expand Down
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ repos:
- id: end-of-file-fixer
- id: trailing-whitespace
- repo: https://github.com/asottile/pyupgrade
rev: v3.19.0
rev: v3.19.1
hooks:
- id: pyupgrade
args: [--py39-plus]
Expand Down
8 changes: 8 additions & 0 deletions android/src/toga_android/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,10 @@ def set_current_window(self, window):
# Platform-specific APIs
######################################################################

######################################################################
# 2024-2: Backwards compatibility for < 0.4.1
######################################################################

async def intent_result(self, intent): # pragma: no cover
warnings.warn(
"intent_result has been deprecated; use start_activity",
Expand All @@ -345,6 +349,10 @@ def complete_handler(code, data):
except AttributeError:
raise RuntimeError("No appropriate Activity found to handle this intent.")

######################################################################
# End backwards compatibility
######################################################################

def _native_startActivityForResult(
self, activity, code, *options
): # pragma: no cover
Expand Down
3 changes: 2 additions & 1 deletion android/src/toga_android/widgets/canvas.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
from java.io import ByteArrayOutputStream
from org.beeware.android import DrawHandlerView, IDrawHandler

from toga.widgets.canvas import Baseline, FillRule, arc_to_bezier, sweepangle
from toga.constants import Baseline, FillRule
from toga.widgets.canvas import arc_to_bezier, sweepangle

from ..colors import native_color
from .base import Widget
Expand Down
9 changes: 9 additions & 0 deletions android/tests_backend/hardware/location.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@


class LocationProbe(HardwareProbe):
supports_background_permission = True

def __init__(self, monkeypatch, app_probe):
super().__init__(monkeypatch, app_probe.app)

Expand Down Expand Up @@ -100,3 +102,10 @@ async def simulate_location_error(self, location):
await self.redraw("Wait for location error")

pytest.xfail("Android's location service doesn't raise errors on failure")

def setup_location_error(self):
# location error simulation handled by ``simulate_location_error``
pass

def setup_tracking_start_error(self):
pytest.xfail("Tracking start cannot fail on Android")
43 changes: 36 additions & 7 deletions android/tests_backend/window.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import asyncio

from android.content import Context
from androidx.appcompat import R as appcompat_R

from toga.constants import WindowState

from .dialogs import DialogsMixin
from .probe import BaseProbe

Expand All @@ -18,14 +22,39 @@ def __init__(self, app, window):
async def wait_for_window(
self,
message,
minimize=False,
full_screen=False,
state_switch_not_from_normal=False,
state=None,
):
await self.redraw(
message,
delay=(0.5 if (full_screen or state_switch_not_from_normal) else 0.1),
)
await self.redraw(message, delay=0.1)
if state:
timeout = 5
polling_interval = 0.1
exception = None
loop = asyncio.get_running_loop()
start_time = loop.time()
while (loop.time() - start_time) < timeout:
try:
assert self.instantaneous_state == state
if state in {WindowState.FULLSCREEN, WindowState.PRESENTATION}:
# Add a slight delay to ensure window properties like
# `content_size` are updated according to the new state.
await self.redraw(delay=0.1)
return
except AssertionError as e:
exception = e
await asyncio.sleep(polling_interval)
continue
raise exception

async def cleanup(self):
# Store the pre closing window state as determination of
# window state after closing the window is unreliable.
pre_close_window_state = self.window.state
self.window.close()
if pre_close_window_state in {WindowState.FULLSCREEN, WindowState.PRESENTATION}:
delay = 0.5
else:
delay = 0.1
await self.redraw("Closing window", delay=delay)

@property
def content_size(self):
Expand Down
1 change: 1 addition & 0 deletions changes/1943.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Added the ``gap`` style, which adds space between adjacent children of a box.
1 change: 1 addition & 0 deletions changes/2990.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Toga GTK now supports location services via integration with GeoClue and the XDG Location Portal.
1 change: 1 addition & 0 deletions changes/3040.misc.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Updated pytest-freezer from 0.4.8 to 0.4.9 in /core.
1 change: 1 addition & 0 deletions changes/3044.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
The ``Pack.margin`` property (and its deprecated alias, ``padding``) can now be accessed via bracket notation, as in ``style["margin"]``. (Previously this worked for the "sub-properties" of ``margin_top`` etc., but not for ``margin``/``padding`` itself.)
1 change: 1 addition & 0 deletions changes/3044.misc.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
An issue with PR #3033 that allowed bracket access of invalid style names on a Pack object has been fixed.
1 change: 1 addition & 0 deletions changes/3047.misc.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
The `wait_for_window()` window probe method, now has a polling based waiting mechanism.
1 change: 1 addition & 0 deletions changes/3048.misc.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
An issue with PR #3033 that failed when providing ``padding`` to ``Pack()`` and ``Pack.update()`` was fixed.
1 change: 1 addition & 0 deletions changes/3051.misc.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
The meta-package build-essential is installed for running testbed for textual on Linux since ubuntu-24.04 doesn't include it and Briefcase explicitly checks for it.
1 change: 1 addition & 0 deletions changes/3053.misc.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
The ``Canvas`` widget has been split up from a single module into a subpackage.
1 change: 1 addition & 0 deletions changes/3055.misc.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ChariotGazer app has been added to Toga success stories.
1 change: 1 addition & 0 deletions changes/3057.misc.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Updated actions/upload-artifact from 4.4.3 to 4.5.0.
1 change: 1 addition & 0 deletions changes/3058.misc.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
The ``pre-commit`` hook for ``pyupgrade`` was updated to its latest version.
1 change: 1 addition & 0 deletions changes/3059.removal.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Deprecations from 0.4.0 and earlier have been removed.
1 change: 1 addition & 0 deletions changes/3060.misc.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Updated sphinxcontrib-spelling from 8.0.0 to 8.0.1 in /core.
2 changes: 0 additions & 2 deletions cocoa/src/toga_cocoa/libs/appkit.py
Original file line number Diff line number Diff line change
Expand Up @@ -626,9 +626,7 @@ class NSLineBreakMode(Enum):

NSStringDrawingUsesLineFragmentOrigin = 1 << 0
NSStringDrawingUsesFontLeading = 1 << 1
NSStringDrawingDisableScreenFontSubstitution = 1 << 2 # DEPRECATED
NSStringDrawingUsesDeviceMetrics = 1 << 3
NSStringDrawingOneShot = 1 << 4 # DEPRECATED
NSStringDrawingTruncatesLastVisibleLine = 1 << 5

######################################################################
Expand Down
2 changes: 1 addition & 1 deletion cocoa/src/toga_cocoa/widgets/canvas.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from travertino.size import at_least

from toga.colors import BLACK, TRANSPARENT, color
from toga.widgets.canvas import Baseline, FillRule
from toga.constants import Baseline, FillRule
from toga_cocoa.colors import native_color
from toga_cocoa.libs import (
CGFloat,
Expand Down
10 changes: 10 additions & 0 deletions cocoa/tests_backend/hardware/location.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from unittest.mock import Mock, PropertyMock

import pytest
from rubicon.objc import ObjCClass

from toga_cocoa import libs as cocoa
Expand All @@ -16,6 +17,8 @@


class LocationProbe(AppProbe):
supports_background_permission = True

def __init__(self, monkeypatch, app_probe):
super().__init__(app_probe.app)

Expand Down Expand Up @@ -173,3 +176,10 @@ async def simulate_location_error(self, location):
)

return await location

def setup_location_error(self):
# location error simulation handled by ``simulate_location_error``
pass

def setup_tracking_start_error(self):
pytest.xfail("Tracking start cannot fail on macOS")
50 changes: 39 additions & 11 deletions cocoa/tests_backend/window.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import asyncio

from rubicon.objc import objc_id, send_message

from toga.constants import WindowState
from toga_cocoa.libs import NSWindow, NSWindowStyleMask

from .dialogs import DialogsMixin
Expand All @@ -25,18 +28,43 @@ def __init__(self, app, window):
async def wait_for_window(
self,
message,
minimize=False,
full_screen=False,
state_switch_not_from_normal=False,
state=None,
):
await self.redraw(
message,
delay=(
1.75
if state_switch_not_from_normal
else 0.75 if full_screen else 0.5 if minimize else 0.1
),
)
await self.redraw(message, delay=0.1)

if state:
timeout = 5
polling_interval = 0.1
exception = None
loop = asyncio.get_running_loop()
start_time = loop.time()
while (loop.time() - start_time) < timeout:
try:
assert self.instantaneous_state == state
assert self.window._impl._pending_state_transition is None
return
except AssertionError as e:
exception = e
await asyncio.sleep(polling_interval)
continue
raise exception

async def cleanup(self):
# Store the pre closing window state as determination of
# window state after closing the window is unreliable.
pre_close_window_state = self.window.state
self.window.close()
# We need to use fixed length delays here as NSWindow.close() is
# non-blocking in nature, and NSWindow doesn't provide a reliable
# indicator to indicate completion of all operations related to
# window closing.
if pre_close_window_state == WindowState.FULLSCREEN:
delay = 1
elif pre_close_window_state == WindowState.MINIMIZED:
delay = 0.5
else:
delay = 0.1
await self.redraw("Closing window", delay=delay)

def close(self):
self.native.performClose(None)
Expand Down
4 changes: 2 additions & 2 deletions core/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ dev = [
"pre-commit == 4.0.1",
"pytest == 8.3.4",
"pytest-asyncio == 0.25.0",
"pytest-freezer == 0.4.8",
"pytest-freezer == 0.4.9",
"setuptools-scm == 8.1.0",
"tox == 4.23.2",
# typing-extensions needed for TypeAlias added in Py 3.10
Expand All @@ -87,7 +87,7 @@ docs = [
"sphinx-csv-filter == 0.4.2",
"sphinx-copybutton == 0.5.2",
"sphinx-toolbox == 3.8.1",
"sphinxcontrib-spelling == 8.0.0",
"sphinxcontrib-spelling == 8.0.1",
]

[project.urls]
Expand Down
Loading

0 comments on commit a71325c

Please sign in to comment.