def __init__(self, plugin, screen, client): self.plugin = plugin self.client = client self._obsolete = False self._active = True # This counter ensures that we don't run into # an infinite loop. If the window is configured, # we configure the actor. If the actor is configured, # we configure the window --> much fun. # Now, we increment the counter if we configure the # window. The actor will only be configured if # the counter equals 0. If it is greater than 0, # it is simply decremented. # Maybe that's not necessary, but it seems to be. self._window_configures = 0 # create the cairo stuff self.surface = create_surface(client.actor, client.screen.info.get_root_visual_type()) self.cr = cairo.cairo_create(self.surface) cairo.cairo_set_operator(self.cr, cairo.CAIRO_OPERATOR_SOURCE) cairo.cairo_set_source_surface(self.cr, self.surface, 0, 0) cairo.cairo_set_source_rgba(self.cr, 255, 0, 0, 0) self.client.push_handlers( on_focus=self.on_focus, on_updated_geom=self.on_updated_geom, on_blur=self.on_blur, ) self.client.actor.push_handlers( on_configure_notify=self.actor_on_configure_notify, on_expose=self.on_expose, on_button_press=self.on_button_press, ) self.client.window.push_handlers( on_property_notify=self.on_property_notify, on_configure_notify=self.window_on_configure_notify, on_unmap_notify=self.on_unmap_notify, on_map_notify=self.on_map_notify, ) # TODO: dirty. something's wrong with substructure and structure notify. self.client.screen.root.push_handlers( on_configure_notify=self.screen_on_configure_notify ) self.redraw()
def redraw(self): log.debug('Redrawing, active=%s, obsolete=%s' % (self._active, self._obsolete)) extents = cairo.cairo_text_extents_t() window_title = self.client.get_window_title().encode('utf-8') # <- TODO: is that too expensive? if self.client.is_focused(): bg_color = hex_to_cairo_color(config['cairodeco.color']) fg_color = hex_to_cairo_color(config['cairodeco.title.color']) else: bg_color = hex_to_cairo_color(config.get('cairodeco.inactive_color', config['cairodeco.color'])) fg_color = hex_to_cairo_color(config.get('cairodeco.title.inactive_color', config['cairodeco.title.color'])) cairo.cairo_set_source_rgba(self.cr, bg_color[0], bg_color[1], bg_color[2], 1) cairo.cairo_set_operator(self.cr, cairo.CAIRO_OPERATOR_SOURCE) cairo.cairo_paint(self.cr) cairo.cairo_set_operator(self.cr, cairo.CAIRO_OPERATOR_OVER) cairo.cairo_set_source_rgba(self.cr, fg_color[0], fg_color[1], fg_color[2], 1) cairo.cairo_show_text(self.cr, window_title) cairo.cairo_text_extents(self.cr, window_title, extents) width = self.client.geom.width x = 0 if config['cairodeco.title.position'] == 'left': x = 0 elif config['cairodeco.title.position'] == 'right': x = width - extents.x_advance elif config['cairodeco.title.position'] == 'center': x = (width - extents.x_advance) / 2 cairo.cairo_move_to(self.cr, x, config['cairodeco.height'] - (config['cairodeco.height'] - extents.height) / 2.0) self.client.conn.flush()
with conn.bunch(): win = xproto.Window.create_toplevel_on_screen(conn, screen, width=width, height=height, back_pixel=screen.white_pixel, event_mask=xproto.EventMask.Exposure | xproto.EventMask.ButtonPress ) win.map() # create a surface for this window surface = cairo.cairo_xcb_surface_create(conn, win, visualtype, width, height) # and a cairo context cr = cairo.cairo_create(surface) cairo.cairo_set_operator(cr, cairo.CAIRO_OPERATOR_SOURCE) cairo.cairo_set_source_surface(cr, surface, 0, 0) cairo.cairo_set_source_rgba(cr, 255, 0, 0, 0) @win.event def on_expose(event): # paint a red rectangle when an expose event occurs cairo.cairo_set_source_rgb(cr, 255, 0, 0) cairo.cairo_rectangle(cr, 100, 100, 300, 300) cairo.cairo_fill(cr) # don't forget to flush! conn.flush() @win.event def on_button_press(event): global running