Merge branch 'beeware:main' into contribute-code-towncrier

This commit is contained in:
Marcos Dione 2024-05-09 11:39:07 +02:00 committed by GitHub
commit 73d7dccd4b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 78 additions and 33 deletions

View file

@ -11,6 +11,9 @@ jobs:
# This permission is required for trusted publishing.
id-token: write
strategy:
# One element of this matrix failing should not terminate the others mid-run.
# This prevents one bad platform from stalling the publication of others.
fail-fast: false
matrix:
package:
- "toga"

View file

@ -49,7 +49,11 @@ jobs:
permissions:
# This permission is required for trusted publishing.
id-token: write
continue-on-error: true
strategy:
# One element of this matrix failing should not terminate the others mid-run.
# This prevents one bad platform from stalling the publication of others.
fail-fast: false
matrix:
package:
- "toga"

View file

@ -1 +0,0 @@
GTK and Windows MapViews have maxZoom of 20, as per the docs.

View file

@ -16,13 +16,20 @@ class Icon:
if path is None:
# Look to the app bundle, and get the icon. Set self.path as None
# as an indicator that this is the app's default icon.
# This bundle icon file definition might not contain an extension,
# even thought the actual file will; so force the .icns extension.
bundle_icon = Path(
NSBundle.mainBundle.objectForInfoDictionaryKey("CFBundleIconFile")
)
path = NSBundle.mainBundle.pathForResource(
bundle_icon.stem,
ofType=bundle_icon.suffix,
ofType=".icns",
)
# If the icon file doesn't exist, raise the problem as FileNotFoundError
# This can't be tested, as the app will always have an icon.
if not Path(path).is_file():
raise FileNotFoundError() # pragma: no cover
self.path = None
else:
self.path = path

View file

@ -91,11 +91,12 @@ class Icon:
path, or a path relative to the module that defines your Toga application
class. This base filename should *not* contain an extension. If an extension
is specified, it will be ignored. If the icon cannot be found, the default
icon will be :attr:`~toga.Icon.DEFAULT_ICON`.
icon will be :attr:`~toga.Icon.DEFAULT_ICON`. If an icon file is found, but
it cannot be loaded (due to a file format or permission error), an exception
will be raised.
:param system: **For internal use only**
"""
self.factory = get_platform_factory()
try:
# Try to load the icon with the given path snippet. If the request is for the
# app icon, use ``resources/<app name>`` as the path.
@ -131,7 +132,7 @@ class Icon:
self._impl = self.factory.Icon(interface=self, path=full_path)
except FileNotFoundError:
# Icon path couldn't be loaded. If the path is the sentinel for the app
# Icon path couldn't be found. If the path is the sentinel for the app
# icon, and this isn't running as a script, fall back to the application
# binary
if path is _APP_ICON:

View file

@ -113,8 +113,15 @@ def test_create(monkeypatch, app, path, system, sizes, extensions, final_paths):
assert icon._impl.path == final_paths
def test_create_fallback(app, capsys):
def test_create_fallback_missing(monkeypatch, app, capsys):
"""If a resource doesn't exist, a fallback icon is used."""
# Prime the dummy so the app icon cannot be loaded
monkeypatch.setattr(
DummyIcon,
"ICON_FAILURE",
FileNotFoundError(),
)
icon = toga.Icon("resources/missing")
assert icon._impl is not None
@ -127,6 +134,19 @@ def test_create_fallback(app, capsys):
)
def test_create_fallback_unloadable(monkeypatch, app, capsys):
"""If a resource exists, but can't be loaded, an error is raised."""
# Prime the dummy so the app icon cannot be loaded
monkeypatch.setattr(
DummyIcon,
"ICON_FAILURE",
ValueError("Icon could not be loaded"),
)
with pytest.raises(ValueError):
toga.Icon("resources/sample")
def test_create_fallback_variants(monkeypatch, app, capsys):
"""If a resource with size variants doesn't exist, a fallback icon is used."""
monkeypatch.setattr(DummyIcon, "SIZES", [32, 72])
@ -164,7 +184,7 @@ def test_create_app_icon(monkeypatch, app, capsys):
def test_create_app_icon_missing(monkeypatch, app, capsys):
"""The app icon can be constructed"""
"""If the app icon is missing, a fallback is used"""
# When running under pytest, code will identify as running as a script
# Load the app default icon.
@ -196,9 +216,13 @@ def test_create_app_icon_non_script(monkeypatch, app, capsys):
def test_create_app_icon_missing_non_script(monkeypatch, app, capsys):
"""The binary executableThe app icon can be reset to the default"""
# Prime the dummy so the app icon cannot be loaded
monkeypatch.setattr(DummyIcon, "ICON_EXISTS", False)
"""If the icon from binary executable cannot be found, the app icon is reset to the default"""
# Prime the dummy so the app icon cannot be found
monkeypatch.setattr(
DummyIcon,
"ICON_FAILURE",
FileNotFoundError(),
)
# Patch sys.executable so the test looks like it's running as a packaged binary
monkeypatch.setattr(sys, "executable", "/path/to/App")

View file

@ -6,6 +6,19 @@ Release History
.. towncrier release notes start
0.4.4 (2024-05-08)
==================
Bugfixes
--------
* The mechanism for loading application icons on macOS was corrected to account for how Xcode populates ``Info.plist`` metadata. (`#2558 <https://github.com/beeware/toga/issues/2558>`__)
Misc
----
* `#2555 <https://github.com/beeware/toga/issues/2555>`__, `#2557 <https://github.com/beeware/toga/issues/2557>`__, `#2560 <https://github.com/beeware/toga/issues/2560>`__
0.4.3 (2024-05-06)
==================
@ -23,7 +36,6 @@ Features
* A geolocation service was added for Android, iOS and macOS. (`#2462 <https://github.com/beeware/toga/issues/2462>`__)
* When a Toga app is packaged as a binary, and no icon is explicitly configured, Toga will now use the binary's icon as the app icon. This means it is no longer necessary to include the app icon as data in a ``resources`` folder if you are packaging your app for distribution. (`#2527 <https://github.com/beeware/toga/issues/2527>`__)
Bugfixes
--------
@ -40,13 +52,11 @@ Bugfixes
* Widget IDs can now be reused after the associated widget's window is closed. (`#2514 <https://github.com/beeware/toga/issues/2514>`__)
* :class:`~toga.WebView` is now compatible with Linux GTK environments only providing WebKit2 version 4.1 without version 4.0. (`#2527 <https://github.com/beeware/toga/issues/2527>`__)
Backward Incompatible Changes
-----------------------------
* The macOS implementations of ``Window.as_image()`` and ``Canvas.as_image()`` APIs now return images in native device resolution, not CSS pixel resolution. This will result in images that are double the previous size on Retina displays. (`#1930 <https://github.com/beeware/toga/issues/1930>`__)
Documentation
-------------
@ -58,13 +68,11 @@ Documentation
* An explicit system requirements section was added to the documentation for widgets that require the installation of additional system components. (`#2544 <https://github.com/beeware/toga/issues/2544>`__)
* The system requirements were updated to be more explicit and now include details for OpenSUSE Tumbleweed. (`#2549 <https://github.com/beeware/toga/issues/2549>`__)
Misc
----
* `#2153 <https://github.com/beeware/toga/issues/2153>`__, `#2372 <https://github.com/beeware/toga/issues/2372>`__, `#2389 <https://github.com/beeware/toga/issues/2389>`__, `#2390 <https://github.com/beeware/toga/issues/2390>`__, `#2391 <https://github.com/beeware/toga/issues/2391>`__, `#2392 <https://github.com/beeware/toga/issues/2392>`__, `#2393 <https://github.com/beeware/toga/issues/2393>`__, `#2394 <https://github.com/beeware/toga/issues/2394>`__, `#2396 <https://github.com/beeware/toga/issues/2396>`__, `#2397 <https://github.com/beeware/toga/issues/2397>`__, `#2400 <https://github.com/beeware/toga/issues/2400>`__, `#2403 <https://github.com/beeware/toga/issues/2403>`__, `#2405 <https://github.com/beeware/toga/issues/2405>`__, `#2406 <https://github.com/beeware/toga/issues/2406>`__, `#2407 <https://github.com/beeware/toga/issues/2407>`__, `#2408 <https://github.com/beeware/toga/issues/2408>`__, `#2409 <https://github.com/beeware/toga/issues/2409>`__, `#2422 <https://github.com/beeware/toga/issues/2422>`__, `#2423 <https://github.com/beeware/toga/issues/2423>`__, `#2427 <https://github.com/beeware/toga/issues/2427>`__, `#2440 <https://github.com/beeware/toga/issues/2440>`__, `#2442 <https://github.com/beeware/toga/issues/2442>`__, `#2445 <https://github.com/beeware/toga/issues/2445>`__, `#2448 <https://github.com/beeware/toga/issues/2448>`__, `#2449 <https://github.com/beeware/toga/issues/2449>`__, `#2450 <https://github.com/beeware/toga/issues/2450>`__, `#2457 <https://github.com/beeware/toga/issues/2457>`__, `#2458 <https://github.com/beeware/toga/issues/2458>`__, `#2459 <https://github.com/beeware/toga/issues/2459>`__, `#2460 <https://github.com/beeware/toga/issues/2460>`__, `#2464 <https://github.com/beeware/toga/issues/2464>`__, `#2465 <https://github.com/beeware/toga/issues/2465>`__, `#2466 <https://github.com/beeware/toga/issues/2466>`__, `#2467 <https://github.com/beeware/toga/issues/2467>`__, `#2470 <https://github.com/beeware/toga/issues/2470>`__, `#2471 <https://github.com/beeware/toga/issues/2471>`__, `#2476 <https://github.com/beeware/toga/issues/2476>`__, `#2487 <https://github.com/beeware/toga/issues/2487>`__, `#2488 <https://github.com/beeware/toga/issues/2488>`__, `#2498 <https://github.com/beeware/toga/issues/2498>`__, `#2501 <https://github.com/beeware/toga/issues/2501>`__, `#2502 <https://github.com/beeware/toga/issues/2502>`__, `#2503 <https://github.com/beeware/toga/issues/2503>`__, `#2504 <https://github.com/beeware/toga/issues/2504>`__, `#2509 <https://github.com/beeware/toga/issues/2509>`__, `#2518 <https://github.com/beeware/toga/issues/2518>`__, `#2519 <https://github.com/beeware/toga/issues/2519>`__, `#2520 <https://github.com/beeware/toga/issues/2520>`__, `#2521 <https://github.com/beeware/toga/issues/2521>`__, `#2522 <https://github.com/beeware/toga/issues/2522>`__, `#2523 <https://github.com/beeware/toga/issues/2523>`__, `#2532 <https://github.com/beeware/toga/issues/2532>`__, `#2533 <https://github.com/beeware/toga/issues/2533>`__, `#2534 <https://github.com/beeware/toga/issues/2534>`__, `#2535 <https://github.com/beeware/toga/issues/2535>`__, `#2536 <https://github.com/beeware/toga/issues/2536>`__, `#2537 <https://github.com/beeware/toga/issues/2537>`__, `#2538 <https://github.com/beeware/toga/issues/2538>`__, `#2539 <https://github.com/beeware/toga/issues/2539>`__, `#2540 <https://github.com/beeware/toga/issues/2540>`__, `#2541 <https://github.com/beeware/toga/issues/2541>`__, `#2542 <https://github.com/beeware/toga/issues/2542>`__, `#2546 <https://github.com/beeware/toga/issues/2546>`__, `#2552 <https://github.com/beeware/toga/issues/2552>`__
0.4.2 (2024-02-06)
==================
@ -106,7 +114,6 @@ Misc
* `#2298 <https://github.com/beeware/toga/issues/2298>`__, `#2299 <https://github.com/beeware/toga/issues/2299>`__, `#2302 <https://github.com/beeware/toga/issues/2302>`__, `#2312 <https://github.com/beeware/toga/issues/2312>`__, `#2313 <https://github.com/beeware/toga/issues/2313>`__, `#2318 <https://github.com/beeware/toga/issues/2318>`__, `#2331 <https://github.com/beeware/toga/issues/2331>`__, `#2332 <https://github.com/beeware/toga/issues/2332>`__, `#2333 <https://github.com/beeware/toga/issues/2333>`__, `#2336 <https://github.com/beeware/toga/issues/2336>`__, `#2337 <https://github.com/beeware/toga/issues/2337>`__, `#2339 <https://github.com/beeware/toga/issues/2339>`__, `#2340 <https://github.com/beeware/toga/issues/2340>`__, `#2357 <https://github.com/beeware/toga/issues/2357>`__, `#2358 <https://github.com/beeware/toga/issues/2358>`__, `#2359 <https://github.com/beeware/toga/issues/2359>`__, `#2363 <https://github.com/beeware/toga/issues/2363>`__, `#2367 <https://github.com/beeware/toga/issues/2367>`__, `#2368 <https://github.com/beeware/toga/issues/2368>`__, `#2369 <https://github.com/beeware/toga/issues/2369>`__, `#2370 <https://github.com/beeware/toga/issues/2370>`__, `#2371 <https://github.com/beeware/toga/issues/2371>`__, `#2375 <https://github.com/beeware/toga/issues/2375>`__, `#2376 <https://github.com/beeware/toga/issues/2376>`__
0.4.1 (2023-12-21)
==================
@ -319,7 +326,6 @@ Features
* The Web backend now uses Shoelace to provide web components. (`#1838 <https://github.com/beeware/toga/pull/1838>`__)
* Winforms apps can now go full screen. (`#1863 <https://github.com/beeware/toga/pull/1863>`__)
Bugfixes
--------
@ -332,7 +338,6 @@ Bugfixes
* The text alignment of MultilineTextInput on Android has been fixed to be TOP aligned. (`#1808 <https://github.com/beeware/toga/pull/1808>`__)
* GTK widgets that involve animation (such as Switch or ProgressBar) are now redrawn correctly. (`#1826 <https://github.com/beeware/toga/issues/1826>`__)
Improved Documentation
----------------------
@ -340,13 +345,11 @@ Improved Documentation
* Some missing settings and constant values were added to the documentation of Pack. (`#1786 <https://github.com/beeware/toga/pull/1786>`__)
* Added documentation for ``toga.App.widgets``. (`#1852 <https://github.com/beeware/toga/pull/1852>`__)
Misc
----
* `#1750 <https://github.com/beeware/toga/issues/1750>`__, `#1764 <https://github.com/beeware/toga/pull/1764>`__, `#1765 <https://github.com/beeware/toga/pull/1765>`__, `#1766 <https://github.com/beeware/toga/pull/1766>`__, `#1770 <https://github.com/beeware/toga/pull/1770>`__, `#1771 <https://github.com/beeware/toga/pull/1771>`__, `#1777 <https://github.com/beeware/toga/pull/1777>`__, `#1797 <https://github.com/beeware/toga/pull/1797>`__, `#1802 <https://github.com/beeware/toga/pull/1802>`__, `#1813 <https://github.com/beeware/toga/pull/1813>`__, `#1818 <https://github.com/beeware/toga/pull/1818>`__, `#1822 <https://github.com/beeware/toga/pull/1822>`__, `#1829 <https://github.com/beeware/toga/pull/1829>`__, `#1830 <https://github.com/beeware/toga/pull/1830>`__, `#1835 <https://github.com/beeware/toga/pull/1835>`__, `#1839 <https://github.com/beeware/toga/pull/1839>`__, `#1854 <https://github.com/beeware/toga/pull/1854>`__, `#1861 <https://github.com/beeware/toga/pull/1861>`__
0.3.0 (2023-01-30)
==================

View file

@ -71,9 +71,11 @@ icon variants that are not available from the highest resolution provided (e.g.,
128px variant can be found, one will be created by scaling the highest resolution
variant that *is* available).
An icon is **guaranteed** to have an implementation, regardless of the path
specified. If you specify a path and no matching icon can be found, Toga will
output a warning to the console, and return :attr:`~toga.Icon.DEFAULT_ICON`.
An icon is **guaranteed** to have an implementation, regardless of the path specified.
If you specify a path and no matching icon can be found, Toga will output a warning to
the console, and return :attr:`~toga.Icon.DEFAULT_ICON`. The only exception to this is
if an icon file is *found*, but it cannot be loaded (e.g., due to a file format or
permission error). In this case, an error will be raised.
Reference
---------

View file

@ -82,7 +82,7 @@ to control the display order of columns independent of the storage of that data.
headings=["Name", "Age"],
data=[
{"name": "Arthur Dent", "age": 42, "planet": "Earth"},
{"name", "Ford Prefect", "age": 37, "planet": "Betelgeuse Five"},
{"name": "Ford Prefect", "age": 37, "planet": "Betelgeuse Five"},
{"name": "Tricia McMillan", "age": 38, "planet": "Earth"},
]
)
@ -106,7 +106,7 @@ header, but internally, the attribute "character" will be used:
accessors={"Name", 'character'},
data=[
{"character": "Arthur Dent", "age": 42, "planet": "Earth"},
{"character", "Ford Prefect", "age": 37, "planet": "Betelgeuse Five"},
{"character": "Ford Prefect", "age": 37, "planet": "Betelgeuse Five"},
{"name": "Tricia McMillan", "age": 38, "planet": "Earth"},
]
)

View file

@ -99,4 +99,5 @@ Wayland
WebKit
whitespace
Winforms
Xcode
zoomable

View file

@ -2,18 +2,19 @@ from .utils import LoggedObject
class Icon(LoggedObject):
ICON_EXISTS = True
ICON_FAILURE = None
EXTENSIONS = [".png", ".ico"]
SIZES = None
def __init__(self, interface, path):
super().__init__()
self.interface = interface
if not self.ICON_EXISTS:
raise FileNotFoundError("Couldn't find icon")
elif path is None:
self.path = "<APP ICON>"
elif path == {}:
raise FileNotFoundError("No image variants found")
if self.ICON_FAILURE:
raise self.ICON_FAILURE
else:
self.path = path
if path is None:
self.path = "<APP ICON>"
elif path == {}:
raise FileNotFoundError("No image variants found")
else:
self.path = path