示例#1
0
 def on_ready(self, app):
     firsttimefile = config.get('help.first_time_file', 
             os.path.expanduser('~/.samuraix/firsttime')
     )
 
     if os.path.exists(firsttimefile) or config.get('help.no_first_time', False):
         return 
     else: 
         filedir = os.path.dirname(firsttimefile)
         if not os.path.exists(filedir):
             os.makedirs(filedir)
         with open(firsttimefile, 'w') as f:
             f.write('hello')
         self.show_help()
示例#2
0
    def add_client(self, client):
        """
            add a client. if the window as a _NET_WM_DESKTOP example,
            respect it, otherwise place it on the active desktop.
        """
        desktops = [self.active_desktop]
        reply = client.window.get_property('_NET_WM_DESKTOP', 'CARDINAL').reply()
        if reply.exists:
            # has a property like this
            desktop_idx = reply.value[0]
            if desktop_idx < len(self.desktops):
                # we have this desktop!
                log.debug('Placing %s on desktop %d' % (client, desktop_idx))
                desktops = [self.desktops[desktop_idx]]
            elif desktop_idx == 0xffffffff:
                desktops = self.desktops

        if self.screen.conn.atoms['_NET_WM_STATE_STICKY'] in client.state:
            desktops = self.desktops

        for desktop in desktops:
            # so, either the window doesn't have this property
            # or we don't have this desktop index, so place it on the active desktop
            desktop.add_client(client)

            # should it be focused automatically? but don't do if it isn't
            # the active desktop
            if (desktop.active and config.get('desktops.autofocus', True)):
                self.screen.focus(client)
示例#3
0
    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()
示例#4
0
 def on_load_config(self, config):
     #self.names = config.get('desktops.names', ['one desktop'])
     self.config = config.get('desktops.desktops', ())
示例#5
0
    def create_actor_window(self):
        screen = self.screen
        client = self.client
        colormap = client.window.get_attributes().reply().colormap
        config = self.plugin.config

        geom = self.client.window.get_geometry().reply()
        # dont know how to get this from client.window so setting it to 0 
        client.window.configure(border_width=0)
        window_border = 0
        border = 2
        title_height = config.get('decorator.title.height', 20)

        client.actor = xproto.Window.create(self.plugin.app.conn,
                screen.root,
                screen.info.root_depth,
                screen.info.root_visual,
                geom.x,
                geom.y,
                # dont forget the borders of client.border in this calculation
                geom.width + (2*border) + (2*window_border),
                geom.height + title_height + (2*border) + (2*window_border),
                override_redirect=True,
                back_pixel=screen.info.white_pixel,
                colormap=colormap,
                # does this help flickering probs? im not sure...
                backing_store=xproto.BackingStore.WhenMapped,
                event_mask=
                    xproto.EventMask.Exposure |
                    xproto.EventMask.StructureNotify |
                    # Child.StructureNotify and Parent.SubstructureNotify
                    # seem to block each other. That's not what we want.
                    # I commented this out, and it seems to work.
                    #xproto.EventMask.SubstructureNotify |
                    xproto.EventMask.SubstructureRedirect |
                    xproto.EventMask.ButtonPress,
                )

        client.window.add_to_save_set()
        client.window.reparent(client.actor)
        log.debug('created client actor client=%s actor=%s', client, client.actor)

        # check if we are on the active desktop. unban/ban
        # the client to get a valid WM_STATE and map the
        # actor window if needed.
        current = client.screen.info.ewmh_get_current_desktop()
        desktop = client.window.ewmh_get_desktop()
        if (current is None or current == desktop):
            log.debug('Unbanning %s because it is on the active desktop.' % client)
            client.unban()
        else:
            log.debug('Banning %s because it is not on an active desktop (active=%s, client\'s=%s)' % (client, current, desktop))
            client.ban(False, False)

        self.ui = ui.TopLevelContainer(
                client.actor, 
                screen.info.get_root_visual_type(),
                style=config.get('decorator.actor.style', self.default_actor_style),
                layouter=ui.VerticalLayouter,
        )
        window_title = self.client.get_window_title().encode('utf-8')

        title_sizer = ui.Container(
            style={'height': title_height},
            layouter=ui.HorizontalLayouter,
        )
        self.ui.add_child(title_sizer)

        def make_func(bindings):
            parsed_bindings = {}
            for k, v in bindings.iteritems():
                parsed_bindings[parse_buttonstroke(k)] = v
            def r(e):
                try:
                    func = parsed_bindings[(e.state, e.detail)]
                except KeyError:
                    return 
                if type(func) == str:
                    self.plugin.app.plugins['actions'].emit(func, {
                            'screen': screen,
                            'x': e.event_x,
                            'y': e.event_y,
                            'client': self.client,
                    })
                else:
                    func()
            return r

        for button in config.get('decorator.buttons.leftside', []):
            but = ui.PangoLabel(
                text=button.get('text'),
                style=button.get('style'),
                on_button_press=make_func(button.get('bindings')),
            )
            title_sizer.add_child(but)

        self.title = ui.PangoLabel(
            text=window_title,
            style=config.get('decorator.title.style', self.default_title_style),
            on_button_press=make_func(config.get('decorator.title.bindings')),
        )
        title_sizer.add_child(self.title)

        for button in config.get('decorator.buttons.rightside', []):
            but = ui.Label(
                text=button.get('text'),
                style=button.get('style'),
                on_button_press=make_func(button.get('bindings')),
            )
            title_sizer.add_child(but)

        style = config.get('decorator.clientwindow.style', self.default_clientwindow_style).copy()
        style['width'] = geom.width
        style['height'] = geom.height

        self.clientwin = ClientWindow(
            client.window,
            style=style,
        )
        self.ui.add_child(self.clientwin)
        #self.ui.layout()
        #log.debug('after layout size is %s %s', self.ui.width, self.ui.height)
        #self.ui.render()

        client.push_handlers(
                on_focus=self.on_focus,
                #on_updated_geom=self.on_updated_geom,
                on_blur=self.on_blur,
                #on_handle_net_wm_state=self.on_handle_net_wm_state,
        )

        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.
        #client.screen.root.push_handlers(
        #        #on_configure_notify=self.screen_on_configure_notify,
        #)

        client.actor.push_handlers(
                on_configure_request=self.actor_on_configure_request,
        )

        self.ui.fit()
        self.clientwin.style['width'] = None
        self.clientwin.style['height'] = None
示例#6
0
 def on_load_config(self, config):
     for stroke, action in config.get('clientbuttons.bindings', {}).iteritems():
         buttonstroke = parse_buttonstroke(stroke)
         self.bindings[buttonstroke] = action
示例#7
0
 def on_load_config(self, config):
     self.focus_method = self.styles[config.get('focus.style', 'click')]
示例#8
0
 def on_load_config(self, config):
     for stroke, action in config.get('cairodeco.bindings', {}).iteritems():
         self.bindings[parse_buttonstroke(stroke)] = action
示例#9
0
 def show_help(self, *ignore):
     url = config.get('help.url', 'http://samurai-x.org/wiki/UserManual')
     log.warning('showing da help')
     webbrowser.open(url)