def init_screens(self) -> list[Screen]: """Creates and returns the screens to be used.""" self.screens = [ Screen( wallpaper=self.theme_config.wallpaper["path"], wallpaper_mode="fill", top=Bar( self.widgets_maker.init_widgets(), 32, opacity=0.95, margin=6, ), ), ] monitors: list[str] = get_monitors() if len(monitors) > 1: subprocess.call(["autorandr"]) for _ in range(1, len(monitors)): self.screens.append( Screen( wallpaper=self.theme_config.wallpaper["path"], wallpaper_mode="fill", top=Bar( self.widgets_maker.init_other_widgets(), 32, opacity=0.95, margin=6, ), )) return self.screens
def test_clock_invalid_timezone(fake_qtile, monkeypatch): """ test clock widget with invalid timezone (and no pytz or dateutil modules) """ class FakeDateutilTZ: @classmethod def tz(cls): return cls @classmethod def gettz(cls, val): return None # pytz and dateutil must not be in the sys.modules dict... monkeypatch.delitem(sys.modules, "pytz") monkeypatch.delitem(sys.modules, "dateutil") # Set up references to pytz and dateutil so we know these aren't being used # If they're called, the widget would try to run None(self.timezone) which # would raise an exception clock.pytz = None clock.dateutil = FakeDateutilTZ # Fake datetime module just adds the timezone value to the time clk2 = clock.Clock(timezone="1") fakebar = Bar([clk2], 24) fakebar.window = FakeWindow() fakebar.width = 10 fakebar.height = 10 fakebar.draw = no_op clk2._configure(fake_qtile, fakebar) # An invalid timezone current causes a TypeError with pytest.raises(TypeError): clk2.poll()
def test_clock_datetime_timezone(fake_qtile, monkeypatch): """ test clock with datetime timezone """ class FakeDateutilTZ: class TZ: @classmethod def gettz(cls, val): None tz = TZ # Set up references to pytz and dateutil so we know these aren't being used # If they're called, the widget would try to run None(self.timezone) which # would raise an exception clock.pytz = None clock.dateutil = FakeDateutilTZ # Fake datetime module just adds the timezone value to the time clk3 = clock.Clock(timezone=1) fakebar = Bar([clk3], 24) fakebar.window = FakeWindow() fakebar.width = 10 fakebar.height = 10 fakebar.draw = no_op clk3._configure(fake_qtile, fakebar) text = clk3.poll() # Default time is 10:20 and we add 1 hour for the timezone assert text == "11:20"
def test_keyboard_kbdd_colours(fake_qtile, patched_widget, fake_window): MockSpawn.call_count = 1 kbd = patched_widget.KeyboardKbdd(configured_keyboards=["gb", "us"], colours=["#ff0000", "#00ff00"]) fakebar = Bar([kbd], 24) fakebar.window = fake_window fakebar.width = 10 fakebar.height = 10 fakebar.draw = no_op kbd._configure(fake_qtile, fakebar) # Create a message with the index of the active keyboard message = MockMessage(body=0) kbd._signal_received(message) assert kbd.layout.colour == "#ff0000" # Create a message with the index of the active keyboard message = MockMessage(body=1) kbd._signal_received(message) assert kbd.layout.colour == "#00ff00" # No change where self.colours is a string kbd.colours = "#ffff00" kbd._set_colour(1) assert kbd.layout.colour == "#00ff00" # Colours list is shorter than length of layouts kbd.colours = ["#ff00ff"] # Should pick second item in colours list but it doesn't exit # so widget looks for previous item kbd._set_colour(1) assert kbd.layout.colour == "#ff00ff"
def test_window_count(): wc = WindowCount() fakebar = Bar([wc], 24) wc.bar = fakebar qtile = FakeQtile() wc.qtile = qtile wc._setup_hooks() # No windows opened assert wc._count == 0 # Add a window and check count qtile.add_window() assert wc._count == 1 # Add a window and check text qtile.add_window() assert wc.text == "2" # Change to empty group qtile.switch_group() assert wc._count == 0 # Change back to group qtile.switch_group() assert wc._count == 2 # Close all windows and check count is 0 and widget not displayed qtile.close_window() qtile.close_window() assert wc._count == 0 assert wc.calculate_length() == 0
def test_widgetbox_widget(manager): manager.conn = xcbq.Connection(manager.display) # We need to trick the widgets into thinking this is libqtile.qtile so # we add some methods that are called when the widgets are configured manager.call_soon = no_op manager.register_widget = no_op tb_one = TextBox(name="tb_one", text="TB ONE") tb_two = TextBox(name="tb_two", text="TB TWO") # Give widgetbox invalid value for button location widget_box = WidgetBox([tb_one, tb_two], close_button_location="middle", fontsize=10) # Create a bar and set attributes needed to run widget fakebar = Bar([widget_box], 24) fakebar.window = FakeWindow() fakebar.width = 10 fakebar.height = 10 fakebar.draw = no_op # Configure the widget box widget_box._configure(manager, fakebar) # Invalid value should be corrected to default assert widget_box.close_button_location == "left" # Check only widget in bar is widgetbox assert fakebar.widgets == [widget_box] # Open box widget_box.cmd_toggle() # Check it's open assert widget_box.box_is_open # Default text position is left assert fakebar.widgets == [widget_box, tb_one, tb_two] # Close box widget_box.cmd_toggle() # Check it's closed assert not widget_box.box_is_open # Check widgets have been removed assert fakebar.widgets == [widget_box] # Move button to right-hand side widget_box.close_button_location = "right" # Re-open box with new layout widget_box.cmd_toggle() # Now widgetbox is on the right assert fakebar.widgets == [tb_one, tb_two, widget_box]
def test_bluetooth_setup(monkeypatch, minimal_conf_noscreen, manager_nospawn): monkeypatch.setattr("libqtile.widget.bluetooth.MessageBus", MockMessageBus) widget = libqtile.widget.bluetooth.Bluetooth() config = minimal_conf_noscreen config.screens = [Screen(top=Bar([widget], 10))] manager_nospawn.start(config) text = manager_nospawn.c.widget["bluetooth"].info()["text"] assert text == "Mock Bluetooth Device"
def test_wlan_display(minimal_conf_noscreen, manager_nospawn, patched_wlan, kwargs, expected): widget = patched_wlan.Wlan(**kwargs) config = minimal_conf_noscreen config.screens = [libqtile.config.Screen(top=Bar([widget], 10))] manager_nospawn.start(config) text = manager_nospawn.c.bar["top"].info()["widgets"][0]["text"] assert text == expected
def test_imapwidget(fake_qtile, monkeypatch, fake_window, patched_imap): imap = patched_imap.ImapWidget(user="******") fakebar = Bar([imap], 24) fakebar.window = fake_window fakebar.width = 10 fakebar.height = 10 fakebar.draw = no_op imap._configure(fake_qtile, fakebar) text = imap.poll() assert text == "INBOX: 2"
def init_screen(main: bool = False): gap = Gap(10) return Screen(bottom=gap, left=gap, right=gap, top=Bar(init_widget_list(), 26, background=colors[0][0], opacity=.75, margin=[0, 0, 10, 0]))
def clipboard_manager(request, minimal_conf_noscreen, manager_nospawn): widget = libqtile.widget.Clipboard(**getattr(request, "param", dict())) config = minimal_conf_noscreen config.screens = [Screen(top=Bar([widget], 10))] manager_nospawn.start(config) if manager_nospawn.backend.name != "x11": pytest.skip("Test only available on X11.") yield manager_nospawn
def create_bar(main=False): widgets = [ w.CurrentLayoutIcon(scale=0.8, foreground=colors["foreground"]), w.GroupBox( active=colors["foreground"], inactive=colors["color8"], other_current_screen_border=colors["color8"], other_screen_border=colors["color8"], this_current_screen_border=colors["color4"], this_screen_border=colors["color12"], urgent_border=colors["color1"], urgent_text=colors["color1"], disable_drag=True, ), w.TextBox("", fontsize=22), w.Spacer(), w.TextBox("", fontsize=22), *[ w.DF( foreground=colors["color1"], format=" <span weight='bold'>{p} ({uf}{m}|{r:.0f}%)</span>", partition=path, warn_space=5, ) for path in ["/", "/home/"] ], w.PulseVolume(emoji=False, fmt="墳 <span weight='bold'>{}</span>"), w.Battery( battery="BAT0", unknown_char="", charge_char="", discharge_char="", empty_char="", format="{char} <span weight='bold'>{percent:2.0%}</span>", ), w.Clock(fmt=" <span weight='bold'>{}</span>"), ] if main: widgets.append(w.Systray()) else: widgets.append( w.CPUGraph( border_width=2, border_color=colors["color7"], graph_color=colors["color7"], fill_color=colors["color7"], ) ) return Bar( widgets, bar_height, background=colors["background"], opacity=0.8, )
def test_openweather_parse( patch_openweather, minimal_conf_noscreen, manager_nospawn, params, expected ): """Check widget parses output correctly for display.""" config = minimal_conf_noscreen config.screens = [ libqtile.config.Screen(top=Bar([patch_openweather.OpenWeather(**params)], 10)) ] manager_nospawn.start(config) info = manager_nospawn.c.widget["openweather"].info()["text"] assert info == expected
def cpu_manager(monkeypatch, manager_nospawn, minimal_conf_noscreen): monkeypatch.setitem(sys.modules, "psutil", MockPsutil("psutil")) from libqtile.widget import cpu reload(cpu) config = minimal_conf_noscreen config.screens = [libqtile.config.Screen(top=Bar([cpu.CPU()], 10))] manager_nospawn.start(config) yield manager_nospawn
def test_no_update_available_without_no_update_string(fake_qtile): """ test output with no update (without dedicated string nor color) """ cu3 = CheckUpdates(distro=good_distro, custom_command=cmd_0_line) fakebar = Bar([cu3], 24) fakebar.window = FakeWindow() fakebar.width = 10 fakebar.height = 10 fakebar.draw = no_op cu3._configure(fake_qtile, fakebar) text = cu3.poll() assert text == ""
def test_clock(fake_qtile, monkeypatch): """ test clock output with default settings """ monkeypatch.setattr("libqtile.widget.clock.datetime", MockDatetime) clk1 = clock.Clock() fakebar = Bar([clk1], 24) fakebar.window = FakeWindow() fakebar.width = 10 fakebar.height = 10 fakebar.draw = no_op clk1._configure(fake_qtile, fakebar) text = clk1.poll() assert text == "10:20"
def test_imapwidget_keyring_error(fake_qtile, monkeypatch, fake_window, patched_imap): patched_imap.keyring.valid = False imap = patched_imap.ImapWidget(user="******") fakebar = Bar([imap], 24) fakebar.window = fake_window fakebar.width = 10 fakebar.height = 10 fakebar.draw = no_op imap._configure(fake_qtile, fakebar) text = imap.poll() assert text == "Gnome Keyring Error"
def test_widgetbox_widget(fake_qtile, fake_window): tb_one = TextBox(name="tb_one", text="TB ONE") tb_two = TextBox(name="tb_two", text="TB TWO") # Give widgetbox invalid value for button location widget_box = WidgetBox([tb_one, tb_two], close_button_location="middle", fontsize=10) # Create a bar and set attributes needed to run widget fakebar = Bar([widget_box], 24) fakebar.window = fake_window fakebar.width = 10 fakebar.height = 10 fakebar.draw = no_op # Configure the widget box widget_box._configure(fake_qtile, fakebar) # Invalid value should be corrected to default assert widget_box.close_button_location == "left" # Check only widget in bar is widgetbox assert fakebar.widgets == [widget_box] # Open box widget_box.cmd_toggle() # Check it's open assert widget_box.box_is_open # Default text position is left assert fakebar.widgets == [widget_box, tb_one, tb_two] # Close box widget_box.cmd_toggle() # Check it's closed assert not widget_box.box_is_open # Check widgets have been removed assert fakebar.widgets == [widget_box] # Move button to right-hand side widget_box.close_button_location = "right" # Re-open box with new layout widget_box.cmd_toggle() # Now widgetbox is on the right assert fakebar.widgets == [tb_one, tb_two, widget_box]
def test_gmail_checker_valid_response(fake_qtile, monkeypatch, fake_window): monkeypatch.setitem(sys.modules, "imaplib", FakeIMAP("imaplib")) reload(gmail_checker) gmc = gmail_checker.GmailChecker(username="******", password="******") fakebar = Bar([gmc], 24) fakebar.window = fake_window fakebar.width = 10 fakebar.height = 10 fakebar.draw = no_op gmc._configure(fake_qtile, fakebar) text = gmc.poll() assert text == "inbox[10],unseen[2]"
def test_gmail_checker_invalid_response(fake_qtile, monkeypatch, fake_window): monkeypatch.setitem(sys.modules, "imaplib", FakeIMAP("imaplib")) reload(gmail_checker) gmc = gmail_checker.GmailChecker() fakebar = Bar([gmc], 24) fakebar.window = fake_window fakebar.width = 10 fakebar.height = 10 fakebar.draw = no_op gmc._configure(fake_qtile, fakebar) text = gmc.poll() assert text == "UNKNOWN ERROR"
def patched_moc(fake_qtile, monkeypatch, fake_window): widget = moc.Moc() MockMocpProcess.reset() monkeypatch.setattr(widget, "call_process", MockMocpProcess.run) monkeypatch.setattr("libqtile.widget.moc.subprocess.Popen", MockMocpProcess.run) fakebar = Bar([widget], 24) fakebar.window = fake_window fakebar.width = 10 fakebar.height = 10 fakebar.draw = no_op widget._configure(fake_qtile, fakebar) return widget
def test_mpris2_no_metadata(fake_qtile, patched_module, fake_window): mp = patched_module.Mpris2(stop_pause_text="Test Paused") fakebar = Bar([mp], 24) fakebar.window = fake_window fakebar.width = 10 fakebar.height = 10 fakebar.draw = no_op fake_qtile.call_later = no_op mp._configure(fake_qtile, fakebar) mp.configured = True mp.message(STATUS_PLAYING) assert mp.displaytext == "No metadata for current track"
def test_df_no_warning(fake_qtile): ''' Test no text when free space over threshold ''' df1 = df.DF() fakebar = Bar([df1], 24) fakebar.window = FakeWindow() fakebar.width = 10 fakebar.height = 10 fakebar.draw = no_op df1._configure(fake_qtile, fakebar) text = df1.poll() assert text == "" df1.draw() assert df1.layout.colour == df1.foreground
def test_cmus_error_handling(fake_qtile, patched_cmus): widget = patched_cmus.Cmus() MockCmusRemoteProcess.is_error = True fakebar = Bar([widget], 24) fakebar.window = FakeWindow() fakebar.width = 10 fakebar.height = 10 fakebar.draw = no_op widget._configure(fake_qtile, fakebar) text = widget.poll() # Widget does nothing with error message so text is blank # TODO: update widget to show error? assert text == ""
def test_update_process_error(fake_qtile): """ test output where update check gives error""" cu7 = CheckUpdates(distro=good_distro, custom_command=cmd_error, no_update_string="ERROR", ) fakebar = Bar([cu7], 24) fakebar.window = FakeWindow() fakebar.width = 10 fakebar.height = 10 fakebar.draw = no_op cu7._configure(fake_qtile, fakebar) text = cu7.poll() assert text == "ERROR"
def test_imapwidget(fake_qtile, monkeypatch): monkeypatch.setitem(sys.modules, "imaplib", FakeIMAP("imaplib")) monkeypatch.setitem(sys.modules, "keyring", FakeKeyring("keyring")) from libqtile.widget import imapwidget imap = imapwidget.ImapWidget(user="******") fakebar = Bar([imap], 24) fakebar.window = FakeWindow() fakebar.width = 10 fakebar.height = 10 fakebar.draw = no_op imap._configure(fake_qtile, fakebar) text = imap.poll() assert text == "INBOX: 2"
def test_update_available(fake_qtile, fake_window): """ test output with update (check number of updates and color) """ cu2 = CheckUpdates(distro=good_distro, custom_command=cmd_1_line, colour_have_updates="#123456") fakebar = Bar([cu2], 24) fakebar.window = fake_window fakebar.width = 10 fakebar.height = 10 fakebar.draw = no_op cu2._configure(fake_qtile, fakebar) text = cu2.poll() assert text == "Updates: 1" assert cu2.layout.colour == cu2.colour_have_updates
def test_escape_text(fake_qtile, patched_cmus, fake_window): widget = patched_cmus.Cmus() # Set track to a stopped item MockCmusRemoteProcess.index = 3 fakebar = Bar([widget], 24) fakebar.window = fake_window fakebar.width = 10 fakebar.height = 10 fakebar.draw = no_op widget._configure(fake_qtile, fakebar) text = widget.poll() # It's stopped so colour should reflect this assert text == "♫ Above & Beyond - Always - Tinlicker Extended Mix"
def test_update_available_with_restart_indicator(monkeypatch, fake_qtile): """ test output with no indicator where restart needed """ cu5 = CheckUpdates(distro=good_distro, custom_command=cmd_1_line, restart_indicator="*", ) monkeypatch.setattr("os.path.exists", lambda x: True) fakebar = Bar([cu5], 24) fakebar.window = FakeWindow() fakebar.width = 10 fakebar.height = 10 fakebar.draw = no_op cu5._configure(fake_qtile, fakebar) text = cu5.poll() assert text == "Updates: 1*"
def build_widget(**kwargs): monkeypatch.setitem(sys.modules, "psutil", MockPsutil("psutil")) from libqtile.widget import net # Reload fixes cases where psutil may have been imported previously reload(net) widget = net.Net(**kwargs) fakebar = Bar([widget], 24) fakebar.window = fake_window fakebar.width = 10 fakebar.height = 10 fakebar.draw = no_op widget._configure(fake_qtile, fakebar) return widget