Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 14 additions & 19 deletions src/core/widgets/glazewm/binding_mode.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,34 +107,29 @@ def _reload_css(self, label: QLabel):
def _update_label(self):
active_widgets = self._widgets_alt if self._show_alt_label else self._widgets
active_label_content = self._label_alt_content if self._show_alt_label else self._label_content

active_label_content = active_label_content.format(
binding_mode=(
self._active_binding_mode.display_name or self._active_binding_mode.name or self._label_if_no_active
),
icon=self._icons.get(self._active_binding_mode.name or "none", self._default_icon),
)

label_parts = re.split("(<span.*?>.*?</span>)", active_label_content)
label_parts = [part for part in label_parts if part]
widget_index = 0

label_options = {
"{binding_mode}": self._active_binding_mode.display_name
or self._active_binding_mode.name
or self._label_if_no_active,
"{icon}": self._icons.get(self._active_binding_mode.name or "none", self._default_icon),
}
for part in label_parts:
part = part.strip()
if part and widget_index < len(active_widgets) and isinstance(active_widgets[widget_index], QLabel):
formatted_text = part
for option, value in label_options.items():
formatted_text = formatted_text.replace(option, str(value))
if "<span" in part and "</span>" in part:
icon = re.sub(r"<span.*?>|</span>", "", part).strip()
if icon in label_options:
active_widgets[widget_index].setProperty(
"class", f"icon {self._active_binding_mode.name or 'none'}"
)
active_widgets[widget_index].setText(formatted_text)
else:
active_widgets[widget_index].setText(icon)
part = re.sub(r"<span.*?>|</span>", "", part).strip()
active_widgets[widget_index].setProperty(
"class", f"icon {self._active_binding_mode.name or 'none'}"
)
active_widgets[widget_index].setText(part)
else:
if widget_index < len(active_widgets) and isinstance(active_widgets[widget_index], QLabel):
active_widgets[widget_index].setText(formatted_text)
active_widgets[widget_index].setText(part)
if active_widgets[widget_index].property("class") == "label-offline":
active_widgets[widget_index].setProperty("class", "label")
if not self._active_binding_mode.name:
Expand Down
29 changes: 17 additions & 12 deletions src/core/widgets/yasb/battery.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,9 +144,8 @@ def _charging_blink(self):
def _update_label(self):
active_widgets = self._widgets_alt if self._show_alt_label else self._widgets
active_label_content = self._label_alt_content if self._show_alt_label else self._label_content
label_parts = re.split("(<span.*?>.*?</span>)", active_label_content)
label_parts = [part for part in label_parts if part]
widget_index = 0

self._battery_state = psutil.sensors_battery()

if self._battery_state is None:
Expand All @@ -155,8 +154,13 @@ def _update_label(self):
self.timer.stop()
return

label_parts = re.split("(<span.*?>.*?</span>)", active_label_content)

for part in label_parts:
part = part.strip()
if not part:
continue

if widget_index < len(active_widgets) and isinstance(active_widgets[widget_index], QLabel):
if "<span" in part and "</span>" in part:
active_widgets[widget_index].hide()
Expand All @@ -170,19 +174,21 @@ def _update_label(self):
is_charging_str = "yes" if self._battery_state.power_plugged else "no"
charging_icon = self._get_charging_icon(original_threshold)

active_label_content = active_label_content.format(
percent=str(self._battery_state.percent),
time_remaining=time_remaining,
is_charging=is_charging_str,
icon=charging_icon,
)
label_parts = re.split("(<span.*?>.*?</span>)", active_label_content)

for part in label_parts:
part = part.strip()
if part and widget_index < len(active_widgets) and isinstance(active_widgets[widget_index], QLabel):
battery_status = (
part.replace("{percent}", str(self._battery_state.percent))
.replace("{time_remaining}", time_remaining)
.replace("{is_charging}", is_charging_str)
.replace("{icon}", charging_icon)
)
if "<span" in battery_status and "</span>" in battery_status:
if "<span" in part and "</span>" in part:
# icon-only QLabel
widget_label = active_widgets[widget_index]
icon = re.sub(r"<span.*?>|</span>", "", battery_status).strip()
icon = re.sub(r"<span.*?>|</span>", "", part).strip()
widget_label.setText(icon)
# apply status‐class
existing_classes = widget_label.property("class")
Expand All @@ -207,8 +213,7 @@ def _update_label(self):
refresh_widget_style(widget_label)
else:
alt_class = "alt" if self._show_alt_label else ""
formatted_text = battery_status.format(battery_status)
active_widgets[widget_index].setText(formatted_text)
active_widgets[widget_index].setText(part)
active_widgets[widget_index].setProperty("class", f"label {alt_class} status-{threshold}")
refresh_widget_style(active_widgets[widget_index])
widget_index += 1
25 changes: 11 additions & 14 deletions src/core/widgets/yasb/bluetooth.py
Original file line number Diff line number Diff line change
Expand Up @@ -310,8 +310,6 @@ def _toggle_label(self):
def _update_label(self, icon, connected_devices=None):
active_widgets = self._widgets_alt if self._show_alt_label else self._widgets
active_label_content = self._label_alt_content if self._show_alt_label else self._label_content
label_parts = re.split("(<span.*?>.*?</span>)", active_label_content)
label_parts = [part for part in label_parts if part]
widget_index = 0

if connected_devices:
Expand All @@ -333,26 +331,25 @@ def _update_label(self, icon, connected_devices=None):
device_names = self._label_no_device
tooltip_text = self._label_no_device

label_options = {
"{icon}": icon,
"{device_name}": device_names,
"{device_count}": len(connected_devices) if connected_devices else 0,
}
active_label_content = active_label_content.format(
icon=icon,
device_name=device_names,
device_count=len(connected_devices) if connected_devices else 0,
)

label_parts = re.split("(<span.*?>.*?</span>)", active_label_content)

for part in label_parts:
part = part.strip()
if part:
formatted_text = part
for option, value in label_options.items():
formatted_text = formatted_text.replace(option, str(value))
if "<span" in part and "</span>" in part:
if widget_index < len(active_widgets) and isinstance(active_widgets[widget_index], QLabel):
active_widgets[widget_index].setText(formatted_text)
active_widgets[widget_index].setText(part)
else:
if self._max_length and len(formatted_text) > self._max_length:
formatted_text = formatted_text[: self._max_length] + self._max_length_ellipsis
if self._max_length and len(part) > self._max_length:
part = part[: self._max_length] + self._max_length_ellipsis
if widget_index < len(active_widgets) and isinstance(active_widgets[widget_index], QLabel):
active_widgets[widget_index].setText(formatted_text)
active_widgets[widget_index].setText(part)
widget_index += 1

if self._tooltip:
Expand Down
15 changes: 6 additions & 9 deletions src/core/widgets/yasb/brightness.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,9 +158,7 @@ def _toggle_brightness_menu(self):
def _update_label(self):
active_widgets = self._widgets_alt if self._show_alt_label else self._widgets
active_label_content = self._label_alt_content if self._show_alt_label else self._label_content
label_parts = re.split("(<span.*?>.*?</span>)", active_label_content)
label_parts = [part for part in label_parts if part]
widget_index = 0

try:
percent = self.get_brightness()
if percent is None:
Expand All @@ -176,7 +174,9 @@ def _update_label(self):
except Exception:
percent, icon = 0, "not supported"

label_options = {"{icon}": icon, "{percent}": percent}
active_label_content = active_label_content.format(icon=icon, percent=percent)
label_parts = re.split("(<span.*?>.*?</span>)", active_label_content)
widget_index = 0

if self._progress_bar["enabled"] and self.progress_widget:
if self._widget_container_layout.indexOf(self.progress_widget) == -1:
Expand All @@ -189,15 +189,12 @@ def _update_label(self):
for part in label_parts:
part = part.strip()
if part:
formatted_text = part
for option, value in label_options.items():
formatted_text = formatted_text.replace(option, str(value))
if "<span" in part and "</span>" in part:
if widget_index < len(active_widgets) and isinstance(active_widgets[widget_index], QLabel):
active_widgets[widget_index].setText(formatted_text)
active_widgets[widget_index].setText(part)
else:
if widget_index < len(active_widgets) and isinstance(active_widgets[widget_index], QLabel):
active_widgets[widget_index].setText(formatted_text)
active_widgets[widget_index].setText(part)
widget_index += 1

def show_brightness_menu(self):
Expand Down
122 changes: 60 additions & 62 deletions src/core/widgets/yasb/clock.py
Original file line number Diff line number Diff line change
Expand Up @@ -511,16 +511,33 @@ def _update_label(self):
# Choose which label set to update (primary or alternate)
active_widgets = self._widgets_alt if self._show_alt_label else self._widgets
active_label_content = self._label_alt_content if self._show_alt_label else self._label_content
label_parts = re.split("(<span.*?>.*?</span>)", active_label_content)
label_parts = [part for part in label_parts if part]
widget_index = 0

now = datetime.now(ZoneInfo(self._active_tz)) if self._active_tz else datetime.now().astimezone()

# Finding the datetime format string in the label using keyerror exception.
try:
active_label_content.format(icon="", alarm="", timedata=now)
except KeyError as ke:
# Remove the quotes around the exception message to get the datetime format.
datetime_format = str(ke)[1:-1]

datetime_format_idx = active_label_content.find(datetime_format)
closing_braces_idx = active_label_content.find("}", datetime_format_idx + len(datetime_format))

datetime_format = active_label_content[datetime_format_idx:closing_braces_idx]
active_label_content = active_label_content.replace(
"{" + datetime_format + "}", now.strftime(datetime_format)
)

current_hour = f"{now.hour:02d}"
current_minute = f"{now.minute:02d}"
hour_changed = self._current_hour != current_hour
minute_changed = self._current_minute != current_minute

if hour_changed:
self._current_hour = current_hour

if minute_changed:
self._current_minute = current_minute

Expand All @@ -539,72 +556,53 @@ def _update_label(self):
self._timer_label.hide()
self._timer_visible = False

clock_icon = self._get_icon_for_hour(now.hour)
hour_class = f"clock_{current_hour}"
alarm_icon = alarm_class = ""

if self._shared_state._snoozed_alarms:
alarm_class = "icon alarm snooze"
alarm_icon = self._alarm_icons["snooze"]

elif self._has_enabled_alarms():
alarm_icon = self._alarm_icons["enabled"]
alarm_class = "icon alarm"

# The icon place holders are replaced with a span tag of the icon string, with all of its appropriate classes
# assigned to it.
label_content_values = {
"icon": f'<span class="{hour_class}">{clock_icon}</span>',
"alarm": f'<span class="{alarm_class}">{alarm_icon}</span>',
"timedata": now,
}

active_label_content = active_label_content.format_map(label_content_values)

# If any of the icon placeholders are already in a span tag, then flatten the 2 layers of nested span tags, and
# merge their classes into one span tag, before sending them for parsing.
active_label_content = re.sub(
r'<span(?: class=([\'"])(?P<class_name>[\w -]*)\1)?><span class=([\'"])(?P<class_name2>[\w -]*)\3>(?P<label_name>.*?)</span></span>',
r'<span class="\g<class_name> \g<class_name2>">\g<label_name></span>',
active_label_content,
)

label_parts = re.split("(<span.*?>.*?</span>)", active_label_content)

for part in label_parts:
part = part.strip()
if part and widget_index < len(active_widgets) and isinstance(active_widgets[widget_index], QLabel):
if "<span" in part and "</span>" in part:
match = re.search(r'<span class=([\'"])(?P<class_name>[\w -]*)\1>[^>]*</span>', part)
classes = match.group("class_name") or ""

icon_placeholder = re.sub(r"<span.*?>|</span>", "", part).strip()
if icon_placeholder == "{icon}":
if hour_changed:
icon = self._get_icon_for_hour(now.hour)
active_widgets[widget_index].setText(icon)
hour_class = f"clock_{current_hour}"
active_widgets[widget_index].setProperty("class", f"icon {hour_class}")
refresh_widget_style(active_widgets[widget_index])
elif icon_placeholder == "{alarm}":
if self._shared_state._snoozed_alarms:
active_widgets[widget_index].setText(self._alarm_icons["snooze"])
active_widgets[widget_index].setProperty("class", "icon alarm snooze")
active_widgets[widget_index].setVisible(True)
refresh_widget_style(active_widgets[widget_index])
elif self._has_enabled_alarms():
active_widgets[widget_index].setText(self._alarm_icons["enabled"])
active_widgets[widget_index].setProperty("class", "icon alarm")
active_widgets[widget_index].setVisible(True)
refresh_widget_style(active_widgets[widget_index])
else:
active_widgets[widget_index].setText("")
active_widgets[widget_index].setVisible(False)

else:
active_widgets[widget_index].setText(icon_placeholder)
else:
has_alarm = "{alarm}" in part and (self._shared_state._snoozed_alarms or self._has_enabled_alarms())

if "{icon}" in part:
icon = self._get_icon_for_hour(now.hour)
part = part.replace("{icon}", icon)

if "{alarm}" in part:
if self._shared_state._snoozed_alarms:
part = part.replace("{alarm}", self._alarm_icons["snooze"])
elif self._has_enabled_alarms():
part = part.replace("{alarm}", self._alarm_icons["enabled"])
else:
part = part.replace("{alarm}", "")
try:
datetime_format_search = re.search(r"\{(.*)}", part)
datetime_format_str = datetime_format_search.group()
datetime_format = datetime_format_search.group(1)
format_label_content = part.replace(datetime_format_str, now.strftime(datetime_format))
except Exception:
format_label_content = part

active_widgets[widget_index].setText(format_label_content)

alarm_state_changed = has_alarm != self._previous_alarm_state
if has_alarm:
if self._shared_state._snoozed_alarms:
active_widgets[widget_index].setProperty("class", "label alarm snooze")
else:
active_widgets[widget_index].setProperty("class", "label alarm")
refresh_widget_style(active_widgets[widget_index])
else:
hour_class = f"clock_{current_hour}"
active_widgets[widget_index].setProperty("class", f"label {hour_class}")
if hour_changed or alarm_state_changed:
refresh_widget_style(active_widgets[widget_index])
active_widgets[widget_index].setText(icon_placeholder)
active_widgets[widget_index].setProperty("class", classes.strip())
refresh_widget_style(active_widgets[widget_index])

else:
active_widgets[widget_index].setText(part)
has_alarm = self._shared_state._snoozed_alarms or self._has_enabled_alarms()
self._previous_alarm_state = has_alarm
widget_index += 1

Expand Down
12 changes: 5 additions & 7 deletions src/core/widgets/yasb/cpu.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,10 @@ def _update_label(self, cpu_freq, cpu_stats, current_perc, cores_perc, cpu_cores

active_widgets = self._widgets_alt if self._show_alt_label else self._widgets
active_label_content = self._label_alt_content if self._show_alt_label else self._label_content
active_label_content = active_label_content.format(info=cpu_info)
cpu_threshold_class = self._get_cpu_threshold(current_perc)

label_parts = re.split("(<span.*?>.*?</span>)", active_label_content)
label_parts = [part for part in label_parts if part]
widget_index = 0

if self._progress_bar["enabled"] and self.progress_widget:
Expand All @@ -184,12 +186,8 @@ def _update_label(self, cpu_freq, cpu_stats, current_perc, cores_perc, cpu_cores
active_widgets[widget_index].setText(icon)
else:
label_class = "label alt" if self._show_alt_label else "label"
formatted_text = part.format(info=cpu_info)
active_widgets[widget_index].setText(formatted_text)
active_widgets[widget_index].setProperty("class", label_class)
active_widgets[widget_index].setProperty(
"class", f"{label_class} status-{self._get_cpu_threshold(current_perc)}"
)
active_widgets[widget_index].setText(part)
active_widgets[widget_index].setProperty("class", f"{label_class} status-{cpu_threshold_class}")
refresh_widget_style(active_widgets[widget_index])
widget_index += 1

Expand Down
Loading