maskfits 2.0.0__tar.gz → 2.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. {maskfits-2.0.0 → maskfits-2.1.0}/PKG-INFO +1 -1
  2. {maskfits-2.0.0 → maskfits-2.1.0}/pyproject.toml +1 -1
  3. {maskfits-2.0.0 → maskfits-2.1.0}/src/maskfits/gui.py +25 -2
  4. {maskfits-2.0.0 → maskfits-2.1.0}/tests/test_window_sizing.py +15 -0
  5. {maskfits-2.0.0 → maskfits-2.1.0}/.gitignore +0 -0
  6. {maskfits-2.0.0 → maskfits-2.1.0}/LICENSE +0 -0
  7. {maskfits-2.0.0 → maskfits-2.1.0}/README.md +0 -0
  8. {maskfits-2.0.0 → maskfits-2.1.0}/src/maskfits/__init__.py +0 -0
  9. {maskfits-2.0.0 → maskfits-2.1.0}/src/maskfits/assets/icon.ico +0 -0
  10. {maskfits-2.0.0 → maskfits-2.1.0}/src/maskfits/assets/icon.png +0 -0
  11. {maskfits-2.0.0 → maskfits-2.1.0}/src/maskfits/automask.py +0 -0
  12. {maskfits-2.0.0 → maskfits-2.1.0}/src/maskfits/automask_window.py +0 -0
  13. {maskfits-2.0.0 → maskfits-2.1.0}/src/maskfits/binning.py +0 -0
  14. {maskfits-2.0.0 → maskfits-2.1.0}/src/maskfits/cli.py +0 -0
  15. {maskfits-2.0.0 → maskfits-2.1.0}/src/maskfits/colormaps.py +0 -0
  16. {maskfits-2.0.0 → maskfits-2.1.0}/src/maskfits/custom_themes.py +0 -0
  17. {maskfits-2.0.0 → maskfits-2.1.0}/src/maskfits/cuts_histogram.py +0 -0
  18. {maskfits-2.0.0 → maskfits-2.1.0}/src/maskfits/hotkeys_window.py +0 -0
  19. {maskfits-2.0.0 → maskfits-2.1.0}/src/maskfits/imagedata.py +0 -0
  20. {maskfits-2.0.0 → maskfits-2.1.0}/src/maskfits/layouts.py +0 -0
  21. {maskfits-2.0.0 → maskfits-2.1.0}/src/maskfits/masking.py +0 -0
  22. {maskfits-2.0.0 → maskfits-2.1.0}/src/maskfits/settings.py +0 -0
  23. {maskfits-2.0.0 → maskfits-2.1.0}/src/maskfits/settings_window.py +0 -0
  24. {maskfits-2.0.0 → maskfits-2.1.0}/src/maskfits/shortcuts.py +0 -0
  25. {maskfits-2.0.0 → maskfits-2.1.0}/src/maskfits/shortcuts_window.py +0 -0
  26. {maskfits-2.0.0 → maskfits-2.1.0}/src/maskfits/theme.py +0 -0
  27. {maskfits-2.0.0 → maskfits-2.1.0}/src/maskfits/theme_editor_window.py +0 -0
  28. {maskfits-2.0.0 → maskfits-2.1.0}/src/maskfits/update_check.py +0 -0
  29. {maskfits-2.0.0 → maskfits-2.1.0}/src/maskfits/update_dialog.py +0 -0
  30. {maskfits-2.0.0 → maskfits-2.1.0}/src/maskfits/widgets.py +0 -0
  31. {maskfits-2.0.0 → maskfits-2.1.0}/tests/test_automask.py +0 -0
  32. {maskfits-2.0.0 → maskfits-2.1.0}/tests/test_cli.py +0 -0
  33. {maskfits-2.0.0 → maskfits-2.1.0}/tests/test_colormaps.py +0 -0
  34. {maskfits-2.0.0 → maskfits-2.1.0}/tests/test_custom_themes.py +0 -0
  35. {maskfits-2.0.0 → maskfits-2.1.0}/tests/test_escape_does_not_close_dialogs.py +0 -0
  36. {maskfits-2.0.0 → maskfits-2.1.0}/tests/test_gui_options.py +0 -0
  37. {maskfits-2.0.0 → maskfits-2.1.0}/tests/test_gui_render.py +0 -0
  38. {maskfits-2.0.0 → maskfits-2.1.0}/tests/test_gui_shortcuts.py +0 -0
  39. {maskfits-2.0.0 → maskfits-2.1.0}/tests/test_hotkey_digit_sync.py +0 -0
  40. {maskfits-2.0.0 → maskfits-2.1.0}/tests/test_hotkeys_window.py +0 -0
  41. {maskfits-2.0.0 → maskfits-2.1.0}/tests/test_imagedata.py +0 -0
  42. {maskfits-2.0.0 → maskfits-2.1.0}/tests/test_masking.py +0 -0
  43. {maskfits-2.0.0 → maskfits-2.1.0}/tests/test_settings.py +0 -0
  44. {maskfits-2.0.0 → maskfits-2.1.0}/tests/test_shortcut_capture.py +0 -0
  45. {maskfits-2.0.0 → maskfits-2.1.0}/tests/test_shortcuts.py +0 -0
  46. {maskfits-2.0.0 → maskfits-2.1.0}/tests/test_shortcuts_window.py +0 -0
  47. {maskfits-2.0.0 → maskfits-2.1.0}/tests/test_theme.py +0 -0
  48. {maskfits-2.0.0 → maskfits-2.1.0}/tests/test_update_check.py +0 -0
  49. {maskfits-2.0.0 → maskfits-2.1.0}/tests/test_update_dialog.py +0 -0
  50. {maskfits-2.0.0 → maskfits-2.1.0}/tests/test_widgets.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: maskfits
3
- Version: 2.0.0
3
+ Version: 2.1.0
4
4
  Summary: A PySide6 GUI for masking pixels in FITS astronomical images.
5
5
  Project-URL: Homepage, https://github.com/jnpippert/maskfits
6
6
  Project-URL: Repository, https://github.com/jnpippert/maskfits
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "maskfits"
7
- version = "2.0.0"
7
+ version = "2.1.0"
8
8
  description = "A PySide6 GUI for masking pixels in FITS astronomical images."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -391,8 +391,20 @@ class MaskFitsApp(QMainWindow):
391
391
  return
392
392
  available = screen.availableGeometry()
393
393
  margin = 60
394
- width = min(preferred_w, max(available.width() - margin, 640))
395
- height = min(preferred_h, max(available.height() - margin, 480))
394
+ floor_w, floor_h = 640, 480
395
+ width = min(preferred_w, max(available.width() - margin, floor_w))
396
+ height = min(preferred_h, max(available.height() - margin, floor_h))
397
+ # Without an explicit minimum, QMainWindow refuses to shrink below
398
+ # whatever its layout naturally needs (sidebar + toolbar + panels),
399
+ # which can exceed a laptop's screen width. That's harmless on its
400
+ # own, but a window manager that later tries to maximize/resize the
401
+ # window to the real screen size and gets a bigger buffer back than
402
+ # it asked for can treat it as a protocol violation (observed as a
403
+ # Wayland "xdg_surface buffer does not match configured maximized
404
+ # state" fatal error under WSLg) - so cap the minimum explicitly to
405
+ # whatever we're willing to shrink to, rather than leave it to the
406
+ # layout's own (possibly larger) size hint.
407
+ self.setMinimumSize(floor_w, floor_h)
396
408
  self.resize(width, height)
397
409
  x = available.x() + (available.width() - width) // 2
398
410
  y = available.y() + (available.height() - height) // 2
@@ -2138,6 +2150,17 @@ def run_gui(paths: list[str], zoom: Optional[float] = None, mode: Optional[str]
2138
2150
  cuts: Optional[str] = None, colormap: Optional[str] = None, binning: Optional[int] = None,
2139
2151
  smooth: Optional[int] = None, extension: Optional[int] = None) -> int:
2140
2152
  _set_windows_app_id()
2153
+ if QApplication.instance() is None:
2154
+ # Must be set before the QApplication exists. Without this, a
2155
+ # fractional host display scale (e.g. Windows' 150% on a laptop,
2156
+ # relayed through WSLg's Wayland compositor) can get rounded to the
2157
+ # nearest integer factor and then re-applied on top of the
2158
+ # compositor's own scaling, making the window appear far larger
2159
+ # than the screen - PassThrough uses the exact reported factor
2160
+ # instead of rounding it.
2161
+ QApplication.setHighDpiScaleFactorRoundingPolicy(
2162
+ Qt.HighDpiScaleFactorRoundingPolicy.PassThrough
2163
+ )
2141
2164
  app = QApplication.instance() or QApplication(sys.argv)
2142
2165
  # The native per-platform style (macOS in particular) draws QSlider's
2143
2166
  # groove/sub-page/add-page/handle itself as a "complex control" and
@@ -73,3 +73,18 @@ def test_window_is_centered_on_the_available_geometry(qapp, monkeypatch):
73
73
  expected_y = (1040 - win.height()) // 2
74
74
  assert abs(win.x() - expected_x) <= 1
75
75
  assert abs(win.y() - expected_y) <= 1
76
+
77
+
78
+ def test_window_gets_an_explicit_minimum_size(qapp, monkeypatch):
79
+ """A window manager maximizing/resizing the window to the real screen
80
+ size must never get a bigger buffer back than it asked for - without an
81
+ explicit minimum, QMainWindow can refuse to shrink below whatever its
82
+ layout naturally needs, which triggered a Wayland protocol violation
83
+ under WSLg (see this file's module docstring)."""
84
+ win = MaskFitsApp([], settings=Settings())
85
+ monkeypatch.setattr(win, "screen", lambda: _FakeScreen(QRect(0, 0, 1920, 1040)))
86
+
87
+ win._size_to_screen(1400, 980)
88
+
89
+ assert win.minimumWidth() <= 640
90
+ assert win.minimumHeight() <= 480
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes