Exemplo n.º 1
0
def main():
    # exit if already running, thanks to Slava V at https://stackoverflow.com/a/384493/4040598
    pid_file = os.path.join(tempfile.gettempdir(), 'sgtk-bar.pid')
    fp = open(pid_file, 'w')
    try:
        fcntl.lockf(fp, fcntl.LOCK_EX | fcntl.LOCK_NB)
    except IOError:
        subprocess.run("pkill -f sgtk-bar", shell=True)
        sys.exit(2)

    global build_from_file

    parser = argparse.ArgumentParser(description="Button bar for sgtk-menu")
    placement = parser.add_mutually_exclusive_group()

    parser.add_argument(
        "-bf",
        type=str,
        help="build from file (default: {})".format(build_from_file))
    parser.add_argument("-bw",
                        type=int,
                        default=90,
                        help="minimum button width (default: 90)")
    parser.add_argument("-bh",
                        type=int,
                        default=90,
                        help="minimum button height (default: 90)")
    placement.add_argument("-b",
                           "--bottom",
                           action="store_true",
                           help="display bar at the bottom")
    placement.add_argument("-t",
                           "--top",
                           action="store_true",
                           help="display bar at the top")
    parser.add_argument("-x",
                        type=int,
                        default=0,
                        help="horizontal offset from edge")
    parser.add_argument("-y",
                        type=int,
                        default=0,
                        help="vertical offset from edge")
    parser.add_argument("-v",
                        "--vertical",
                        action="store_true",
                        help="arrange buttons vertically")
    parser.add_argument("-p",
                        type=int,
                        default=20,
                        help="button padding (default: 20)")
    parser.add_argument("-s",
                        type=int,
                        default=32,
                        help="icon size (min: 16, max: 48, default: 32)")
    parser.add_argument(
        "-d",
        type=int,
        default=100,
        help="bar delay in milliseconds (default: 100; sway & i3 only)")
    parser.add_argument(
        "-o",
        type=float,
        default=0.3,
        help="overlay opacity (min: 0.0, max: 1.0, default: 0.3)")

    parser.add_argument(
        "-css",
        type=str,
        default="style.css",
        help="use alternative {} style sheet instead of style.css".format(
            os.path.join(config_dir, '<CSS>')))
    global args
    args = parser.parse_args()

    # Create default config files if not found
    create_default_configs(config_dir)

    css_file = os.path.join(config_dirs()[0], args.css) if os.path.exists(
        os.path.join(config_dirs()[0], 'style.css')) else None

    if args.s < 16:
        args.s = 16
    elif args.s > 48:
        args.s = 48

    # We do not need any delay in other WMs
    if other_wm:
        args.d = 0

    # Replace appendix file name with custom - if any
    if args.bf:
        build_from_file = os.path.join(config_dirs()[0], args.bf)

    if css_file:
        screen = Gdk.Screen.get_default()
        provider = Gtk.CssProvider()
        try:
            provider.load_from_path(css_file)
            Gtk.StyleContext.add_provider_for_screen(
                screen, provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
        except Exception as e:
            print(e)

    screen = Gdk.Screen.get_default()
    provider = Gtk.CssProvider()
    style_context = Gtk.StyleContext()
    style_context.add_provider_for_screen(
        screen, provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)

    # Overlay window
    global win
    win = MainWindow()
    if other_wm:
        # We need the window to be visible to obtain the screen geometry when i3ipc module unavailable
        win.resize(1, 1)
        win.show_all()
    global geometry
    # If we're not on sway neither i3, this won't return values until the window actually shows up.
    # Let's try as many times as needed. The retries int protects from an infinite loop.
    retries = 0
    while geometry[0] == 0 and geometry[1] == 0 and geometry[
            2] == 0 and geometry[3] == 0:
        geometry = display_geometry(win, wm, mouse_pointer)
        retries += 1
        if retries > 50:
            print("\nFailed to get the current screen geometry, exiting...\n")
            sys.exit(2)
    x, y, w, h = geometry

    win.resize(w, h)
    win.set_skip_taskbar_hint(True)
    if other_wm:
        win.move(x, y)
    win.show_all()

    GLib.timeout_add(args.d, show_bar)
    Gtk.main()
Exemplo n.º 2
0
pynput = False
try:
    from pynput.mouse import Controller

    mouse_pointer = Controller()
    pynput = True
except:
    mouse_pointer = None
    pass

geometry = (0, 0, 0, 0)

win = None  # overlay window
args = None

config_dir = config_dirs()[0]
if not os.path.exists(config_dir):
    os.makedirs(config_dir)
build_from_file = os.path.join(config_dirs()[0], 'exit')


def main():
    # exit if already running, thanks to Slava V at https://stackoverflow.com/a/384493/4040598
    pid_file = os.path.join(tempfile.gettempdir(), 'sgtk-bar.pid')
    fp = open(pid_file, 'w')
    try:
        fcntl.lockf(fp, fcntl.LOCK_EX | fcntl.LOCK_NB)
    except IOError:
        subprocess.run("pkill -f sgtk-bar", shell=True)
        sys.exit(2)
Exemplo n.º 3
0
def main():
    # exit if already running, thanks to Slava V at https://stackoverflow.com/a/384493/4040598
    pid_file = os.path.join(tempfile.gettempdir(), 'sgtk-menu.pid')
    fp = open(pid_file, 'w')
    try:
        fcntl.lockf(fp, fcntl.LOCK_EX | fcntl.LOCK_NB)
    except IOError:
        subprocess.run("pkill -f sgtk-menu", shell=True)
        sys.exit(2)

    global build_from_file

    if not sys.stdin.isatty():
        global pipe_menu
        pipe_menu = []
        for line in sys.stdin:
            pipe_menu.append(line.rstrip())
    
    parser = argparse.ArgumentParser(description="GTK menu for sway, i3 and some other WMs")
    placement = parser.add_mutually_exclusive_group()
    placement.add_argument("-b", "--bottom", action="store_true", help="display menu at the bottom")
    placement.add_argument("-c", "--center", action="store_true", help="center menu on the screen")
    placement.add_argument("-p", "--pointer", action="store_true", help="display at mouse pointer (not-sway only)")

    favourites = parser.add_mutually_exclusive_group()
    favourites.add_argument("-f", "--favourites", action="store_true", help="prepend 5 most used items")
    favourites.add_argument('-fn', type=int, help="prepend <FN> most used items")

    appendix = parser.add_mutually_exclusive_group()
    appendix.add_argument("-a", "--append", action="store_true",
                          help="append custom menu from {}".format(build_from_file))
    appendix.add_argument("-af", type=str, help="append custom menu from {}".format(os.path.join(config_dir, '<AF>')))

    parser.add_argument("-n", "--no-menu", action="store_true", help="skip menu, display appendix only")
    parser.add_argument("-l", type=str, help="force language (e.g. \"de\" for German)")
    parser.add_argument("-s", type=int, default=20, help="menu icon size (min: 16, max: 48, default: 20)")
    parser.add_argument("-w", type=int, help="menu width in px (integer, default: screen width / 8)")
    parser.add_argument("-d", type=int, default=100, help="menu delay in milliseconds (default: 100; sway & i3 only)")
    parser.add_argument("-o", type=float, default=0.3,
                        help="overlay opacity (min: 0.0, max: 1.0, default: 0.3; sway only)")
    parser.add_argument("-t", type=int, default=30, help="sway submenu lines limit (default: 30)")
    parser.add_argument("-y", type=int, default=0, help="y offset from edge to display menu at")
    parser.add_argument("-css", type=str, default="style.css",
                        help="use alternative {} style sheet instead of style.css"
                        .format(os.path.join(config_dir, '<CSS>')))
    parser.add_argument("-v", "--version", action="store_true", help="display version and exit")
    parser.add_argument("-wm", action="store_true", help="display detected Window Manager and exit")
    global args
    args = parser.parse_args()

    if args.version:
        print_version()
        sys.exit(0)
    if args.wm:
        print(wm)
        sys.exit(0)
        
    if pipe_menu:
        args.no_menu = True

    if not wm == "sway" and not args.d == 100:
        args.d = 0
        print("[-d] argument ignored if not-sway")

    # Create default config files if not found
    create_default_configs(config_dir)

    css_file = os.path.join(config_dirs()[0], args.css) if os.path.exists(
        os.path.join(config_dirs()[0], 'style.css')) else None

    if args.s < 16:
        args.s = 16
    elif args.s > 48:
        args.s = 48

    # Replace appendix file name with custom - if any
    if args.af:
        build_from_file = os.path.join(config_dirs()[0], args.af)

    if css_file:
        screen = Gdk.Screen.get_default()
        provider = Gtk.CssProvider()
        try:
            provider.load_from_path(css_file)
            Gtk.StyleContext.add_provider_for_screen(
                screen, provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
        except Exception as e:
            print(e)

    # cache stores number of clicks on each item
    global cache
    cache = load_json(cache_file)

    if not cache:
        save_json(cache, cache_file)
    global sorted_cache
    sorted_cache = sorted(cache.items(), reverse=True, key=lambda x: x[1])

    global locale
    locale = get_locale_string(args.l)
    category_names_dictionary = localized_category_names(locale)

    # replace additional category names with main ones
    for name in category_names:
        main_category_name = additional_to_main(name)
        try:
            localized_names_dictionary[main_category_name] = category_names_dictionary[main_category_name]
        except:
            pass

    screen = Gdk.Screen.get_default()
    provider = Gtk.CssProvider()
    style_context = Gtk.StyleContext()
    style_context.add_provider_for_screen(
        screen, provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION
    )

    # find all .desktop entries, create DesktopEntry class instances;
    # DesktopEntry adds itself to the proper List in the class constructor
    list_entries()

    # Overlay window
    global win
    win = MainWindow()

    geometry = (0, 0, 0, 0)
    # If we're not on sway neither i3, this won't return values until the window actually shows up.
    # Let's try as many times as needed. The retries int protects from an infinite loop.
    retries = 0
    while geometry[0] == 0 and geometry[1] == 0 and geometry[2] == 0 and geometry[3] == 0:
        geometry = display_geometry(win, wm, mouse_pointer)
        retries += 1
        if retries > 50:
            print("\nFailed to get the current screen geometry, exiting...\n")
            sys.exit(2)
    x, y, w, h = geometry

    if wm == "sway":
        # resize to current screen dimensions on sway
        win.resize(w, h)
    else:
        win.resize(0, 0)
        if args.center:
            x = x + (w // 2)
            y = y + (h // 2)
        elif args.bottom:
            y = h - args.y
        elif args.pointer:
            if mouse_pointer:
                x, y = mouse_pointer.position
            else:
                print("\nYou need the python-pynput package!\n")
        else:
            y = y + args.y

        win.move(x, y)

    win.menu = build_menu()
    win.menu.set_property("name", "menu")

    global menu_items_list
    menu_items_list = win.menu.get_children()

    win.menu.propagate_key_event = False
    win.menu.connect("key-release-event", win.search_items)
    # Let's reserve some width for long entries found with the search box
    if args.w:
        win.menu.set_property("width_request", args.w)
    else:
        win.menu.set_property("width_request", int(win.screen_dimensions[0] / 8))
    win.show_all()

    GLib.timeout_add(args.d, open_menu)
    Gtk.main()
Exemplo n.º 4
0
                  "Other": "applications-other"}

localized_names_dictionary = {}  # name => translated name
locale = ''

win = None  # overlay window
args = None
all_items_list = []  # list of all DesktopMenuItem objects assigned to a .desktop entry
all_copies_list = []  # list of copies of above used while searching (not assigned to a submenu!)
menu_items_list = []  # created / updated with menu.get_children()
filtered_items_list = []  # used in the search method

# If we need to cheat_sway, we only add first args.t entries to all_copies list, but we need them all for searching!
missing_copies_list = []

config_dir = config_dirs()[0]
if not os.path.exists(config_dir):
    os.makedirs(config_dir)
build_from_file = os.path.join(config_dirs()[0], 'appendix')

if "XDG_CACHE_HOME" in os.environ:
    cache_dir = os.environ["XDG_CACHE_HOME"]
else:
    cache_dir = os.path.join(os.path.expanduser('~/.cache'))
if not os.path.exists(cache_dir):
    os.makedirs(cache_dir)
cache_file = os.path.join(cache_dir, 'sgtk-menu')

cache = None
sorted_cache = None
Exemplo n.º 5
0
def main():
    # exit if already running, thanks to Slava V at https://stackoverflow.com/a/384493/4040598
    pid_file = os.path.join(tempfile.gettempdir(), 'sgtk-grid.pid')
    fp = open(pid_file, 'w')
    try:
        fcntl.lockf(fp, fcntl.LOCK_EX | fcntl.LOCK_NB)
    except IOError:
        subprocess.run("pkill -f sgtk-grid", shell=True)
        sys.exit(2)

    global build_from_file
    parser = argparse.ArgumentParser(
        description="Application grid for sgtk-menu")

    parser.add_argument(
        '-d',
        type=str,
        default="",
        help="use alternate folder list (: delimited) for .Desktop files")
    parser.add_argument('-c',
                        type=int,
                        default=6,
                        help="number of grid columns (default: 6)")
    parser.add_argument('-t',
                        type=int,
                        default=30,
                        help="top margin width in px (default: 30)")
    parser.add_argument('-b',
                        type=int,
                        default=15,
                        help="bottom margin width in px (default: 15)")

    favourites = parser.add_mutually_exclusive_group()
    favourites.add_argument(
        "-f",
        action="store_true",
        help="prepend 1 row of favourites (most used items)")
    favourites.add_argument('-fn',
                            default=0,
                            type=int,
                            help="prepend <FN> rows of favourites")

    parser.add_argument("-l",
                        type=str,
                        help="force language (e.g. \"de\" for German)")
    parser.add_argument("-s",
                        type=int,
                        default=72,
                        help="menu icon size (min: 16, max: 96, default: 72)")
    parser.add_argument(
        "-o",
        type=float,
        default=0.9,
        help="overlay opacity (min: 0.0, max: 1.0, default: 0.9)")
    parser.add_argument(
        "-css",
        type=str,
        default="grid.css",
        help="use alternative {} style sheet instead of grid.css".format(
            os.path.join(config_dir, '<CSS>')))
    global args
    args = parser.parse_args()

    # Create default config files if not found
    create_default_configs(config_dir)

    css_file = os.path.join(config_dirs()[0], args.css) if os.path.exists(
        os.path.join(config_dirs()[0], 'style.css')) else None

    if args.s < 16:
        args.s = 16
    elif args.s > 96:
        args.s = 96

    if css_file:
        screen = Gdk.Screen.get_default()
        provider = Gtk.CssProvider()
        try:
            provider.load_from_path(css_file)
            Gtk.StyleContext.add_provider_for_screen(
                screen, provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
        except Exception as e:
            print(e)

    # cache stores number of clicks on each item
    global cache
    cache = load_json(cache_file)

    if not cache:
        save_json(cache, cache_file)
    global sorted_cache
    sorted_cache = sorted(cache.items(), reverse=True, key=lambda x: x[1])

    global locale
    locale = get_locale_string(args.l)

    screen = Gdk.Screen.get_default()
    provider = Gtk.CssProvider()
    style_context = Gtk.StyleContext()
    style_context.add_provider_for_screen(
        screen, provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)

    # find all .desktop entries, create AppButton class instances;
    list_entries()

    # find favourites in the list above
    if args.f or args.fn > 0:
        list_favs()

    # Overlay window
    global win
    win = MainWindow()

    geometry = (0, 0, 0, 0)
    # If we're not on sway neither i3, this won't return values until the window actually shows up.
    # Let's try as many times as needed. The retries int protects from an infinite loop.
    retries = 0
    while geometry[0] == 0 and geometry[1] == 0 and geometry[
            2] == 0 and geometry[3] == 0:
        geometry = display_geometry(win, wm, mouse_pointer)
        retries += 1
        if retries > 50:
            print("\nFailed to get the current screen geometry, exiting...\n")
            sys.exit(2)
    x, y, w, h = geometry

    if wm == "sway":
        win.resize(w, h)

    # align width of all buttons
    max_width = 0
    for item in all_apps:
        width = item.get_allocated_width()
        if width > max_width:
            max_width = width
    for item in all_favs:
        item.set_size_request(max_width, max_width / 2)
    for item in all_apps:
        item.set_size_request(max_width, max_width / 2)
    win.search_box.set_size_request(max_width, 0)
    if all_favs:
        win.sep1.set_size_request(w / 3, 1)

    win.show_all()
    # If done inside the constructor on Openbox, stops the window from grabbing focus!
    win.set_skip_taskbar_hint(True)

    # Necessary in FVWM, otherwise it always gets on screen 0
    win.move(x, y)

    Gtk.main()
Exemplo n.º 6
0
def main():
    # exit if already running, thanks to Slava V at https://stackoverflow.com/a/384493/4040598
    pid_file = os.path.join(tempfile.gettempdir(), 'sgtk-dmenu.pid')
    fp = open(pid_file, 'w')
    try:
        fcntl.lockf(fp, fcntl.LOCK_EX | fcntl.LOCK_NB)
    except IOError:
        subprocess.run("pkill -f sgtk-dmenu", shell=True)
        sys.exit(2)

    global build_from_file
    parser = argparse.ArgumentParser(
        description="GTK menu for sway, i3 and some floating WMs")
    placement = parser.add_mutually_exclusive_group()
    placement.add_argument("-b",
                           "--bottom",
                           action="store_true",
                           help="display menu at the bottom (sway & i3 only)")
    placement.add_argument("-c",
                           "--center",
                           action="store_true",
                           help="center menu on the screen (sway & i3 only)")

    appendix = parser.add_mutually_exclusive_group()
    appendix.add_argument(
        "-a",
        "--append",
        action="store_true",
        help="append custom menu from {}".format(build_from_file))
    appendix.add_argument("-af",
                          type=str,
                          help="append custom menu from {}".format(
                              os.path.join(config_dir, '<AF>')))

    parser.add_argument("-s",
                        type=int,
                        default=20,
                        help="menu icon size (min: 16, max: 48, default: 20)")
    parser.add_argument(
        "-w",
        type=int,
        help="menu width in px (integer, default: screen width / 8)")
    parser.add_argument(
        "-d",
        type=int,
        default=100,
        help="menu delay in milliseconds (default: 100; sway & i3 only)")
    parser.add_argument(
        "-o",
        type=float,
        default=0.3,
        help="overlay opacity (min: 0.0, max: 1.0, default: 0.3; "
        "sway & i3 only)")
    parser.add_argument("-t",
                        type=int,
                        default=15,
                        help="lines limit (default: 20)")
    parser.add_argument(
        "-y",
        type=int,
        default=0,
        help="y offset from edge to display menu at (sway & i3 only)")
    parser.add_argument(
        "-css",
        type=str,
        default="style.css",
        help="use alternative {} style sheet instead of style.css".format(
            os.path.join(config_dir, '<CSS>')))
    global args
    args = parser.parse_args()

    # Copy default templates and style sheet - if not found
    create_default_configs(config_dir)

    css_file = os.path.join(config_dirs()[0], args.css) if os.path.exists(
        os.path.join(config_dirs()[0], 'style.css')) else None

    if args.s < 16:
        args.s = 16
    elif args.s > 48:
        args.s = 48

    # We do not need any delay in other WMs
    if other_wm:
        args.d = 0

    # Replace appendix template file name with custom - if any
    if args.af:
        build_from_file = os.path.join(config_dirs()[0], args.af)

    if css_file:
        screen = Gdk.Screen.get_default()
        provider = Gtk.CssProvider()
        try:
            provider.load_from_path(css_file)
            Gtk.StyleContext.add_provider_for_screen(
                screen, provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
        except Exception as e:
            print(e)

    screen = Gdk.Screen.get_default()
    provider = Gtk.CssProvider()
    style_context = Gtk.StyleContext()
    style_context.add_provider_for_screen(
        screen, provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)

    global all_commands_list
    all_commands_list = list_commands()
    all_commands_list.sort()

    # Overlay window
    global win
    win = MainWindow()
    if other_wm:
        # We need this to obtain the screen geometry when i3ipc module unavailable
        win.resize(1, 1)
        win.show_all()
    global geometry
    # If we're not on sway neither i3, this won't return values until the window actually shows up.
    # Let's try as many times as needed. The retries int protects from an infinite loop.
    retries = 0
    while geometry[0] == 0 and geometry[1] == 0 and geometry[
            2] == 0 and geometry[3] == 0:
        geometry = display_geometry(win, wm, mouse_pointer)
        retries += 1
        if retries > 50:
            print("\nFailed to get the current screen geometry, exiting...\n")
            sys.exit(2)
    x, y, w, h = geometry

    if not other_wm:
        # resize to the active screen dimensions on sway/i3
        win.resize(w, h)
    else:
        win.resize(1, 1)
        win.set_gravity(Gdk.Gravity.CENTER)
        if mouse_pointer:
            x, y = mouse_pointer.position
            win.move(x, y)
        else:
            win.move(0, 0)
            print("\nYou need the python-pynput package!\n")

    # hide window from panel on Openbox
    win.set_skip_taskbar_hint(True)

    win.menu = build_menu(all_commands_list)
    win.menu.set_property("name", "menu")

    global menu_items_list
    menu_items_list = win.menu.get_children()

    win.menu.propagate_key_event = False
    win.menu.connect("key-release-event", win.search_items)
    # Let's reserve some width for long entries found with the search box
    if args.w:
        win.menu.set_property("width_request", args.w)
    else:
        win.menu.set_property("width_request",
                              int(win.screen_dimensions[0] / 8))
    win.show_all()

    # on sway/i3 we need a timeout for window to appear in the proper place; for other_wm args.d has been zeroed
    GLib.timeout_add(args.d, open_menu)
    Gtk.main()