ttkbootstrap 2.2.0__tar.gz → 2.2.1__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 (163) hide show
  1. {ttkbootstrap-2.2.0/src/ttkbootstrap.egg-info → ttkbootstrap-2.2.1}/PKG-INFO +2 -2
  2. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/pyproject.toml +2 -2
  3. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/style/builders_tk.py +46 -3
  4. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1/src/ttkbootstrap.egg-info}/PKG-INFO +2 -2
  5. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/tests/test_menu_border.py +41 -3
  6. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/LICENSE +0 -0
  7. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/MANIFEST.in +0 -0
  8. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/README.md +0 -0
  9. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/setup.cfg +0 -0
  10. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/__init__.py +0 -0
  11. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/__init__.pyi +0 -0
  12. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/__main__.py +0 -0
  13. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/assets/__init__.py +0 -0
  14. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/assets/app_icons/ttkbootstrap.ico +0 -0
  15. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/assets/app_icons/ttkbootstrap.png +0 -0
  16. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/assets/elements/README.md +0 -0
  17. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/assets/elements/__init__.py +0 -0
  18. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/assets/elements/checkbox-checked.png +0 -0
  19. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/assets/elements/checkbox-indeterminate.png +0 -0
  20. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/assets/elements/checkbox-unchecked.png +0 -0
  21. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/assets/elements/manifest.json +0 -0
  22. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/assets/elements/progressbar-default.png +0 -0
  23. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/assets/elements/progressbar-thin.png +0 -0
  24. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/assets/elements/radio.png +0 -0
  25. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/assets/elements/sizegrip.png +0 -0
  26. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/assets/elements/slider-handle.png +0 -0
  27. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/assets/elements/slider-track.png +0 -0
  28. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/assets/elements/switch-round.png +0 -0
  29. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/assets/elements/switch-square.png +0 -0
  30. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/assets/icons/LICENSE +0 -0
  31. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/assets/icons/README.md +0 -0
  32. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/assets/icons/bootstrap.ttf +0 -0
  33. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/assets/icons/glyphmap.json +0 -0
  34. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/assets/icons/icon_metrics.json +0 -0
  35. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/cli.py +0 -0
  36. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/colorutils.py +0 -0
  37. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/constants.py +0 -0
  38. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/convert_theme.py +0 -0
  39. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/dialogs/__init__.py +0 -0
  40. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/dialogs/base.py +0 -0
  41. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/dialogs/colorchooser.py +0 -0
  42. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/dialogs/colordropper.py +0 -0
  43. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/dialogs/datepicker.py +0 -0
  44. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/dialogs/filedialog.py +0 -0
  45. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/dialogs/fontdialog.py +0 -0
  46. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/dialogs/message.py +0 -0
  47. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/dialogs/query.py +0 -0
  48. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/internal/__init__.py +0 -0
  49. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/internal/busy.py +0 -0
  50. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/internal/configure_delegation.py +0 -0
  51. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/internal/positioning.py +0 -0
  52. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/internal/publisher.py +0 -0
  53. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/internal/utility.py +0 -0
  54. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/internal/wheel.py +0 -0
  55. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/localization/README.md +0 -0
  56. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/localization/__init__.py +0 -0
  57. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/localization/api.py +0 -0
  58. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/localization/msgcat.py +0 -0
  59. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/localization/msgs.py +0 -0
  60. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/menu.py +0 -0
  61. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/publisher.py +0 -0
  62. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/py.typed +0 -0
  63. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/style/__init__.py +0 -0
  64. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/style/_compat.py +0 -0
  65. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/style/assets.py +0 -0
  66. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/style/bootstyle.py +0 -0
  67. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/style/builders/__init__.py +0 -0
  68. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/style/builders/button.py +0 -0
  69. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/style/builders/calendar.py +0 -0
  70. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/style/builders/checkbutton.py +0 -0
  71. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/style/builders/combobox.py +0 -0
  72. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/style/builders/entry.py +0 -0
  73. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/style/builders/floodgauge.py +0 -0
  74. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/style/builders/frame.py +0 -0
  75. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/style/builders/label.py +0 -0
  76. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/style/builders/labelframe.py +0 -0
  77. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/style/builders/menubutton.py +0 -0
  78. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/style/builders/notebook.py +0 -0
  79. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/style/builders/panedwindow.py +0 -0
  80. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/style/builders/progressbar.py +0 -0
  81. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/style/builders/radiobutton.py +0 -0
  82. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/style/builders/registry.py +0 -0
  83. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/style/builders/scale.py +0 -0
  84. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/style/builders/scrollbar.py +0 -0
  85. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/style/builders/separator.py +0 -0
  86. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/style/builders/sizegrip.py +0 -0
  87. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/style/builders/spinbox.py +0 -0
  88. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/style/builders/toggle.py +0 -0
  89. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/style/builders/toolbutton.py +0 -0
  90. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/style/builders/treeview.py +0 -0
  91. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/style/builders/utils.py +0 -0
  92. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/style/builders_ttk.py +0 -0
  93. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/style/elements.py +0 -0
  94. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/style/engine.py +0 -0
  95. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/style/icons.py +0 -0
  96. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/style/layout.py +0 -0
  97. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/style/scaling.py +0 -0
  98. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/style/theme.py +0 -0
  99. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/themes/__init__.py +0 -0
  100. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/themes/builtin.py +0 -0
  101. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/themes/legacy.py +0 -0
  102. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/themes/standard.py +0 -0
  103. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/utility.py +0 -0
  104. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/utils/__init__.py +0 -0
  105. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/utils/color.py +0 -0
  106. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/utils/config.py +0 -0
  107. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/utils/fonts.py +0 -0
  108. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/utils/platform.py +0 -0
  109. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/utils/scaling.py +0 -0
  110. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/validation.py +0 -0
  111. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/widgets/__init__.py +0 -0
  112. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/widgets/dateentry.py +0 -0
  113. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/widgets/floodgauge.py +0 -0
  114. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/widgets/labeledscale.py +0 -0
  115. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/widgets/meter.py +0 -0
  116. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/widgets/scrolled.py +0 -0
  117. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/widgets/tableview.py +0 -0
  118. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/widgets/toast.py +0 -0
  119. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/widgets/tooltip.py +0 -0
  120. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap/window.py +0 -0
  121. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap.egg-info/SOURCES.txt +0 -0
  122. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap.egg-info/dependency_links.txt +0 -0
  123. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap.egg-info/entry_points.txt +0 -0
  124. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap.egg-info/requires.txt +0 -0
  125. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkbootstrap.egg-info/top_level.txt +0 -0
  126. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkcreator/__init__.py +0 -0
  127. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/src/ttkcreator/__main__.py +0 -0
  128. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/tests/test_bootstyle_grammar.py +0 -0
  129. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/tests/test_bootstyle_value_tokens.py +0 -0
  130. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/tests/test_busy_api.py +0 -0
  131. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/tests/test_cli_api.py +0 -0
  132. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/tests/test_config_api.py +0 -0
  133. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/tests/test_configure_delegation.py +0 -0
  134. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/tests/test_convert_theme.py +0 -0
  135. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/tests/test_dateentry_api.py +0 -0
  136. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/tests/test_dialogs_api.py +0 -0
  137. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/tests/test_durable_style_options.py +0 -0
  138. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/tests/test_filedialog_api.py +0 -0
  139. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/tests/test_floodgauge_api.py +0 -0
  140. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/tests/test_fonts_api.py +0 -0
  141. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/tests/test_icon_drop.py +0 -0
  142. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/tests/test_icon_theme.py +0 -0
  143. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/tests/test_labeledscale_tooltip_api.py +0 -0
  144. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/tests/test_menu_api.py +0 -0
  145. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/tests/test_meter_api.py +0 -0
  146. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/tests/test_mixin_api.py +0 -0
  147. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/tests/test_scaling.py +0 -0
  148. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/tests/test_scroll_events.py +0 -0
  149. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/tests/test_scrolled_api.py +0 -0
  150. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/tests/test_style_package.py +0 -0
  151. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/tests/test_style_reference.py +0 -0
  152. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/tests/test_surface_color.py +0 -0
  153. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/tests/test_surface_families.py +0 -0
  154. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/tests/test_surface_grammar.py +0 -0
  155. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/tests/test_tableview_api.py +0 -0
  156. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/tests/test_toast_api.py +0 -0
  157. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/tests/test_toolkit.py +0 -0
  158. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/tests/test_treeview_rowheight.py +0 -0
  159. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/tests/test_utility_api.py +0 -0
  160. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/tests/test_widget_catalog_coverage.py +0 -0
  161. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/tests/test_widget_reexports.py +0 -0
  162. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/tests/test_widget_stubs.py +0 -0
  163. {ttkbootstrap-2.2.0 → ttkbootstrap-2.2.1}/tests/test_window_api.py +0 -0
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ttkbootstrap
3
- Version: 2.2.0
4
- Summary: A supercharged theme extension for tkinter that enables on-demand modern flat style themes inspired by Bootstrap.
3
+ Version: 2.2.1
4
+ Summary: Modern themes for Tkinter. Sleek, responsive styles inspired by Bootstrap. Includes ready-to-use widgets, 30+ themes, and tools for building beautiful, cross-platform desktop apps with ease.
5
5
  Author-email: Israel Dryer <israel.dryer@gmail.com>
6
6
  License-Expression: MIT AND (Apache-2.0 OR BSD-2-Clause)
7
7
  Project-URL: Homepage, https://github.com/israel-dryer/ttkbootstrap
@@ -4,8 +4,8 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "ttkbootstrap"
7
- version = "2.2.0"
8
- description = "A supercharged theme extension for tkinter that enables on-demand modern flat style themes inspired by Bootstrap."
7
+ version = "2.2.1"
8
+ description = "Modern themes for Tkinter. Sleek, responsive styles inspired by Bootstrap. Includes ready-to-use widgets, 30+ themes, and tools for building beautiful, cross-platform desktop apps with ease."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
11
11
  license = "MIT AND (Apache-2.0 OR BSD-2-Clause)"
@@ -13,6 +13,45 @@ from ttkbootstrap.style.theme import Colors, ThemeDefinition, _accent_on_color
13
13
  _MENU_HAIRLINE_TAG = "TtkbootstrapMenuHairline"
14
14
 
15
15
 
16
+ def _is_menubar(widget: tk.Menu) -> bool:
17
+ """True when `widget` is serving as a window's menubar.
18
+
19
+ Painting one floods the bar with the border color, because a menubar's
20
+ entries cover only its left. This used to be inferred from `<Map>` -- a
21
+ menubar is displayed through a clone, so the widget styled here did not map
22
+ -- but that is a property of the build, not a guarantee: on CI's x11 it does
23
+ map under CPython 3.13.15 and does not under 3.10.20, on the *same* Tk
24
+ (8.6.14), which painted every x11 menubar. Ask directly instead, so the
25
+ invariant no longer depends on what the interpreter and Tk happen to do.
26
+
27
+ Two ways to serve as a menubar, since either widget may be the one that maps:
28
+ the menu installed as some window's ``-menu``, or the clone Tk displays for
29
+ it (``-type menubar``; the original stays ``normal``).
30
+
31
+ The windows checked are the menu's own toplevel, the root, and the root's
32
+ direct children -- not a walk of the whole tree. A cascade posts its submenu
33
+ on every hover, so this runs at pointer speed and cannot afford to
34
+ instantiate a wrapper for every widget in the app. That covers a menubar
35
+ built on the window it serves, which is how one is written; a menu parented
36
+ to one window and installed on a *nested* toplevel would be missed.
37
+ """
38
+ if str(widget.cget("type")) == "menubar":
39
+ return True
40
+ name = str(widget)
41
+ root = widget._root()
42
+ windows = [widget.winfo_toplevel(), root]
43
+ windows.extend(
44
+ w for w in root.winfo_children() if isinstance(w, tk.Toplevel)
45
+ )
46
+ for window in windows:
47
+ try:
48
+ if str(window.cget("menu")) == name:
49
+ return True
50
+ except tk.TclError:
51
+ continue # not a window, or torn down mid-check
52
+ return False
53
+
54
+
16
55
  def _on_menu_map(event):
17
56
  """Repaint a popup menu's border as it is posted.
18
57
 
@@ -342,13 +381,17 @@ class StyleBuilderTK:
342
381
  popup, so only the 1px strip is left showing.
343
382
 
344
383
  That only holds for a popup. A menubar's entries cover just the left of
345
- the bar, so the border color would flood the rest of it -- which is why
346
- this waits for `<Map>`: a menu used as a menubar is displayed through a
347
- clone, so the widget styled here never maps and never gets painted.
384
+ the bar, so the border color would flood the rest of it -- so a menubar
385
+ is refused here, at the one place that paints, rather than at each
386
+ caller. Waiting for `<Map>` is still what defers a popup's paint until it
387
+ is posted; it is no longer what keeps a menubar out (see `_is_menubar`).
348
388
 
349
389
  Entry colors are theme-managed, like those of a themed `Text`. An entry
350
390
  the user gave its own color keeps it; the rest follow the theme.
351
391
  """
392
+ if _is_menubar(widget):
393
+ return
394
+
352
395
  surface = self.colors.bg
353
396
  previous = getattr(widget, "_tb_menu_entry_bg", None)
354
397
  widget.configure(background=self.colors.border)
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ttkbootstrap
3
- Version: 2.2.0
4
- Summary: A supercharged theme extension for tkinter that enables on-demand modern flat style themes inspired by Bootstrap.
3
+ Version: 2.2.1
4
+ Summary: Modern themes for Tkinter. Sleek, responsive styles inspired by Bootstrap. Includes ready-to-use widgets, 30+ themes, and tools for building beautiful, cross-platform desktop apps with ease.
5
5
  Author-email: Israel Dryer <israel.dryer@gmail.com>
6
6
  License-Expression: MIT AND (Apache-2.0 OR BSD-2-Clause)
7
7
  Project-URL: Homepage, https://github.com/israel-dryer/ttkbootstrap
@@ -16,10 +16,12 @@ against real pixels on X11 (``xwd`` capture of a posted menu, all four edges
16
16
  reading exactly ``colors.border``); a headless suite cannot post and capture.
17
17
  """
18
18
 
19
+ from types import SimpleNamespace
20
+
19
21
  import pytest
20
22
 
21
23
  import ttkbootstrap as ttk
22
- from ttkbootstrap.style.builders_tk import _MENU_HAIRLINE_TAG
24
+ from ttkbootstrap.style.builders_tk import _MENU_HAIRLINE_TAG, _on_menu_map
23
25
  from ttkbootstrap.style.scaling import Scaling
24
26
 
25
27
 
@@ -87,19 +89,55 @@ def test_a_never_posted_menu_is_not_painted(root, x11):
87
89
  """The guard that keeps a menubar intact.
88
90
 
89
91
  A menubar's entries cover only the left of the bar, so painting it would
90
- flood the rest with the border color. Tk displays a menubar through a
91
- *clone*, so the widget styled here never maps -- and only a map paints.
92
+ flood the rest with the border color.
93
+ """
94
+ menubar = ttk.Menu(root)
95
+ menubar.add_cascade(label="File")
96
+ root.configure(menu=menubar)
97
+ try:
98
+ assert str(menubar.cget("background")) == root.style.colors.bg
99
+ assert not getattr(menubar, "_tb_menu_hairline", False)
100
+ finally:
101
+ root.configure(menu="")
102
+
103
+
104
+ def test_a_menubar_that_maps_is_still_not_painted(root, x11):
105
+ """The same guard, forced instead of trusted.
106
+
107
+ The test above only shows the menubar went unpainted *because it never
108
+ mapped* -- and that is a property of the build, not a guarantee. Tk displays
109
+ a menubar through a clone, so historically the widget styled here did not
110
+ map; under CPython 3.13.15 it does, which painted every x11 menubar in the
111
+ border color. Not the Tk version either: CI's 3.10 job does not map it on
112
+ the same Tk 8.6.14. Deliver the `<Map>` by hand so the refusal is asserted
113
+ on every box regardless of what the local build does.
92
114
  """
93
115
  menubar = ttk.Menu(root)
94
116
  menubar.add_cascade(label="File")
95
117
  root.configure(menu=menubar)
96
118
  try:
119
+ _on_menu_map(SimpleNamespace(widget=menubar))
97
120
  assert str(menubar.cget("background")) == root.style.colors.bg
98
121
  assert not getattr(menubar, "_tb_menu_hairline", False)
99
122
  finally:
100
123
  root.configure(menu="")
101
124
 
102
125
 
126
+ def test_a_mapped_popup_is_painted(root, x11):
127
+ """The positive control for the guard above.
128
+
129
+ Refusing to paint a menubar is only correct if a popup arriving down the
130
+ same path still gets its border -- otherwise the guard could be over-broad
131
+ and no test would notice.
132
+ """
133
+ popup = ttk.Menu(root)
134
+ popup.add_command(label="Open")
135
+
136
+ _on_menu_map(SimpleNamespace(widget=popup))
137
+ assert str(popup.cget("background")) == root.style.colors.border
138
+ assert popup._tb_menu_hairline is True
139
+
140
+
103
141
  def test_entries_follow_a_theme_switch(root, x11):
104
142
  menu = ttk.Menu(root)
105
143
  menu.add_command(label="Open")
File without changes
File without changes
File without changes
File without changes