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