Skip to content

Commit e3e3fdd

Browse files
authored
Merge pull request #160 from Video-Nomad/fix/systray-empty-pinned-fix
fix(systray): properly hide pinned container on last icon delete
2 parents 0790e25 + ccf34b9 commit e3e3fdd

File tree

3 files changed

+47
-19
lines changed

3 files changed

+47
-19
lines changed

docs/widgets/(Widget)-Systray.md

+17-11
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
# Systray Widget
2-
| Option | Type | Default | Description |
3-
|----------------------|---------|-------------|-----------------------------------------------------------------------------------------|
4-
| `class_name` | string | `'systray'` | The class name for the base widget. |
5-
| `label_collapsed` | string | `'▼'` | Label used for the collapse button when unpinned container is hidden. |
6-
| `label_expanded` | string | `'▶'` | Label used for the collapse button when unpinned container is shown. |
7-
| `label_position` | string | `'left'` | The position of the button that collapses unpinned container. Can be "left" or "right". |
8-
| `icon_size` | integer | `16` | The size of the icons in the systray. Can be any integer between 8 and 64. |
9-
| `pin_click_modifier` | string | `'alt'` | The modifier key used to pin/unpin icons. Can be "ctrl", "alt" or "shift". |
10-
| `show_unpinned` | boolean | `true` | Whether to show unpinned container on startup. |
11-
| `show_battery` | boolean | `false` | Whether to show battery icon (from the original systray). |
12-
| `show_volume` | boolean | `false` | Whether to show volume icon (from the original systray). |
2+
| Option | Type | Default | Description |
3+
|------------------------|---------|-------------|-----------------------------------------------------------------------------------------|
4+
| `class_name` | string | `'systray'` | The class name for the base widget. |
5+
| `label_collapsed` | string | `'▼'` | Label used for the collapse button when unpinned container is hidden. |
6+
| `label_expanded` | string | `'▶'` | Label used for the collapse button when unpinned container is shown. |
7+
| `label_position` | string | `'left'` | The position of the button that collapses unpinned container. Can be "left" or "right". |
8+
| `icon_size` | integer | `16` | The size of the icons in the systray. Can be any integer between 8 and 64. |
9+
| `pin_click_modifier` | string | `'alt'` | The modifier key used to pin/unpin icons. Can be "ctrl", "alt" or "shift". |
10+
| `show_unpinned` | boolean | `true` | Whether to show unpinned container on startup. |
11+
| `show_unpinned_button` | boolean | `true` | Whether to show the collapse unpinned icons button. |
12+
| `show_battery` | boolean | `false` | Whether to show battery icon (from the original systray). |
13+
| `show_volume` | boolean | `false` | Whether to show volume icon (from the original systray). |
14+
| `show_network` | boolean | `false` | Whether to show network icon (from the original systray).
1315

1416

1517
## Example Configuration
@@ -24,8 +26,10 @@ systray:
2426
icon_size: 16 # Can be any integer between 8 and 64
2527
pin_click_modifier: "alt" # Can be "ctrl", "alt" or "shift"
2628
show_unpinned: true
29+
show_unpinned_button: true
2730
show_battery: false
2831
show_volume: false
32+
show_network: false
2933
```
3034
3135
## Important Notes:
@@ -41,8 +45,10 @@ There are some limitations with the systray widget:
4145
- **icon_size:** The size of the icons in the systray. Can be any integer between 8 and 64.
4246
- **pin_click_modifier:** The modifier key used to pin/unpin icons. Can be "ctrl", "alt" or "shift".
4347
- **show_unpinned:** Whether to show unpinned container on startup.
48+
- **show_unpinned_button:** Whether to show the 'collapse unpinned icons' button.
4449
- **show_battery:** Whether to show battery icon (from the original systray).
4550
- **show_volume:** Whether to show volume icon (from the original systray).
51+
- **show_network:** Whether to show network icon (from the original systray).
4652
4753
## Style
4854
```css

src/core/validation/widgets/yasb/systray.py

+12
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@
66
"icon_size": 16,
77
"pin_click_modifier": "alt",
88
"show_unpinned": True,
9+
"show_unpinned_button": True,
910
"show_battery": False,
1011
"show_volume": False,
12+
"show_network": False,
1113
}
1214

1315
VALIDATION_SCHEMA = {
@@ -48,6 +50,11 @@
4850
"required": False,
4951
"default": DEFAULTS["show_unpinned"],
5052
},
53+
"show_unpinned_button": {
54+
"type": "boolean",
55+
"required": False,
56+
"default": DEFAULTS["show_unpinned_button"],
57+
},
5158
"show_battery": {
5259
"type": "boolean",
5360
"required": False,
@@ -58,4 +65,9 @@
5865
"required": False,
5966
"default": DEFAULTS["show_volume"],
6067
},
68+
"show_network": {
69+
"type": "boolean",
70+
"required": False,
71+
"default": DEFAULTS["show_network"],
72+
},
6173
}

src/core/widgets/yasb/systray.py

+18-8
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747

4848
BATTERY_ICON_GUID = UUID("7820ae75-23e3-4229-82c1-e41cb67d5b9c")
4949
VOLUME_ICON_GUID = UUID("7820ae73-23e3-4229-82c1-e41cb67d5b9c")
50+
NETWORK_GUID = UUID("7820ae74-23e3-4229-82c1-e41cb67d5b9c")
5051

5152

5253
class TrayMonitorThread(QThread):
@@ -90,23 +91,26 @@ def __init__(
9091
icon_size: int,
9192
pin_click_modifier: str,
9293
show_unpinned: bool,
94+
show_unpinned_button: bool,
9395
show_battery: bool,
9496
show_volume: bool,
97+
show_network: bool,
9598
):
9699
super().__init__(class_name=class_name) # type: ignore
97100
self.label_collapsed = label_collapsed
98101
self.label_expanded = label_expanded
99102
self.label_position = label_position if label_position in {"left", "right"} else "left"
100103
self.icon_size = icon_size
101-
self.show_volume = show_volume
102-
self.show_battery = show_battery
103104
self.show_unpinned = show_unpinned
105+
self.show_unpinned_button = show_unpinned_button
104106

105107
self.filtered_guids: set[UUID] = set()
106-
if not self.show_battery:
108+
if not show_battery:
107109
self.filtered_guids.add(BATTERY_ICON_GUID)
108-
if not self.show_volume:
110+
if not show_volume:
109111
self.filtered_guids.add(VOLUME_ICON_GUID)
112+
if not show_network:
113+
self.filtered_guids.add(NETWORK_GUID)
110114

111115
IconWidget.icon_size = icon_size
112116
IconWidget.pin_modifier_key = {
@@ -128,6 +132,10 @@ def __init__(
128132
self.sort_timer.timeout.connect(self.sort_icons) # type: ignore
129133
self.sort_timer.setSingleShot(True)
130134

135+
self.pinned_vis_check_timer = QTimer(self)
136+
self.pinned_vis_check_timer.timeout.connect(self.update_pinned_widget_visibility) # type: ignore
137+
self.pinned_vis_check_timer.setSingleShot(True)
138+
131139
self.unpinned_vis_btn = QPushButton()
132140
self.unpinned_vis_btn.setCheckable(True)
133141
self.unpinned_vis_btn.clicked.connect(self.toggle_unpinned_widget_visibility) # type: ignore
@@ -157,6 +165,8 @@ def __init__(
157165
else:
158166
self.widget_layout.insertWidget(-1, self.unpinned_vis_btn)
159167

168+
self.unpinned_vis_btn.setVisible(self.show_unpinned_button)
169+
160170
QTimer.singleShot(0, self.setup_client) # pyright: ignore [reportUnknownMemberType]
161171

162172
def setup_client(self):
@@ -182,7 +192,7 @@ def showEvent(self, a0: QShowEvent | None) -> None:
182192
super().showEvent(a0)
183193
self.unpinned_vis_btn.setChecked(self.show_unpinned)
184194
self.unpinned_vis_btn.setText(self.label_expanded if self.show_unpinned else self.label_collapsed)
185-
self.unpinned_widget.setVisible(self.show_unpinned)
195+
self.unpinned_widget.setVisible(self.show_unpinned or not self.show_unpinned_button)
186196

187197
@pyqtSlot()
188198
def on_drag_started(self):
@@ -231,7 +241,7 @@ def on_icon_modified(self, data: IconData):
231241
self.update_icon_data(icon.data, data)
232242
icon.update_icon()
233243
icon.setHidden(data.uFlags & NIF_STATE != 0 and data.dwState == 1)
234-
self.update_pinned_widget_visibility()
244+
self.pinned_vis_check_timer.start(300)
235245

236246
@pyqtSlot(IconData)
237247
def on_icon_deleted(self, data: IconData) -> None:
@@ -240,7 +250,7 @@ def on_icon_deleted(self, data: IconData) -> None:
240250
if icon is not None:
241251
self.icons.remove(icon)
242252
icon.deleteLater()
243-
self.update_pinned_widget_visibility()
253+
self.pinned_vis_check_timer.start(300)
244254

245255
@pyqtSlot(object)
246256
def on_icon_pinned_changed(self, icon: IconWidget):
@@ -295,7 +305,7 @@ def check_icons(self):
295305
icons_changed = True
296306

297307
if icons_changed:
298-
self.update_pinned_widget_visibility()
308+
self.pinned_vis_check_timer.start(300)
299309

300310
def update_icon_data(self, old_data: IconData | None, new_data: IconData):
301311
"""Update the icon data with the new data received from the tray monitor"""

0 commit comments

Comments
 (0)