frobar-ng: Fix last few issues

This commit is contained in:
Geoffrey Frogeye 2025-01-10 18:35:10 +01:00
parent 24dd070bd9
commit 42d3d1b3a6
Signed by: geoffrey
GPG key ID: C72403E7F82E6AD8

View file

@ -277,6 +277,8 @@ class Side(ComposableText):
text += "%{B" + hexa + "}%{F-}" text += "%{B" + hexa + "}%{F-}"
else: else:
text += "%{B-}%{F" + hexa + "}%{R}%{F-}" text += "%{B-}%{F" + hexa + "}%{R}%{F-}"
elif isinstance(lastSection, SpacerSection):
text += "%{B-}%{F" + hexa + "}%{R}%{F-}"
else: else:
if self.alignment == Alignment.RIGHT: if self.alignment == Alignment.RIGHT:
if lastSection.color == section.color: if lastSection.color == section.color:
@ -291,7 +293,7 @@ class Side(ComposableText):
text += "%{F-}" text += "%{F-}"
text += section.getMarkup() text += section.getMarkup()
lastSection = section lastSection = section
if self.alignment != Alignment.RIGHT: if self.alignment != Alignment.RIGHT and lastSection:
text += "%{R}%{B-}" text += "%{R}%{B-}"
return text return text
@ -467,6 +469,23 @@ class StaticProvider(SingleSectionProvider):
self.section.setText(self.text) self.section.setText(self.text)
class SpacerSection(Section):
pass
class SpacerProvider(SingleSectionProvider):
sectionType = SpacerSection
def __init__(self, length: int = 5) -> None:
super().__init__(color=rich.color.Color.default())
self.length = length
async def run(self) -> None:
await super().run()
assert isinstance(self.section, SpacerSection)
self.section.setText(" " * self.length)
class StatefulSection(Section): class StatefulSection(Section):
def __init__( def __init__(
@ -621,9 +640,11 @@ class I3WorkspacesProvider(MultiSectionsProvider):
def __init__( def __init__(
self, self,
custom_names: dict[str, str] = {},
) -> None: ) -> None:
super().__init__() super().__init__()
self.workspaces: dict[int, i3ipc.WorkspaceReply] self.workspaces: dict[int, i3ipc.WorkspaceReply]
self.custom_names = custom_names
self.sections: dict[int, Section] = dict() self.sections: dict[int, Section] = dict()
self.modulesFromOutput: dict[str, Module] = dict() self.modulesFromOutput: dict[str, Module] = dict()
@ -649,8 +670,8 @@ class I3WorkspacesProvider(MultiSectionsProvider):
section.color = self.COLOR_VISIBLE section.color = self.COLOR_VISIBLE
else: else:
section.color = self.COLOR_DEFAULT section.color = self.COLOR_DEFAULT
if workspace.focused or workspace.visible: if workspace.focused:
name = f"{name} X" # FIXME Custom names name = self.custom_names.get(name, name)
section.setText(name) section.setText(name)
return update return update
@ -730,11 +751,13 @@ class MprisProvider(MirrorProvider):
for name in self.manager.props.player_names: for name in self.manager.props.player_names:
self.init_player(name) self.init_player(name)
self.update_sections() self.updateSections()
while True: while True:
# Occasionally it will skip a second
# but haven't managed to reproduce with debug info
await self.playing.wait() await self.playing.wait()
self.update_title() self.updateTitle()
if self.player: if self.player:
pos = self.player.props.position pos = self.player.props.position
rem = 1 - (pos % 1000000) / 1000000 rem = 1 - (pos % 1000000) / 1000000
@ -752,13 +775,13 @@ class MprisProvider(MirrorProvider):
return default return default
@staticmethod @staticmethod
def format_us(ms: int) -> str: def formatUs(ms: int) -> str:
if ms < 60 * 60 * 1000000: if ms < 60 * 60 * 1000000:
return time.strftime("%M:%S", time.gmtime(ms // 1000000)) return time.strftime("%M:%S", time.gmtime(ms // 1000000))
else: else:
return str(datetime.timedelta(microseconds=ms)) return str(datetime.timedelta(microseconds=ms))
def find_current_player(self) -> None: def findCurrentPlayer(self) -> None:
for name in [self.playerctldName] + self.manager.props.player_names: for name in [self.playerctldName] + self.manager.props.player_names:
# TODO Test what happens when playerctld is not available # TODO Test what happens when playerctld is not available
self.player = gi.repository.Playerctl.Player.new_from_name(name) self.player = gi.repository.Playerctl.Player.new_from_name(name)
@ -768,8 +791,8 @@ class MprisProvider(MirrorProvider):
else: else:
self.player = None self.player = None
def update_sections(self) -> None: def updateSections(self) -> None:
self.find_current_player() self.findCurrentPlayer()
if self.player is None: if self.player is None:
self.status.setText(None) self.status.setText(None)
@ -807,18 +830,18 @@ class MprisProvider(MirrorProvider):
else: else:
self.artist.setText(None) self.artist.setText(None)
self.update_title() self.updateTitle()
def update_title(self) -> None: def updateTitle(self) -> None:
if self.player is None: if self.player is None:
return return
metadata = self.player.props.metadata metadata = self.player.props.metadata
pos = self.player.props.position # In µs pos = self.player.props.position # In µs
text = f"{self.format_us(pos)}" text = f"{self.formatUs(pos)}"
dur = self.get(metadata, "mpris:length") dur = self.get(metadata, "mpris:length")
if dur: if dur:
text += f"/{self.format_us(dur)}" text += f"/{self.formatUs(dur)}"
title = self.get(metadata, "xesam:title") title = self.get(metadata, "xesam:title")
if title: if title:
text += f" {clip(title)}" text += f" {clip(title)}"
@ -829,7 +852,7 @@ class MprisProvider(MirrorProvider):
manager: gi.repository.Playerctl.PlayerManager, manager: gi.repository.Playerctl.PlayerManager,
player: gi.repository.Playerctl.Player, player: gi.repository.Playerctl.Player,
) -> None: ) -> None:
self.update_sections() self.updateSections()
def on_event( def on_event(
self, self,
@ -837,7 +860,7 @@ class MprisProvider(MirrorProvider):
_: typing.Any, _: typing.Any,
manager: gi.repository.Playerctl.PlayerManager, manager: gi.repository.Playerctl.PlayerManager,
) -> None: ) -> None:
self.update_sections() self.updateSections()
def init_player(self, name: gi.repository.Playerctl.PlayerName) -> None: def init_player(self, name: gi.repository.Playerctl.PlayerName) -> None:
player = gi.repository.Playerctl.Player.new_from_name(name) player = gi.repository.Playerctl.Player.new_from_name(name)
@ -855,7 +878,7 @@ class MprisProvider(MirrorProvider):
self, manager: gi.repository.Playerctl.PlayerManager, name: str self, manager: gi.repository.Playerctl.PlayerManager, name: str
) -> None: ) -> None:
self.init_player(name) self.init_player(name)
self.update_sections() self.updateSections()
class AlertingProvider(Provider): class AlertingProvider(Provider):
@ -939,14 +962,11 @@ class TemperatureProvider(AlertingProvider, PeriodicStatefulProvider):
RAMP = "" RAMP = ""
MAIN_TEMPS = ["coretemp", "amdgpu", "cpu_thermal"] MAIN_TEMPS = ["coretemp", "amdgpu", "cpu_thermal"]
# For Intel, AMD and ARM respectively. # For Intel, AMD and ARM respectively.
# FIXME Threshold doesn't seem to match old version
main: str main: str
async def init(self) -> None: async def init(self) -> None:
self.section.numberStates = 2 self.section.numberStates = 2
self.warningThreshold = 75
self.dangerThreshold = 95
allTemp = psutil.sensors_temperatures() allTemp = psutil.sensors_temperatures()
for main in self.MAIN_TEMPS: for main in self.MAIN_TEMPS:
@ -957,8 +977,8 @@ class TemperatureProvider(AlertingProvider, PeriodicStatefulProvider):
raise IndexError("Could not find suitable temperature sensor") raise IndexError("Could not find suitable temperature sensor")
temp = allTemp[self.main][0] temp = allTemp[self.main][0]
self.warningThresold = temp.high or 90.0 self.warningThreshold = temp.high or 90.0
self.dangerThresold = temp.critical or 100.0 self.dangerThreshold = temp.critical or 100.0
async def loop(self) -> None: async def loop(self) -> None:
allTemp = psutil.sensors_temperatures() allTemp = psutil.sensors_temperatures()
@ -1200,6 +1220,7 @@ class TimeProvider(PeriodicStatefulProvider):
async def main() -> None: async def main() -> None:
# TODO Configurable
FROGARIZED = [ FROGARIZED = [
"#092c0e", "#092c0e",
"#143718", "#143718",
@ -1218,7 +1239,6 @@ async def main() -> None:
"#5c73c4", "#5c73c4",
"#d43982", "#d43982",
] ]
# TODO Configurable
# TODO Not super happy with the color management, # TODO Not super happy with the color management,
# while using an existing library is great, it's limited to ANSI colors # while using an existing library is great, it's limited to ANSI colors
@ -1256,10 +1276,18 @@ async def main() -> None:
leftPreferred = 0 if dualScreen else None leftPreferred = 0 if dualScreen else None
rightPreferred = 1 if dualScreen else None rightPreferred = 1 if dualScreen else None
workspaces_suffixes = "▲■"
workspaces_names = dict(
(str(i + 1), f"{i+1} {c}") for i, c in enumerate(workspaces_suffixes)
)
color = rich.color.Color.parse color = rich.color.Color.parse
bar.addProvider(I3ModeProvider(color=color("red")), alignment=Alignment.LEFT) bar.addProvider(I3ModeProvider(color=color("red")), alignment=Alignment.LEFT)
bar.addProvider(I3WorkspacesProvider(), alignment=Alignment.LEFT) bar.addProvider(
I3WorkspacesProvider(custom_names=workspaces_names), alignment=Alignment.LEFT
)
if dualScreen: if dualScreen:
bar.addProvider( bar.addProvider(
I3WindowTitleProvider(color=color("white")), I3WindowTitleProvider(color=color("white")),
@ -1271,6 +1299,15 @@ async def main() -> None:
screenNum=rightPreferred, screenNum=rightPreferred,
alignment=Alignment.CENTER, alignment=Alignment.CENTER,
) )
else:
bar.addProvider(
SpacerProvider(),
alignment=Alignment.LEFT,
)
bar.addProvider(
MprisProvider(color=color("bright_white")),
alignment=Alignment.LEFT,
)
bar.addProvider(CpuProvider(), screenNum=leftPreferred, alignment=Alignment.RIGHT) bar.addProvider(CpuProvider(), screenNum=leftPreferred, alignment=Alignment.RIGHT)
bar.addProvider(LoadProvider(), screenNum=leftPreferred, alignment=Alignment.RIGHT) bar.addProvider(LoadProvider(), screenNum=leftPreferred, alignment=Alignment.RIGHT)