def _render_surface(self, surface: Surface, sx: int, sy: int, rdata: Tuple) -> None: texture = surface.get_texture() if texture is None: return now, window, wx, wy, opacity, scale = rdata x = (wx + sx) * scale y = (wy + sy) * scale width = surface.current.width * scale height = surface.current.height * scale transform_matrix = self.transform_matrix if window.borderwidth: bw = int(window.borderwidth * scale) if surface == window.surface.surface: outer_w = width + bw * 2 outer_h = height + bw * 2 num = len(window.bordercolor) bws = [bw // num] * num for i in range(bw % num): bws[i] += 1 coord = 0 for i, bc in enumerate(window.bordercolor): border = Box( int(x + coord), int(y + coord), int(outer_w - coord * 2), int(bws[i]), ) self.renderer.render_rect(border, bc, transform_matrix) # Top border border.y = int(y + outer_h - bws[i] - coord) self.renderer.render_rect( border, bc, transform_matrix) # Bottom border border.y = int(y + coord) border.width = int(bws[i]) border.height = int(outer_h - coord * 2) self.renderer.render_rect(border, bc, transform_matrix) # Left border border.x = int(x + outer_w - bws[i] - coord) self.renderer.render_rect(border, bc, transform_matrix) # Right border coord += bws[i] x += bw y += bw box = Box( int(x), int(y), int(width), int(height), ) inverse = wlrOutput.transform_invert(surface.current.transform) matrix = Matrix.project_box(box, inverse, 0, transform_matrix) self.renderer.render_texture_with_matrix(texture, matrix, opacity) surface.send_frame_done(now)
def _render_surface( self, surface: Surface, sx: int, sy: int, data: Tuple[Output, View, Timespec] ) -> None: output, view, now = data texture = surface.get_texture() if texture is None: return ox, oy = self._output_layout.output_coords(output) ox += view.x + sx oy += view.y + sy box = Box( int(ox * output.scale), int(oy * output.scale), int(surface.current.width * output.scale), int(surface.current.height * output.scale), ) transform = surface.current.transform inverse = Output.transform_invert(transform) matrix = Matrix.project_box(box, inverse, 0, output.transform_matrix) self._renderer.render_texture_with_matrix(texture, matrix, 1) surface.send_frame_done(now)
def _render_surface(self, surface: Surface, sx: int, sy: int, rdata: Tuple) -> None: texture = surface.get_texture() if texture is None: return now, window, wx, wy, opacity, scale = rdata x = (wx + sx) * scale y = (wy + sy) * scale width = surface.current.width * scale height = surface.current.height * scale transform_matrix = self.transform_matrix if window.borderwidth: bw = window.borderwidth * scale if surface == window.surface.surface: bc = window.bordercolor border = Box( int(x), int(y), int(width + bw * 2), int(bw), ) x += bw y += bw self.renderer.render_rect(border, bc, transform_matrix) # Top border border.y = int(y + height) self.renderer.render_rect(border, bc, transform_matrix) # Bottom border border.y = int(y - bw) border.width = int(bw) border.height = int(height + bw * 2) self.renderer.render_rect(border, bc, transform_matrix) # Left border border.x = int(x + width) self.renderer.render_rect(border, bc, transform_matrix) # Right border else: x += bw y += bw box = Box( int(x), int(y), int(width), int(height), ) inverse = wlrOutput.transform_invert(surface.current.transform) matrix = Matrix.project_box(box, inverse, 0, transform_matrix) self.renderer.render_texture_with_matrix(texture, matrix, opacity) surface.send_frame_done(now)
def _render_dnd_icon( self, dnd: Dnd, now: Timespec, scale: float, transform_matrix: Matrix ) -> None: """Render the drag-n-drop icon if there is one.""" icon = dnd.wlr_drag.icon if icon.mapped: texture = icon.surface.get_texture() if texture: box = Box( int((dnd.x - self.x) * scale), int((dnd.y - self.y) * scale), int(icon.surface.current.width * scale), int(icon.surface.current.height * scale), ) inverse = wlrOutput.transform_invert(icon.surface.current.transform) matrix = Matrix.project_box(box, inverse, 0, transform_matrix) self.renderer.render_texture_with_matrix(texture, matrix, 1) icon.surface.send_frame_done(now)
def _on_frame(self, _listener, _data): wlr_output = self.wlr_output with PixmanRegion32() as damage: if not self._damage.attach_render(damage): # no new frame needed wlr_output.rollback() return with wlr_output: if not damage.not_empty(): # No damage, only buffer swap needed return now = Timespec.get_monotonic_time() renderer = self.renderer renderer.begin(wlr_output._ptr.width, wlr_output._ptr.height) scale = wlr_output.scale if self.wallpaper: width, height = wlr_output.effective_resolution() box = Box(0, 0, int(width * scale), int(height * scale)) matrix = Matrix.project_box(box, wlr_output.transform, 0, wlr_output.transform_matrix) renderer.render_texture_with_matrix( self.wallpaper, matrix, 1) else: renderer.clear([0, 0, 0, 1]) mapped = (self.layers[LayerShellV1Layer.BACKGROUND] + self.layers[LayerShellV1Layer.BOTTOM] + self.core.mapped_windows + self.layers[LayerShellV1Layer.TOP] + self.layers[LayerShellV1Layer.OVERLAY]) for window in mapped: if isinstance(window, Internal): box = Box( int((window.x - self.x) * scale), int((window.y - self.y) * scale), int(window.width * scale), int(window.height * scale), ) matrix = Matrix.project_box( box, wlr_output.transform, 0, wlr_output.transform_matrix) renderer.render_texture_with_matrix( window.texture, matrix, window.opacity) else: rdata = ( now, window, window.x - self.x, # layout coordinates -> output coordinates window.y - self.y, window.opacity, wlr_output.scale, ) window.surface.for_each_surface( self._render_surface, rdata) if self.core.live_dnd: self._render_dnd_icon(now) wlr_output.render_software_cursors(damage=damage) renderer.end()
def _on_frame(self, _listener: Listener, _data: Any) -> None: with PixmanRegion32() as damage: try: if not self._damage.attach_render(damage): # No new frame needed. self.wlr_output.rollback() return except RuntimeError: # Failed to attach render; skip. return with self.wlr_output as wlr_output: if not damage.not_empty(): # No damage, only buffer swap needed. return now = Timespec.get_monotonic_time() scale = wlr_output.scale transform_matrix = wlr_output.transform_matrix with self.renderer.render( wlr_output._ptr.width, wlr_output._ptr.height ) as renderer: if self.wallpaper: width, height = wlr_output.effective_resolution() box = Box(0, 0, int(width * scale), int(height * scale)) matrix = Matrix.project_box(box, no_transform, 0, transform_matrix) renderer.render_texture_with_matrix(self.wallpaper, matrix, 1) else: renderer.clear([0, 0, 0, 1]) mapped: Sequence[WindowType] = ( self.layers[LayerShellV1Layer.BACKGROUND] + self.layers[LayerShellV1Layer.BOTTOM] + self.core.mapped_windows # type: ignore + self.layers[LayerShellV1Layer.TOP] + self.layers[LayerShellV1Layer.OVERLAY] ) for window in mapped: if isinstance(window, Internal): box = Box( int((window.x - self.x) * scale), int((window.y - self.y) * scale), int(window.width * scale), int(window.height * scale), ) matrix = Matrix.project_box(box, no_transform, 0, transform_matrix) renderer.render_texture_with_matrix( window.texture, matrix, window.opacity ) else: rdata = ( now, window, window.x - self.x, # layout coordinates -> output coordinates window.y - self.y, window.opacity, scale, transform_matrix, ) window.surface.for_each_surface(self._render_surface, rdata) if self.core.live_dnd: self._render_dnd_icon(self.core.live_dnd, now, scale, transform_matrix) wlr_output.render_software_cursors(damage=damage)