Ejemplo n.º 1
0
def workspace(pl, segment_info, workspace=None, strip=False):
    '''Return the specified workspace name

	:param str workspace:
		Specifies which workspace to show. If unspecified, may be set by the 
		``list_workspaces`` lister if used, otherwise falls back to 
		currently focused workspace.

	:param bool strip:
		Specifies whether workspace numbers (in the ``1: name`` format) should 
		be stripped from workspace names before being displayed. Defaults to false.

	Highlight groups used: ``workspace`` or ``w_visible``, ``workspace`` or ``w_focused``, ``workspace`` or ``w_urgent``.
	'''
    if workspace:
        try:
            w = next((w for w in get_i3_connection().get_workspaces()
                      if w['name'] == workspace))
        except StopIteration:
            return None
    elif segment_info.get('workspace'):
        w = segment_info['workspace']
    else:
        try:
            w = next((w for w in get_i3_connection().get_workspaces()
                      if w['focused']))
        except StopIteration:
            return None

    return [{
        'contents': format_name(w['name'], strip=strip),
        'highlight_groups': workspace_groups(w)
    }]
Ejemplo n.º 2
0
def get_icon(w, separator, icons, show_multiple_icons):
    if 'dummy' in w:
        return ""
    icons_tmp = WS_ICONS
    icons_tmp.update(icons)
    icons = icons_tmp

    ws_containers = {
        w_con.name: w_con
        for w_con in get_i3_connection().get_tree().workspaces()
    }
    wins = [
        win for win in ws_containers[w['name']].leaves()
        if win.parent.scratchpad_state == 'none'
    ]
    if len(wins) == 0:
        return ""

    result = ""
    cnt = 0
    for key in icons:
        if not icons[key] or len(icons[key]) < 1:
            continue
        if any(key in win.window_class for win in wins if win.window_class):
            result += separator + icons[key]
            cnt += 1
    if not show_multiple_icons and cnt > 1:
        if 'multiple' in icons:
            return separator + icons['multiple']
        else:
            return ""
    return result
Ejemplo n.º 3
0
def workspace_lister(pl, segment_info, only_show=None, output=None):
    '''List all workspaces in segment_info format

	Sets the segment info values of ``workspace`` and ``output`` to the name of 
	the i3 workspace and the ``xrandr`` output respectively and the keys
	``"visible"``, ``"urgent"`` and ``"focused"`` to a boolean indicating these
	states.

	:param list only_show:
		Specifies which workspaces to list. Valid entries are ``"visible"``, 
		``"urgent"`` and ``"focused"``. If omitted or ``null`` all workspaces 
		are listed.

	:param str output:
		May be set to the name of an X output. If specified, only workspaces 
		on that output are listed. Overrides automatic output detection by 
		the lemonbar renderer and bindings. Set to ``false`` to force 
		all workspaces to be shown.
	'''

    if output == None:
        output = output or segment_info.get('output')

    return ((updated(
        segment_info,
        output=w.output,
        workspace=w,
    ), {
        'draw_inner_divider': None
    }) for w in get_i3_connection().get_workspaces()
            if (((not only_show or any(getattr(w, typ)
                                       for typ in only_show)) and (
                                           not output or w.output == output))))
Ejemplo n.º 4
0
def workspaces(pl, segment_info, only_show=None, output=None, strip=0):
    '''Return list of used workspaces

	:param list only_show:
		Specifies which workspaces to show. Valid entries are ``"visible"``, 
		``"urgent"`` and ``"focused"``. If omitted or ``null`` all workspaces 
		are shown.

	:param str output:
		May be set to the name of an X output. If specified, only workspaces 
		on that output are shown. Overrides automatic output detection by 
		the lemonbar renderer and bindings.

	:param int strip:
		Specifies how many characters from the front of each workspace name 
		should be stripped (e.g. to remove workspace numbers). Defaults to zero.

	Highlight groups used: ``workspace`` or ``w_visible``, ``workspace`` or ``w_focused``, ``workspace`` or ``w_urgent``.
	'''
    output = output or segment_info.get('output')

    return [{
        'contents': w['name'][strip:],
        'highlight_groups': workspace_groups(w)
    } for w in get_i3_connection().get_workspaces() if ((not only_show or any(
        w[typ]
        for typ in only_show)) and (not output or w['output'] == output))]
Ejemplo n.º 5
0
def workspaces(pl, segment_info, only_show=None, output=None, strip=0):
	'''Return list of used workspaces

	:param list only_show:
		Specifies which workspaces to show. Valid entries are ``"visible"``, 
		``"urgent"`` and ``"focused"``. If omitted or ``null`` all workspaces 
		are shown.

	:param str output:
		May be set to the name of an X output. If specified, only workspaces 
		on that output are shown. Overrides automatic output detection by 
		the lemonbar renderer and bindings.

	:param int strip:
		Specifies how many characters from the front of each workspace name 
		should be stripped (e.g. to remove workspace numbers). Defaults to zero.

	Highlight groups used: ``workspace`` or ``w_visible``, ``workspace`` or ``w_focused``, ``workspace`` or ``w_urgent``.
	'''
	output = output or segment_info.get('output')

	return [
		{
			'contents': w['name'][strip:],
			'highlight_groups': workspace_groups(w)
		}
		for w in get_i3_connection().get_workspaces()
		if ((not only_show or any(w[typ] for typ in only_show))
		    and (not output or w['output'] == output))
	]
Ejemplo n.º 6
0
def workspace(pl, segment_info, workspace=None, strip=False):
	'''Return the specified workspace name

	:param str workspace:
		Specifies which workspace to show. If unspecified, may be set by the 
		``list_workspaces`` lister if used, otherwise falls back to 
		currently focused workspace.

	:param bool strip:
		Specifies whether workspace numbers (in the ``1: name`` format) should 
		be stripped from workspace names before being displayed. Defaults to false.

	Highlight groups used: ``workspace`` or ``w_visible``, ``workspace`` or ``w_focused``, ``workspace`` or ``w_urgent``.
	'''
	if workspace:
		try:
			w = next((
				w for w in get_i3_connection().get_workspaces()
				if w['name'] == workspace
			))
		except StopIteration:
			return None
	elif segment_info.get('workspace'):
		w = segment_info['workspace']
	else:
		try:
			w = next((
				w for w in get_i3_connection().get_workspaces()
				if w['focused']
			))
		except StopIteration:
			return None

	return [{
		'contents': format_name(w['name'], strip=strip),
		'highlight_groups': workspace_groups(w)
	}]
Ejemplo n.º 7
0
def scratchpad(pl, icons=SCRATCHPAD_ICONS):
    '''Returns the windows currently on the scratchpad

        :param dict icons:
            Specifies the strings to show for the different scratchpad window states. Must
                contain the keys ``fresh`` and ``changed``.

        Highlight groups used: ``scratchpad`` or ``scratchpad:visible``, ``scratchpad`` or ``scratchpad:focused``, ``scratchpad`` or ``scratchpad:urgent``.
        '''

    return [{
        'contents': icons.get(w.scratchpad_state, icons['changed']),
        'highlight_groups': scratchpad_groups(w)
    } for w in get_i3_connection().get_tree().descendents()
            if w.scratchpad_state != 'none']
Ejemplo n.º 8
0
def scratchpad(pl, icons=SCRATCHPAD_ICONS):
	'''Returns the windows currently on the scratchpad

	:param dict icons:
		Specifies the strings to show for the different scratchpad window states. Must 
		contain the keys ``fresh`` and ``changed``.

	Highlight groups used: ``scratchpad`` or ``scratchpad:visible``, ``scratchpad`` or ``scratchpad:focused``, ``scratchpad`` or ``scratchpad:urgent``.
	'''

	return [
		{
			'contents': icons.get(w.scratchpad_state, icons['changed']),
			'highlight_groups': scratchpad_groups(w)
		}
		for w in get_i3_connection().get_tree().descendents()
		if w.scratchpad_state != 'none'
	]
Ejemplo n.º 9
0
def active_window(pl, cutoff=100):
    '''Returns the title of the currently active window.

	:param int cutoff:
		Maximum title length. If the title is longer, the window_class is used instead.

	Highlight groups used: ``active_window_title``.
	'''

    focused = get_i3_connection().get_tree().find_focused()
    cont = focused.name
    if len(cont) > cutoff:
        cont = focused.window_class

    return [{
        'contents': cont,
        'highlight_groups': ['active_window_title']
    }] if focused.name != focused.workspace().name else []
Ejemplo n.º 10
0
def workspace_lister(pl, segment_info, only_show=None, output=None):
	'''List all workspaces in segment_info format

	Sets the segment info values of ``workspace`` and ``output`` to the name of 
	the i3 workspace and the ``xrandr`` output respectively and the keys
	``"visible"``, ``"urgent"`` and ``"focused"`` to a boolean indicating these
	states.

	:param list only_show:
		Specifies which workspaces to list. Valid entries are ``"visible"``, 
		``"urgent"`` and ``"focused"``. If omitted or ``null`` all workspaces 
		are listed.

	:param str output:
		May be set to the name of an X output. If specified, only workspaces 
		on that output are listed. Overrides automatic output detection by 
		the lemonbar renderer and bindings. Set to ``false`` to force 
		all workspaces to be shown.
	'''

	if output == None:
		output = output or segment_info.get('output')

	return (
		(
			updated(
				segment_info,
				output=w['output'],
				workspace={
					'name': w['name'],
					'visible': w['visible'],
					'urgent': w['urgent'],
					'focused': w['focused'],
				},
			),
			{
				'draw_inner_divider': None
			}
		)
		for w in get_i3_connection().get_workspaces()
		if (((not only_show or any(w[typ] for typ in only_show))
		    and (not output or w['output'] == output)))
	)
Ejemplo n.º 11
0
def workspaces(pl,
               segment_info,
               only_show=None,
               output=None,
               strip=0,
               separator=" ",
               icons=WS_ICONS,
               show_icons=True,
               show_multiple_icons=True,
               show_dummy_workspace=False,
               show_output=False,
               priority_workspaces=[]):
    '''Return list of used workspaces

        :param list only_show:
                Specifies which workspaces to show. Valid entries are ``"visible"``,
                ``"urgent"`` and ``"focused"``. If omitted or ``null`` all workspaces
                are shown.
        :param str output:
                May be set to the name of an X output. If specified, only workspaces
                on that output are shown. Overrides automatic output detection by
                the lemonbar renderer and bindings.
                Use "__all__" to show workspaces on all outputs.
        :param int strip:
                Specifies how many characters from the front of each workspace name
                should be stripped (e.g. to remove workspace numbers). Defaults to zero.
        :param string separator:
                Specifies a string to be inserted between the workspace name and program icons
                and between program icons.
        :param dict icons:
                A dictionary mapping a substring of window classes to strings to be used as an icon for that
                window class. The following window classes have icons by default:
                ``Xfce4-terminal``, ``Chromium``, ``Steam``, ``jetbrains``, ``Gimp``, ``Pavucontrol``, ``Lmms``,
                ``Thunderbird``, ``Thunar``, ``Skype``, ``TelegramDesktop``, ``feh``, ``Firefox``, ``Evince``,
                ``Okular``, ``libreoffice-calc``, ``libreoffice-writer``.
                You can override the default icons by defining an icon for that window class yourself, and disable
                single icons by setting their icon to "" or None.
                Further, there is a ``multiple`` icon for workspaces containing more than one window (which is used if
                ``show_multiple_icons`` is ``False``)
        :param boolean show_icons:
                Determines whether to show icons. Defaults to True.
        :param boolean show_multiple_icons:
                If this is set to False, instead of displying multiple icons per workspace,
                the icon "multiple" will be used.
        :param boolean show_dummy_workspace:
                If this is set to True, this segment will alway display an additional, non-existing
                workspace. This workspace will be handled as if it was a non-urgent and non-focused
                regular workspace, i.e., click events will work as with normal workspaces.
        :param boolean show_output:
                Show the name of the output if more than one output is connected and output is not
                set to ``__all__``.
        :param string list priority_workspaces:
                A list of workspace names to be sorted before any other workspaces in the given
                order.

        Highlight groups used: ``workspace`` or ``workspace:visible``, ``workspace`` or ``workspace:focused``, ``workspace`` or ``workspace:urgent`` or ``output``.

        Click values supplied: ``workspace_name`` (string) for workspaces and ``output_name`` (string) for outputs.
        '''

    output_count = 1
    if not output == "__all__":
        output = output or segment_info.get('output')
        if show_output:
            output_count = len(
                [o for o in get_i3_connection().get_outputs() if o['active']])
    else:
        output = None
    if output:
        output = [output]
    else:
        output = [
            o['name'] for o in get_i3_connection().get_outputs() if o['active']
        ]

    def sort_ws(ws):
        import re

        def natural_key(ws):
            str = ws['name']
            return [
                int(s) if s.isdigit() else s for s in re.split(r'(\d+)', str)
            ]

        ws = sorted(ws, key=natural_key) + (get_next_ws(ws, output)
                                            if show_dummy_workspace else [])
        result = []
        for n in priority_workspaces:
            result += [w for w in ws if w['name'] == n]
        return result + [w for w in ws if not w['name'] in priority_workspaces]

    if len(output) <= 1:
        res = []
        if output_count > 1:
            res += [{
                'contents': output[0],
                'highlight_groups': ['output'],
                'click_values': {
                    'output_name': output[0]
                }
            }]
        res += [{
            'contents':
            w['name'][min(len(w['name']), strip):] +
            (get_icon(w, separator, icons, show_multiple_icons)
             if show_icons else ""),
            'highlight_groups':
            workspace_groups(w),
            'click_values': {
                'workspace_name': w['name']
            }
        } for w in sort_ws(get_i3_connection().get_workspaces())
                if (not only_show or any(
                    w[typ] for typ in only_show)) and w['output'] == output[0]]
        return res
    else:
        res = []
        for n in output:
            res += [{
                'contents': n,
                'highlight_groups': ['output'],
                'click_values': {
                    'output_name': n
                }
            }]
            res += [{
                'contents':
                w['name'][min(len(w['name']), strip):] +
                (get_icon(w, separator, icons, show_multiple_icons)
                 if show_icons else ""),
                'highlight_groups':
                workspace_groups(w),
                'click_values': {
                    'workspace_name': w['name']
                }
            } for w in sort_ws(get_i3_connection().get_workspaces())
                    if (not only_show or any(
                        w[typ] for typ in only_show)) and w['output'] == n]
        return res
Ejemplo n.º 12
0
if __name__ == '__main__':
    name = 'wm'
    if len(sys.argv) > 1:
        name = sys.argv[1]

    powerline = I3Powerline(name, renderer_module='i3bar')
    powerline.update_renderer()

    interval = 0.5

    print('{"version": 1}')
    print('[')
    print('[]')

    lock = Lock()

    def render(event=None, data=None, sub=None):
        global lock
        with lock:
            print(',[' + powerline.render()[:-1] + ']')
            sys.stdout.flush()

    i3 = get_i3_connection()
    i3_subscribe(i3, 'workspace', render)

    while True:
        start_time = monotonic()
        render()
        time.sleep(max(interval - (monotonic() - start_time), 0.1))
Ejemplo n.º 13
0
def workspaces(pl,
               segment_info,
               only_show=None,
               output=None,
               strip=0,
               format='{name}',
               icons=WS_ICONS,
               sort_workspaces=False,
               show_output=False,
               priority_workspaces=[],
               hide_empty_workspaces=False):
    '''Return list of used workspaces

	:param list only_show:
		Specifies which workspaces to show. Valid entries are ``"visible"``,
		``"urgent"`` and ``"focused"``. If omitted or ``null`` all workspaces
		are shown.
	:param str output:
		May be set to the name of an X output. If specified, only workspaces
		on that output are shown. Overrides automatic output detection by
		the lemonbar renderer and bindings.
		Use "__all__" to show workspaces on all outputs.
	:param int strip:
		Specifies how many characters from the front of each workspace name
		should be stripped (e.g. to remove workspace numbers). Defaults to zero.
	:param str format:
		Specifies the format used to display workspaces; defaults to ``{name}``.
		Valid fields are: ``name`` (workspace name), ``number`` (workspace number
		if present), `stipped_name`` (workspace name stripped of leading number),
		``icon`` (if available, icon for application running in the workspace,
		uses the ``multiple`` icon instead of multiple different icons), ``multi_icon``
		(similar to ``icon``, but does not use ``multiple``, instead joins all icons
		with a single space)
	:param dict icons:
		A dictionary mapping a substring of window classes to strings to be used as an
		icon for that window class.
		Further, there is a ``multiple`` icon for workspaces containing more than one
		window.
	:param bool sort_workspaces:
		Sort the workspaces displayed by their name according to the natural ordering.
	:param bool show_output:
		Shows the name of the output if more than one output is connected.
	:param list priority_workspaces:
		A list of workspace names to be sorted before any other workspaces in the given
		order.
	:param bool hide_empty_workspaces:
		Hides all workspaces without any open window.
		Also hides non-focussed workspaces containing only an open scratchpad.


	Highlight groups used: ``workspace`` or ``w_visible``, ``workspace:visible``, ``workspace`` or ``w_focused``, ``workspace:focused``, ``workspace`` or ``w_urgent``, ``workspace:urgent``, ``workspace`` or ``output``.
	'''
    conn = get_i3_connection()

    if not output == "__all__":
        output = output or segment_info.get('output')
    else:
        output = None

    if output:
        output = [output]
    else:
        output = [o.name for o in conn.get_outputs() if o.active]

    def sort_ws(ws):
        if sort_workspaces:

            def natural_key(ws):
                str = ws.name
                return [
                    int(s) if s.isdigit() else s
                    for s in re.split(r'(\d+)', str)
                ]

            ws = sorted(ws, key=natural_key)
        result = []
        for n in priority_workspaces:
            result += [w for w in ws if w.name == n]
        return result + [w for w in ws if not w.name in priority_workspaces]

    ws_containers = {
        w_con.name: w_con
        for w_con in conn.get_tree().workspaces()
    }

    if len(output) <= 1:
        res = []
        if show_output:
            res += [{'contents': output[0], 'highlight_groups': ['output']}]
        res += [{
         'contents': format.format(name = w.name[min(len(w.name), strip):],
          stripped_name = format_name(w.name, strip=True),
          number = w.num,
          icon = get_icon(w, '', icons, False, ws_containers),
          multi_icon = get_icon(w, ' ', icons, True, ws_containers)),
         'highlight_groups': workspace_groups(w)
         } for w in sort_ws(conn.get_workspaces()) \
           if (not only_show or any(getattr(w, tp) for tp in only_show)) \
           if w.output == output[0] \
           if not (hide_empty_workspaces and is_empty_workspace(w, ws_containers))]
        return res
    else:
        res = []
        for n in output:
            if show_output:
                res += [{'contents': n, 'highlight_groups': ['output']}]
            res += [{
             'contents': format.format(name = w.name[min(len(w.name), strip):],
              stripped_name = format_name(w.name, strip=True),
              number = w.num,
              icon = get_icon(w, '', icons, False, ws_containers),
              multi_icon = get_icon(w, ' ', icons, True, ws_containers)),
             'highlight_groups': workspace_groups(w)
             } for w in sort_ws(conn.get_workspaces()) \
               if (not only_show or any(getattr(w, tp) for tp in only_show)) \
               if w.output == n \
               if not (hide_empty_workspaces and is_empty_workspace(w, ws_containers))]
        return res
Ejemplo n.º 14
0
def workspace(pl,
              segment_info,
              workspace=None,
              strip=False,
              format=None,
              icons=WS_ICONS):
    '''Return the specified workspace name

	:param str workspace:
		Specifies which workspace to show. If unspecified, may be set by the
		``list_workspaces`` lister if used, otherwise falls back to
		currently focused workspace.

	:param bool strip:
		Specifies whether workspace numbers (in the ``1: name`` format) should
		be stripped from workspace names before being displayed. Defaults to false.
		Deprecated: Use {name} or {stripped_name} of format instead.

	:param str format:
		Specifies the format used to display workspaces; defaults to ``{name}``.
		Valid fields are: ``name`` (workspace name), ``number`` (workspace number
		if present), `stipped_name`` (workspace name stripped of leading number),
		``icon`` (if available, icon for application running in the workspace,
		uses the ``multiple`` icon instead of multiple different icons), ``multi_icon``
		(similar to ``icon``, but does not use ``multiple``, instead joins all icons
		with a single space)

	:param dict icons:
		A dictionary mapping a substring of window classes to strings to be used as an
		icon for that window class.
		Further, there is a ``multiple`` icon for workspaces containing more than one
		window.

	Highlight groups used: ``workspace`` or ``w_visible``, ``workspace:visible``, ``workspace`` or ``w_focused``, ``workspace:focused``, ``workspace`` or ``w_urgent``, ``workspace:urgent``, ``workspace``.
	'''
    if format == None:
        format = '{stripped_name}' if strip else '{name}'

    conn = get_i3_connection()
    ws_containers = {
        w_con.name: w_con
        for w_con in conn.get_tree().workspaces()
    }

    if workspace:
        try:
            w = next((w for w in conn.get_workspaces() if w.name == workspace))
        except StopIteration:
            return None
    elif segment_info.get('workspace'):
        w = segment_info['workspace']
    else:
        try:
            w = next((w for w in conn.get_workspaces() if w.focused))
        except StopIteration:
            return None

    return [{
        'contents':
        format.format(name=w.name,
                      stripped_name=format_name(w.name, strip=True),
                      number=w.num,
                      icon=get_icon(w, '', icons, False, ws_containers),
                      multi_icon=get_icon(w, ' ', icons, True, ws_containers)),
        'highlight_groups':
        workspace_groups(w)
    }]
Ejemplo n.º 15
0
def active_window(pl, segment_info, cutoff=100, global_menu=False, item_length=20, \
        max_width=80, auto_expand=False, show_empty=False, **kwargs):
    '''
        Returns the title of the currently active window.
        To enhance the global menu support, add the following to your ``.bashrc``:

        .. code-block:: shell

            if [ -n "$GTK_MODULES" ]; then
                GTK_MODULES="${GTK_MODULES}:appmenu-gtk-module"
            else
                GTK_MODULES="appmenu-gtk-module"
            fi

            if [ -z "$UBUNTU_MENUPROXY" ]; then
                UBUNTU_MENUPROXY=1
            fi

            export GTK_MODULES
            export UBUNTU_MENUPROXY


        :param int cutoff:
            Maximum title length. If the title is longer, the window_class is used instead.
        :param boolean global_menu:
            Activate global menu support (experimental)
        :param int item_length:
            Maximum length of a menu item.
        :param int max_width:
            Maximum total length of the content.
        :param bool auto_expand:
            Add spaces to center the segment.
        :param bool show_empty:
            Show the sehment if no window is focused.

        Highlight groups used: ``active_window_title:single`` or ``active_window_title:stacked_unfocused`` or ``active_window_title:stacked`` or ``active_window_title``.
        '''

    global active_window_state
    global last_active_window
    global last_active_window_name
    global last_oneshot
    global menu_items
    global current_layer
    global start
    global path

    conn = get_i3_connection()

    if len(path) > 0:
        max_width = max_width - len('Main Menu')
    if len(path) > 1:
        max_width = max_width - len('Up a Level')

    channel_name = 'i3wm.active_window'

    channel_value = None
    if global_menu and 'payloads' in segment_info and channel_name in segment_info[
            'payloads']:
        channel_value = segment_info['payloads'][channel_name]

    focused = conn.get_tree().find_focused()
    ws = focused.workspace()

    o_name = [w.output for w in conn.get_workspaces() \
            if w.name == ws.name][0]
    output = segment_info.get('output')

    if last_active_window != focused.window and last_active_window:
        # Please, don't kill me for this line
        if global_menu and last_active_window and 'payloads' in segment_info \
                and 'i3wm.workspaces' in segment_info['payloads']:
            segment_info['payloads']['i3wm.workspaces'] = None

        last_active_window = None
        last_active_window_name = None
        active_window_state = 0
        start = 0
        menu_items = None
        current_layer = None
        path = []

    if o_name != output:
        if not show_empty:
            return None
        # Get visible workspace
        ws = [w for w in conn.get_workspaces() if w.output == output \
                and w.visible]
        if not len(ws):
            return None
        ws = [w for w in focused.workspaces() if w.name == ws[0].name]
        if not len(ws):
            return None

        highlight = compute_highlight(ws[0], None)

        return [{
            'contents': '',
            'width': 'auto',
            'highlight_groups': highlight,
            'click_values': {
                'segment': ''
            },
            'payload_name': 'DROP'
        }]

    if focused.name == focused.workspace().name:
        if not show_empty:
            return None
        return [{
            'contents': '',
            'width': 'auto',
            'highlight_groups': compute_highlight(ws, None),
            'click_values': {
                'segment': ''
            },
            'payload_name': 'DROP'
        }]

    cont = [focused.name]
    if cutoff and len(cont) > cutoff:
        cont = [focused.window_class]

    main_cont = cont[0]

    if channel_value and not isinstance(channel_value, str) and len(channel_value) == 2 \
            and channel_value[0].startswith('menu_click') and channel_value[1] > last_oneshot:
        last_oneshot = channel_value[1]
        click_area = channel_value[0].split(':')[1]
        if active_window_state == 0:
            last_active_window = focused.window
            last_active_window_name = focused.name
            menu_items = compute_menu(focused.window)
            current_layer = split_layer(menu_items, max_width, item_length)
            path = []
            active_window_state = 1
        elif click_area == 'Main Menu':
            start = 0
            current_layer = split_layer(menu_items, max_width, item_length)
            path = []
        elif click_area == 'Up a Level':
            start = 0
            path = path[:-1]
            current_layer = menu_items
            cnt = 0
            for i in path:
                current_layer = current_layer[i]
                cnt += 1
                if cnt > 1:
                    current_layer.update({'Up a Level': ''})
                current_layer.update({'Main Menu': ''})
            current_layer = split_layer(current_layer, max_width, item_length)
        elif click_area == '$<':
            start = max(0, start - 1)
        elif click_area == '$>':
            start = min(len(current_layer) - 1, start + 1)
        elif click_area != '':
            if isinstance(current_layer[start][click_area], dict):
                current_layer = current_layer[start][click_area]
                if len(path) > 0:
                    current_layer.update({'Up a Level': ''})
                current_layer.update({'Main Menu': ''})
                current_layer = split_layer(current_layer, max_width,
                                            item_length)
                start = 0
                path += [click_area]
            else:
                if isinstance(current_layer[start][click_area], tuple):
                    gtk_click(current_layer[start][click_area][0],
                              current_layer[start][click_area][1])
                else:
                    current_layer[start][click_area]()
                current_layer = split_layer(menu_items, max_width, item_length)
                path = []
                start = 0

    if channel_value and not isinstance(channel_value, str) and len(channel_value) == 2 \
            and channel_value[0] == 'menu_off' and channel_value[1] > last_oneshot:
        last_oneshot = channel_value[1]
        active_window_state = 0
    if channel_value and not isinstance(channel_value, str) and len(channel_value) == 2 \
            and channel_value[0] == 'menu_on' and channel_value[1] > last_oneshot:
        last_oneshot = channel_value[1]
        active_window_state = 1
        if last_active_window != focused.window:
            last_active_window = focused.window
            last_active_window_name = focused.name
            menu_items = compute_menu(focused.window)
            current_layer = split_layer(menu_items, max_width, item_length)
            path = []
            start = 0

    if current_layer and active_window_state:
        cont = list(current_layer[start].keys())

    highlight = compute_highlight(ws, focused)
    res = []

    show_prev = start > 0 and active_window_state > 0
    show_next = current_layer and active_window_state > 0 \
            and start < len(current_layer) - 1

    def shorten(string, length):
        if len(string) < length - 1:
            return string
        return string[:length - 1] + '…'

    if global_menu and (auto_expand or show_prev):
        res += [{
            'contents': '<' if show_prev else '',
            'highlight_groups': highlight,
            'payload_name': channel_name if show_prev else 'DROP',
            'draw_soft_divider': False,
            'draw_inner_divider': True if show_prev else False,
            'width': 'auto' if auto_expand else None,
            'align': 'r',
            'click_values': {
                'segment': '$<'
            }
        }]

    total_len = 0
    for i in range(0, len(cont)):
        total_len += min(len(cont[i]), item_length) if cont[i] != main_cont \
                    else min(len(cont[i]), max_width)

    def truncate(pl, wd, seg):
        nl = max(5 * len(cont), int(total_len) - wd)
        if int(total_len) <= nl:
            return seg['contents']
        shr = (int(total_len) - nl) // len(cont)
        return shorten(seg['contents'], len(seg['contents']) - shr)

    for i in range(0, len(cont)):
        draw_div = i != 0 or show_prev or not auto_expand
        res += [{
            'contents': (shorten(cont[i],item_length) if cont[i] != main_cont \
                    else shorten(cont[i], max_width)),
            'highlight_groups': highlight,
            'payload_name': channel_name,
            'draw_inner_divider': draw_div,
            'draw_soft_divider': True ,
            'click_values': { 'segment': cont[i] if cont[i] != main_cont else '' },
            'truncate': truncate
            }]

    if global_menu and (auto_expand or show_next):
        res += [{
            'contents': '>' if show_next else '',
            'highlight_groups': highlight,
            'payload_name': channel_name if show_next else 'DROP',
            'width': 'auto' if auto_expand else None,
            'click_values': {
                'segment': '$>'
            },
            'draw_inner_divider': bool(show_next),
        }]
    return res
Ejemplo n.º 16
0
if __name__ == '__main__':
	name = 'wm'
	if len(sys.argv) > 1:
		name = sys.argv[1]

	powerline = I3Powerline(name, renderer_module='i3bar')
	powerline.update_renderer()

	interval = 0.5

	print ('{"version": 1}')
	print ('[')
	print ('[]')

	lock = Lock()

	def render(event=None, data=None, sub=None):
		global lock
		with lock:
			print (',[' + powerline.render()[:-1] + ']')
			sys.stdout.flush()

	i3 = get_i3_connection()
	i3_subscribe(i3, 'workspace', render)

	while True:
		start_time = monotonic()
		render()
		time.sleep(max(interval - (monotonic() - start_time), 0.1))