def set_source_rgb(self, colour: Union[ColorType, List[ColorType]], ctx: cairocffi.Context = None): # If an alternate context is not provided then we draw to the # drawer's default context if ctx is None: ctx = self.ctx if isinstance(colour, list): if len(colour) == 0: # defaults to black ctx.set_source_rgba(*utils.rgb("#000000")) elif len(colour) == 1: ctx.set_source_rgba(*utils.rgb(colour[0])) else: linear = cairocffi.LinearGradient(0.0, 0.0, 0.0, self.height) step_size = 1.0 / (len(colour) - 1) step = 0.0 for c in colour: rgb_col = utils.rgb(c) if len(rgb_col) < 4: rgb_col[3] = 1 linear.add_color_stop_rgba(step, *rgb_col) step += step_size ctx.set_source(linear) else: ctx.set_source_rgba(*utils.rgb(colour))
def set_source_rgb(self, colour): if type(colour) == list: if len(colour) == 0: # defaults to black self.ctx.set_source_rgba(*utils.rgb("#000000")) elif len(colour) == 1: self.ctx.set_source_rgba(*utils.rgb(colour[0])) else: linear = cairocffi.LinearGradient(0.0, 0.0, 0.0, self.height) step_size = 1.0 / (len(colour) - 1) step = 0.0 for c in colour: rgb_col = utils.rgb(c) if len(rgb_col) < 4: rgb_col[3] = 1 linear.add_color_stop_rgba(step, *rgb_col) step += step_size self.ctx.set_source(linear) else: self.ctx.set_source_rgba(*utils.rgb(colour))
def __init__(self, qtile: Qtile, win: Internal, width: int, height: int): base.Drawer.__init__(self, qtile, win, width, height) self._stride = cairocffi.ImageSurface.format_stride_for_width( cairocffi.FORMAT_ARGB32, self.width) self._source = cairocffi.ImageSurface(cairocffi.FORMAT_ARGB32, width, height) with cairocffi.Context(self._source) as context: # Initialise surface to all black context.set_source_rgba(*utils.rgb("#000000")) context.paint()
def _reset_texture(self): clear = cairocffi.ImageSurface(cairocffi.FORMAT_ARGB32, self.width, self.height) with cairocffi.Context(clear) as context: context.set_source_rgba(*utils.rgb("#000000")) context.paint() self.texture = Texture.from_pixels( self.core.renderer, DRM_FORMAT_ARGB8888, cairocffi.ImageSurface.format_stride_for_width(cairocffi.FORMAT_ARGB32, self.width), self.width, self.height, cairocffi.cairo.cairo_image_surface_get_data(clear._pointer), )
def __init__(self, qtile: Qtile, win: Internal, width: int, height: int): base.Drawer.__init__(self, qtile, win, width, height) self._target = win.texture self._stride = cairocffi.ImageSurface.format_stride_for_width( cairocffi.FORMAT_ARGB32, self.width) self._source = cairocffi.ImageSurface(cairocffi.FORMAT_ARGB32, width, height) with cairocffi.Context(self._source) as context: # Initialise surface to all black context.set_source_rgba(*utils.rgb("#000000")) context.paint() for output in qtile.core.outputs: # type: ignore if output.contains(win): break # Internals only show on one output self._output = output
def test_multiple_borders(xmanager): xmanager.test_window("one") wid = xmanager.c.window.info()["id"] name = os.path.join(tempfile.gettempdir(), 'test_multiple_borders.txt') cmd = ["import", "-border", "-window", str(wid), "-crop", "5x1+0+4", '-depth', '8', name] subprocess.run(cmd, env={"DISPLAY": xmanager.display}) with open(name, 'r') as f: data = f.readlines() os.unlink(name) # just test that each of the 5 borders is lighter than the last as the screenshot is # not pixel-perfect avg = -1 for i in range(5): color = utils.rgb(data[i + 1].split()[2]) next_avg = sum(color) / 3 assert avg < next_avg avg = next_avg
def _rgb(color: ColorType) -> ffi.CData: """Helper to create and cache float[4] arrays for border painting""" if isinstance(color, ffi.CData): return color return ffi.new("float[4]", utils.rgb(color))
def test_rgb_from_hex_string_with_alpha(): assert utils.rgb("#ff0000.5") == (1, 0, 0, 0.5)
def test_rgb_from_hex_number_with_alpha(): assert utils.rgb("ff0000.3") == (1, 0, 0, 0.3)
def test_rgb_from_hex_string(): assert utils.rgb("#00ff00") == (0, 1, 0, 1)
def test_rgb_from_hex_number(): assert utils.rgb("ff00ff") == (1, 0, 1, 1)
def test_rgb_from_base10_tuple_with_alpha(): assert utils.rgb([255, 255, 0, 0.5]) == (1, 1, 0, 0.5)
def test_rgb_from_base10_tuple(): assert utils.rgb([255, 255, 0]) == (1, 1, 0, 1)
def _configure(self, qtile, screen): # We only want to adjust margin sizes once unless there's a new strut if not self._configured or self._add_strut: Gap._configure(self, qtile, screen) self._borders_drawn = False if sum(self._initial_margin) or sum( self.border_width) or self._add_strut: try: # Check if colours are valid but don't convert to rgba here if isinstance(self.border_color, list) and len( self.border_color) == 4: [rgb(col) for col in self.border_color] else: rgb(self.border_color) self.border_color = [self.border_color] * 4 except (ValueError, TypeError): logger.warning( "Invalid border_color specified. Borders will not be displayed." ) self.border_width = [0, 0, 0, 0] # Increase the margin size for the border. The border will be drawn # in this space so the empty space will just be the margin. self.margin = [ m + b + s for m, b, s in zip( self._initial_margin, self.border_width, self.struts) ] if self.horizontal: self.x += self.margin[3] - self.border_width[3] self.width -= self.margin[1] + self.margin[3] self.length = self.width if self.size == self.initial_size: self.size += self.margin[0] + self.margin[2] if self.screen.top is self: self.y += self.margin[0] - self.border_width[0] else: self.y -= self.margin[2] + self.border_width[2] else: self.y += self.margin[0] - self.border_width[0] self.height -= self.margin[0] + self.margin[2] self.length = self.height self.size += self.margin[1] + self.margin[3] if self.screen.left is self: self.x += self.margin[3] else: self.x -= self.margin[1] width = self.width + (self.border_width[1] + self.border_width[3]) height = self.height + (self.border_width[0] + self.border_width[2]) if self.window: # We get _configure()-ed with an existing window when screens are getting # reconfigured but this screen is present both before and after self.window.place(self.x, self.y, width, height, 0, None) else: # Whereas we won't have a window if we're startup up for the first time or # the window has been killed by us no longer using the bar's screen # X11 only: # To preserve correct display of SysTray widget, we need a 24-bit # window where the user requests an opaque bar. if self.qtile.core.name == "x11": depth = (32 if has_transparency(self.background) else self.qtile.core.conn.default_screen.root_depth) self.window = self.qtile.core.create_internal( self.x, self.y, width, height, depth) else: self.window = self.qtile.core.create_internal( self.x, self.y, width, height) self.window.opacity = self.opacity self.window.unhide() self.window.process_window_expose = self.process_window_expose self.window.process_button_click = self.process_button_click self.window.process_button_release = self.process_button_release self.window.process_pointer_enter = self.process_pointer_enter self.window.process_pointer_leave = self.process_pointer_leave self.window.process_pointer_motion = self.process_pointer_motion self.window.process_key_press = self.process_key_press # We create a new drawer even if there's already a window to ensure the # drawer is the right size. self.drawer = self.window.create_drawer(width, height) self.drawer.clear(self.background) self.crashed_widgets = [] if self._configured: for i in self.widgets: self._configure_widget(i) else: for idx, i in enumerate(self.widgets): # Create a mirror if this widget is being placed on a different bar # We don't do isinstance(i, Mirror) because importing Mirror (at the top) # would give a circular import as libqtile.widget.base imports lbqtile.bar if i.configured and i.bar != self and i.__class__.__name__ != "Mirror": i = i.create_mirror() self.widgets[idx] = i success = self._configure_widget(i) if success: qtile.register_widget(i) self._remove_crashed_widgets() self.draw() self._resize(self.length, self.widgets) self._configured = True self._add_strut = False
def test_rgb(self): assert utils.rgb([255, 255, 0, 0.5]) == (1, 1, 0, 0.5) assert utils.rgb([255, 255, 0]) == (1, 1, 0, 1) assert utils.rgb("ff0000") == (1, 0, 0, 1) assert utils.rgb("ff0000.5") == (1, 0, 0, 0.5)