Merge branch 'beeware:main' into contribute-code-towncrier
This commit is contained in:
commit
73d7dccd4b
11 changed files with 78 additions and 33 deletions
3
.github/workflows/publish.yml
vendored
3
.github/workflows/publish.yml
vendored
|
|
@ -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"
|
||||
|
|
|
|||
4
.github/workflows/release.yml
vendored
4
.github/workflows/release.yml
vendored
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
GTK and Windows MapViews have maxZoom of 20, as per the docs.
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
==================
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
---------
|
||||
|
|
|
|||
|
|
@ -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"},
|
||||
]
|
||||
)
|
||||
|
|
|
|||
|
|
@ -99,4 +99,5 @@ Wayland
|
|||
WebKit
|
||||
whitespace
|
||||
Winforms
|
||||
Xcode
|
||||
zoomable
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue