home · contact · privacy
In status bar code, re-organize what to global.
authorPlom Heller <plom@plomlompom.com>
Mon, 21 Sep 2026 05:27:44 +0000 (07:27 +0200)
committerPlom Heller <plom@plomlompom.com>
Mon, 21 Sep 2026 05:27:44 +0000 (07:27 +0200)
home/user/.config/sway/status.py

index a89214ed1d88b6ab742df9eeb16ff29fd37ff4b1..b8367967c903f8fa5c03aaf78a32b1e04e8bbb45 100755 (executable)
@@ -12,8 +12,6 @@ sys_path.append(
         str(Path(__file__).resolve().parents[2] / '.local' / 'bin' / 'lib'))
 from pactl import pactl_info_default_dev
 
-METADATA = {'version': 1}
-
 COL_GREEN = '#00DD00'
 COL_GREY = '#AAAAAA'
 COL_RED = '#DD0000'
@@ -21,25 +19,27 @@ COL_WHITE = '#DDDDDD'
 COL_YELLOW = '#DDDD00'
 COL_ESCALATION = (COL_GREEN, COL_YELLOW, COL_RED)
 
-CMD_PASTE = 'wl-paste'
-CLIP_LEN_MAX = 32
-MSG_CLIPBOARD_EMPTY = 'Nothing is copied'
-
-KB_LAYOUTS = ('us', 'de')  # keep in sync with sway config's xkb_layout
-
-AUDIO_DEVS_LABELS = (('sink', 'vol'),
-                     ('source', '--mic'))
-
-PATH_POWER_SUPPLY = Path('/sys/class/power_supply')
-GLOB_BATTERY = 'BAT*'
+# for blocks_battery
 BATTERY_STATUS_SYMBOLS = {
         'Charging': ('^', COL_GREEN),
         'Discharging': ('v', COL_RED),
         'Not charging': ('-', COL_WHITE),
 }
+BATTERY_ESCALATIONS_CHARGE = (85, 25)
+BATTERY_ESCALATIONS_HEALTH = (85, 25)
+
+# for blocks_clipboard
+CMD_PASTE = 'wl-paste'
+CLIP_LEN_MAX = 32
 
-PATH_THERMAL = Path('/sys/class/thermal')
-GLOB_THERMAL = 'thermal_zone*/temp'
+# for blocks_layout
+KB_LAYOUTS = ('us', 'de')  # keep in sync with sway config's xkb_layout
+
+# for blocks_network
+NETWORK_STRENGTH_ESCALATIONS = (80, 50)
+
+# for blocks_thermal
+THERMAL_ESCALATIONS = (55, 80)
 
 
 class Block(NamedTuple):
@@ -92,45 +92,12 @@ def first_among_equals[T](
     return items.pop()
 
 
-def blocks_clipboard(
-        ) -> tuple[Block, ...]:
-    'Produce clipboard contents summary.'
-    blocks = []
-    args: tuple[str, ...]
-    for args in (tuple(), ('--primary',)):
-        col_clip = COL_YELLOW
-        brackets = '()'
-        proc = subprocess_run((CMD_PASTE,) + args,
-                              check=False, capture_output=True)
-        if proc.returncode:
-            stderr = proc.stderr.decode('utf8', 'replace').strip()
-            if stderr == MSG_CLIPBOARD_EMPTY:
-                clip = 'empty'
-                col_clip = COL_GREY
-            else:
-                clip = 'error'
-                col_clip = COL_RED
-        else:
-            try:
-                clip = proc.stdout.decode('utf8').replace('\n', ' ').strip()
-                brackets = '[]'
-            except UnicodeDecodeError:
-                clip = 'binary'
-        if (ellipsed := len(clip) > CLIP_LEN_MAX):
-            clip = clip[:CLIP_LEN_MAX - 1]
-        blocks += [Block(f'{(args[0] if args else CMD_PASTE)} {brackets[0]}'),
-                   Block(clip, col_clip)]
-        if ellipsed:
-            blocks += [Block('…', COL_GREEN)]
-        blocks += [Block(brackets[1], separator_block_width=5)]
-    return tuple(blocks)
-
-
 def blocks_audio(
         ) -> tuple[Block, ...]:
     "Produce audio devices' volume, muteness."
     blocks = []
-    for dev_type, label in AUDIO_DEVS_LABELS:
+    for dev_type, label in (('sink', 'vol'),
+                            ('source', '--mic')):
         dev_info = pactl_info_default_dev(dev_type)
         is_mute = dev_info['mute']
         percentage = first_among_equals(
@@ -150,7 +117,7 @@ def blocks_audio(
 def blocks_battery(
         ) -> tuple[Block, ...]:
     'Produce battery charge, status, health status bar text.'
-    path_battery = next(PATH_POWER_SUPPLY.glob(GLOB_BATTERY))
+    path_battery = next(Path('/sys/class/power_supply').glob('BAT*'))
     status, status_color = BATTERY_STATUS_SYMBOLS.get(
         (path_battery / 'status').read_text(encoding='utf8').strip(),
         ('?', COL_RED))
@@ -164,9 +131,43 @@ def blocks_battery(
             charge_pc = round(now / full * 100)
             health_pc = round(full / full_design * 100)
             break
-    return (Block.color_escalated(charge_pc, (85, 25)),
+    return (Block.color_escalated(charge_pc, BATTERY_ESCALATIONS_CHARGE),
             Block(status, status_color),
-            Block.color_escalated(health_pc, (85, 25)))
+            Block.color_escalated(health_pc, BATTERY_ESCALATIONS_HEALTH))
+
+
+def blocks_clipboard(
+        ) -> tuple[Block, ...]:
+    'Produce clipboard contents summary.'
+    blocks = []
+    args: tuple[str, ...]
+    for args in (tuple(), ('--primary',)):
+        col_clip = COL_YELLOW
+        brackets = '()'
+        proc = subprocess_run((CMD_PASTE,) + args,
+                              check=False, capture_output=True)
+        if proc.returncode:
+            stderr = proc.stderr.decode('utf8', 'replace').strip()
+            if stderr == 'Nothing is copied':
+                clip = 'empty'
+                col_clip = COL_GREY
+            else:
+                clip = 'error'
+                col_clip = COL_RED
+        else:
+            try:
+                clip = proc.stdout.decode('utf8').replace('\n', ' ').strip()
+                brackets = '[]'
+            except UnicodeDecodeError:
+                clip = 'binary'
+        if (ellipsed := len(clip) > CLIP_LEN_MAX):
+            clip = clip[:CLIP_LEN_MAX - 1]
+        blocks += [Block(f'{(args[0] if args else CMD_PASTE)} {brackets[0]}'),
+                   Block(clip, col_clip)]
+        if ellipsed:
+            blocks += [Block('…', COL_GREEN)]
+        blocks += [Block(brackets[1], separator_block_width=5)]
+    return tuple(blocks)
 
 
 def blocks_datetime(
@@ -243,7 +244,8 @@ def blocks_network(
         blocks += [Block(f'{dev_type} ')]
         if len(info_toks) == 3:
             percentage = int(info_toks[2])
-            blocks += [Block.color_escalated(percentage, (80, 50)),
+            blocks += [Block.color_escalated(percentage,
+                                             NETWORK_STRENGTH_ESCALATIONS),
                        Block('% ')]
         blocks += [Block('/'.join(info_toks[:2]), COL_WHITE,
                          separator_block_width=5)]
@@ -254,15 +256,16 @@ def blocks_thermal(
         ) -> tuple[Block, ...]:
     'Produce Celsius of current device hotness.'
     temperature = round(max(int_at_path(path)
-                        for path in PATH_THERMAL.glob(GLOB_THERMAL)) / 1000)
-    return (Block.color_escalated(temperature, (55, 80)),
+                        for path in Path('/sys/class/thermal'
+                                         ).glob('thermal_zone*/temp')) / 1000)
+    return (Block.color_escalated(temperature, THERMAL_ESCALATIONS),
             Block('°C'))
 
 
 def print_bar(
         ) -> None:
     'Produce stream of status bar updates.'
-    print(json_dumps(METADATA))
+    print(json_dumps({'version': 1}))
     print('[', end='')
     while True:
         blocks: list[Block] = []