diff --git a/i3/conf/common/base b/i3/conf/common/base index a222771..052c594 100644 --- a/i3/conf/common/base +++ b/i3/conf/common/base @@ -144,7 +144,7 @@ floating_modifier $mod # Screensaver || ThinkVantage bindsym XF86ScreenSaver exec xautolock -locknow bindsym XF86Battery exec xautolock -locknow - bindsym XF86Launch1 exec "xautolock -locknow; sleep 1; xset dpms force off" + bindsym XF86Launch1 exec "xautolock -locknow; sync; systemctl suspend-then-hibernate" # Lock screen bindsym $mod+Ctrl+l exec "xautolock -locknow; sleep 1; xset dpms force off" diff --git a/i3/scripts/autorun.sh b/i3/scripts/autorun.sh deleted file mode 100755 index 13ee4db..0000000 --- a/i3/scripts/autorun.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env bash - -function run { - if ! pgrep $1 ; - then - $@& - fi -} -run compton -run kwalletd5 -run xscreensaver -nosplash -nitrogen --restore & - -# Programms -run nextcloud -#run telegram-desktop -#run discord -#run thunderbird diff --git a/i3/scripts/dmenu/Dmenu.py b/i3/scripts/dmenu/Dmenu.py deleted file mode 100644 index e0578f4..0000000 --- a/i3/scripts/dmenu/Dmenu.py +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -import os -import sys -import json -import subprocess - - -class Dmenu(object): - def __init__(self, items: list): - with open(os.path.dirname(sys.argv[0]) + "/dmenu.json") as fp: - self._dmenu = json.load(fp)["dmenu"] - self._items = items - - def run(self): - """Returns (exitCode, stdout)""" - p1 = subprocess.run( - self._dmenu, - input="\n".join(self._items), - encoding="utf-8", - stdout=subprocess.PIPE, - ) - return (p1.returncode, p1.stdout) diff --git a/i3/scripts/dmenu/dmenu.json b/i3/scripts/dmenu/dmenu.json deleted file mode 100644 index 60ef1ef..0000000 --- a/i3/scripts/dmenu/dmenu.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "dmenu": [ - "dmenu", - "-i", - "-l", - "6", - "-x", - "550", - "-y", - "400", - "-w", - "500", - "-h", - "20", - "-dim", - "0.2", - "-p", - "Do", - "-fn", - "Inconsolata-14:normal", - "-nb", - "#3F3F3F", - "-nf", - "#DCDCCC", - "-sb", - "#1E2320", - "-sf", - "#F0DFAF" - ] -} diff --git a/i3/scripts/dmenu/init.py b/i3/scripts/dmenu/init.py deleted file mode 100755 index 497a376..0000000 --- a/i3/scripts/dmenu/init.py +++ /dev/null @@ -1,145 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -import sqlite3 -import json -import argparse -import sys -import os -from modules import Application, MPC -from Dmenu import Dmenu - -del sys.path[0] -sys.path.insert(0, os.path.dirname(sys.argv[0])) - - -# CONFIG -loadModules = [Application(), MPC()] - -con = sqlite3.connect(os.path.dirname(sys.argv[0]) + "/database.sqlite") - -# ARGUMENTS PARSER - -parser = argparse.ArgumentParser(description="Smart Dropdown Launcher for AwesomeWM") -parser.add_argument( - "--create", - dest="FLAG_CREATE", - action="store_const", - const=True, - default=False, - help="Force TABLE \ - CREATION", -) -parser.add_argument( - "--build", - dest="FLAG_BUILD", - action="store_const", - const=True, - default=False, - help="Force Build \ -the Database", -) -parser.add_argument( - "--truncate", - dest="FLAG_TRUNCATE", - action="store_const", - const=True, - default=False, - help="Truncate\ - Database during build", -) -args = parser.parse_args() - - -# Helper functions - - -def create_db(): - command = "CREATE TABLE entries(`ID` INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE, `Name` TEXT, `json` TEXT, `hits` INTEGER NOT NULL DEFAULT 0, `disabled` INTEGER NOT NULL DEFAULT 0, `type` TEXT NOT NULL DEFAULT 'file', `file` TEXT);" - with con: - cur = con.cursor() - cur.execute(command) - con.commit() - - -def retrieve_db(): - rows = [] - with con: - con.row_factory = sqlite3.Row - cur = con.cursor() - cur.execute("SELECT * FROM entries;") - ro = cur.fetchall() - for r in ro: - r = dict(r) - r["json"] = json.loads(r["json"]) - rows.append(r) - return rows - - -def build_db(): - entries = {} - for mod in loadModules: - entries.update(mod.build_db()) - for k, v in entries.items(): - if "Exec" in v["json"]: - with con: - con.cursor().execute( - "INSERT INTO entries(Name, json, file, type, disabled) VALUES(?, ?, ?, ?, ?)", - (k, json.dumps(v["json"]), v["file"], v["type"], v["disabled"]), - ) - - -def build_menu(): - entries = [] - db = retrieve_db() - for mod in loadModules: - entries += mod.build_menu([x for x in db if x["type"] == mod.db_type]) - - # sort by hits - return sorted(entries, key=lambda i: i[2], reverse=True) - - -def run_program(data): - with con: - cur = con.cursor() - cur.execute("UPDATE entries SET hits=? WHERE ID=?", (data[2] + 1, data[0])) - cur.execute("SELECT type FROM entries WHERE ID=?", (data[0],)) - con.commit() - typ = dict(cur.fetchone())["type"] - for mod in loadModules: - if mod.db_type == typ: - mod.call(data[1]) - - -if args.FLAG_CREATE: - with con: - con.cursor().execute("DROP TABLE IF EXISTS entries;") - create_db() - # set BUILD flag so the database gets rebuilt too - args.FLAG_BUILD = True - -if args.FLAG_BUILD: - if args.FLAG_TRUNCATE: - with con: - con.cursor().execute("DELETE FROM entries") - con.cursor().execute("DELETE FROM sqlite_sequence WHERE name='entries'") - con.commit() - build_db() - -entries = build_menu() -p1 = Dmenu([x[1] for x in entries]).run() - -if p1[0] != 0: - # error on escape - exit(1) - -selected = list(filter(lambda x: p1[1].strip().startswith(x[1]), entries)) -if selected == []: - # -> terminal module? None-Type modules? - pass -else: - # use actual user input - selected = (selected[0][0], p1[1].rstrip(), selected[0][2]) - run_program(selected) - -con.close() diff --git a/i3/scripts/dmenu/modules/Application.py b/i3/scripts/dmenu/modules/Application.py deleted file mode 100644 index 2c2c113..0000000 --- a/i3/scripts/dmenu/modules/Application.py +++ /dev/null @@ -1,128 +0,0 @@ -from .Module import Module as _Module -import locale as _locale -import subprocess as _subprocess -import shlex as _shlex -from pathlib import Path as _Path -from os import listdir as _listdir -from os.path import isfile as _isfile, join as _join - - -class Application(_Module): - - def __init__(self): - self.db_type = "Application" - self._home = str(_Path.home()) - self._lang = _locale.getlocale()[0].split("_")[0].strip() - self._dirs = ["/usr/share/applications", self._home + "/.local/share/applications"] - self._references = {} - - def build_db(self): - """Function which adds entries to the database. - returns dict with: - Name, json, disabled, type, "file" """ - db = {} - for d in self._dirs: - for fi in _listdir(d): - if _isfile(_join(d, fi)): - fc = self._scan_file(_join(d, fi)) - for k, v in fc.items(): - db.update({k: { - "Name": k, - "json": v, - "disabled": (("NoDisplay" in v and v["NoDisplay"] == "true") or - ("Hidden" in v and v["Hidden"] == "true")), - "file": v['file'], - "type": self.db_type - }}) - return db - - def update_db(self, database: dict): - """Function which updates entries in the database. - returns dict with modified/deleted/added database entries""" - entries = self.build_db() - dbremove = [] - # dbKey == id, dbValue dict of fileds - for dbKey, dbValue in database: - if dbValue["type"] == self.db_type: - if dbValue["Name"] not in entries: - dbremove.append(dbKey) - else: - # update all values managed by this module - for k, v in entries[dbValue["Name"]]: - dbValue[k] = v - # remove no more existing entries - for i in dbremove: - database.pop(i) - return database - - def build_menu(self, items: dict): - """Builds the menu entries. - return list of tuples (id, name, hits)""" - # we only get entries of our app type so no problem here - # json is already unjsonified - NAME_PREFIX="run " - NAME_POSTFIX=" (%PATH%)" - entries = [] - for r in items: - identifier=(NAME_PREFIX + r['Name'] + NAME_POSTFIX).replace("%PATH%", r['json']['Exec']) - entries.append((r['ID'], identifier, r['hits'])) - if ("Terminal" not in r["json"]): - r['json']["Terminal"] = "false" - self._references[identifier] = (r['json']["Exec"], r['json']["Terminal"], r['file'], r['Name']) - - return entries - - def call(self, cmd: str): - """Handles the selected entry""" - # find the entry - reference = list(filter(lambda x: cmd.startswith(x), self._references.keys())) - entry = reference[0] - cmd = cmd.replace(entry, "").lstrip() - # Just call the program - _subprocess.Popen(_shlex.split(self._expand_fieldcodes(self._references[entry][0], cmd, reference)), - encoding="utf-8", - shell=(self._references[entry][1] == "true")) - - def _scan_file(self, fi): - entries = {} - with open(fi, encoding="utf-8", mode="r") as f: - data = {} - for line in f: - line = line.strip() - if line.startswith("["): # and line.rstrip() != "[Desktop Entry]": - data["header"] = line.strip("[]") - if "Name" in data and "Exec" in data: - data['file'] = fi - entries[data["Name"]] = data - data = {} - if "=" in line: - s = line.split("=") - if "[" in s[0] and "]" in s[0]: - if "[" + self._lang + "]" in s[0]: - data[s[0].replace("[" + self._lang + "]", "").strip()] = s[1] - elif s[0] != "Name" or "Name" not in data.keys(): - data[s[0]] = s[1] - - if "Name" in data: - data['file'] = fi - entries[data["Name"]] = data - return entries - - def _expand_fieldcodes(self, entry: str, cmd: str, reference): - fieldcodes = ['%f', '%F', '%u', '%U', '%i', '%c', '%k'] # todo implement %i as expand icon-key - for fc in range(0, len(fieldcodes)): - fieldcodes[fc] = fieldcodes[fc] in entry - if True in fieldcodes: - if '%k' in entry: - entry = entry.replace('%k', '"' + reference[2] + "'") - if '%c' in entry: - entry = entry.replace('%c', '"' + reference[3] + "'") - if '%i' in entry: - entry = entry.replace(' %i', "") - if '%f' in entry or '%F' in entry or '%u' in entry or '%U' in entry: - entry = entry.replace('%f', cmd) - entry = entry.replace('%F', cmd) - entry = entry.replace('%u', cmd) - entry = entry.replace('%U', cmd) - cmd = "" - return (entry + " " + cmd).rstrip() diff --git a/i3/scripts/dmenu/modules/MPC.py b/i3/scripts/dmenu/modules/MPC.py deleted file mode 100644 index 2f6070a..0000000 --- a/i3/scripts/dmenu/modules/MPC.py +++ /dev/null @@ -1,118 +0,0 @@ -from .Module import Module as _Module -import locale as _locale -from pathlib import Path as _Path -from Dmenu import Dmenu -import subprocess as _subprocess - - -class MPC(_Module): - - def __init__(self): - self.db_type = "MPC" - self._home = str(_Path.home()) - self._lang = _locale.getlocale()[0].split("_")[0].strip() - self._dirs = ["/usr/share/applications", self._home + "/.local/share/applications"] - self.replace = True - - def build_db(self): - """Function which adds entries to the database. - returns dict with: - Name, json, disabled, type, "file" """ - - # we only add an generic Submenu entry. - db = {"Media Player Control [MPC]": { - "Name": "Media Player Control [MPC]", - "json": "", - "disabled": False, - "file": "none", - "type": self.db_type - }} - return db - - def update_db(self, database: dict): - """Function which updates entries in the database. - returns dict with modified/deleted/added database entries""" - return self.build_db() - - def build_menu(self, items: dict): - """Builds the menu entries. - return list of tuples (id, name, hits)""" - # we only get entries of our app type so no problem here - # json is already unjsonified - entries = [] - for r in items: - entries.append((r['ID'], r['Name'], r['hits'])) - - return entries - - def gatherInfo(self): - out = {} - infoprocess = _subprocess.run("mpc", stdout=_subprocess.PIPE, shell=True) - info = infoprocess.stdout.decode("utf8").split("\n") - if len(info) == 4: - status = [x.split(":") for x in info[2].split(" ")] - - out["song"] = info[0] - out["playing"] = "[playing]" in info[1] - - else: - status = [x.split(":") for x in info[0].split(" ")] - - out["replace"] = self.replace - status = [x for x in status if len(x) == 2] - - for i in status: - i[0] = i[0].strip() - i[1] = i[1].strip() - if i[1] == "off": - out[i[0]] = False - elif i[1] == "on": - out[i[0]] = True - else: - out[i[0]] = i[1] - return out - - def buildStatusMenu(self): - info = self.gatherInfo() - if info["replace"]: - playlists = ['MODE: REPLACE'] - else: - playlists = ['MODE: APPEND'] - - if info["random"]: - playlists += ['RANDOM: on'] - else: - playlists += ['RANDOM: off'] - - return (len(playlists), playlists) - - def handleStatusMenu(self, text: str): - if text.startswith("MODE: "): - self.replace = not self.replace - elif text.startswith("RANDOM: "): - _subprocess.run("mpc random", shell=True) - - def call(self, cmd: str): - """Handles the selected entry""" - # our menu entry was selected, time to create and show the submenu - while True: - infolen, playlists = self.buildStatusMenu() - - playprocess = _subprocess.run("mpc lsplaylists", stdout=_subprocess.PIPE, shell=True) - playlists += playprocess.stdout.decode("utf8").split("\n") - menu = Dmenu(playlists) - ex = menu.run() - - if ex[0] == 0: - if ex[1].rstrip() in playlists[0:infolen]: - self.handleStatusMenu(ex[1].rstrip()) - continue - # user selected an entry - # mpc clear(?) -> mpc load ex[1] -> mpc play - command = "mpc load '" + ex[1].rstrip() + "'" - if self.replace: - command = "mpc clear; " + command + "; mpc play" - _subprocess.run(command, shell=True) - break - else: - break diff --git a/i3/scripts/dmenu/modules/Module.py b/i3/scripts/dmenu/modules/Module.py deleted file mode 100644 index 619c805..0000000 --- a/i3/scripts/dmenu/modules/Module.py +++ /dev/null @@ -1,25 +0,0 @@ -class Module(object): - """Abstract class, implement: build_db, update_db, build_menu, call""" - - def __init__(self, obj): - pass - - def build_db(): - """Function which adds entries to the database. - returns dict with: - Name, json, disabled, type, "file" """ - raise NotImplementedError("Should have implemented this") - - def update_db(database: dict): - """Function which updates entries in the database. - returns dict with modified/deleted/added database entries""" - raise NotImplementedError("Should have implemented this") - - def build_menu(items: dict): - """Builds the menu entries. - return list of tuples (id, name, hits)""" - raise NotImplementedError("Should have implemented this") - - def call(entry: str): - """Handles the selected entry""" - raise NotImplementedError("Should have implemented this") diff --git a/i3/scripts/dmenu/modules/__init__.py b/i3/scripts/dmenu/modules/__init__.py deleted file mode 100644 index 03e78ad..0000000 --- a/i3/scripts/dmenu/modules/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -from .Application import Application -from .MPC import MPC