added clip_wl - clipboard manager for wayland

This commit is contained in:
Paul Wilde 2022-07-16 14:20:55 +01:00
parent 41b3f5728b
commit 8875f99279
4 changed files with 140 additions and 5 deletions

View file

@ -34,6 +34,7 @@ type
x*: int x*: int
y*: int y*: int
const WM_TOOLS_DIR* = getHomeDir() & "Nextcloud/.wm_tools/"
const background* = "#000000" const background* = "#000000"
const backgroundalt* = "#bb222222" const backgroundalt* = "#bb222222"
const backgroundalt2* = "#bb333333" const backgroundalt2* = "#bb333333"
@ -136,8 +137,10 @@ proc debugLog*(str: string) =
proc switchTwmMode*(mode: string = "default") = proc switchTwmMode*(mode: string = "default") =
# I intend to add support for more twm as time goes on (I switch around a lot) # I intend to add support for more twm as time goes on (I switch around a lot)
# Switch out of an i3 bindsym mode if set # Switch out of an i3 bindsym mode if set
discard execCmd("sway mode \"" & mode & "\"") if wayland:
discard execCmd("i3-msg mode \"" & mode & "\"") discard execCmd("sway mode \"" & mode & "\"")
else:
discard execCmd("i3-msg mode \"" & mode & "\"")
proc checkWayland() = proc checkWayland() =
if getEnv("XDG_SESSION_TYPE") == "wayland": if getEnv("XDG_SESSION_TYPE") == "wayland":
@ -216,7 +219,10 @@ proc runMenu*(data: Info, opts: varargs[string], rofi: bool = false): string =
return output.output return output.output
proc copyToClipboard*(str: string) = proc copyToClipboard*(str: string) =
discard execCmd("echo -n " & quote(str) & " | xclip -selection clipboard") if wayland:
discard execCmd("wl-copy " & str)
else:
discard execCmd("echo -n " & quote(str) & " | xclip -selection clipboard")
proc outputData*(data: Info, args: varargs[string]): string {.discardable.} = proc outputData*(data: Info, args: varargs[string]): string {.discardable.} =
var output = "" var output = ""
@ -234,13 +240,17 @@ proc outputData*(data: Info, args: varargs[string]): string {.discardable.} =
return output return output
proc checkCacheDir() =
if not dirExists(WM_TOOLS_DIR):
createDir(WM_TOOLS_DIR)
# At Start up: # At Start up:
checkCacheDir()
checkWayland()
# Switch bindsym mode back to default as it could be being used. # Switch bindsym mode back to default as it could be being used.
switchTwmMode() switchTwmMode()
checkWayland()
let args* = getArguments() let args* = getArguments()
for idx, arg in args: for idx, arg in args:

116
clip_wl.nim Normal file
View file

@ -0,0 +1,116 @@
import base
import std/[strutils,os,db_sqlite,osproc]
const CLIP_DB = WM_TOOLS_DIR & ".clipboard_cache.sqlite"
const KEEP_ITEMS = 20
proc openDBConn(): DBConn =
let db: DBconn = open(CLIP_DB,"","","")
try:
db.exec(sql"""create table if not exists
clip_items (
timestamp DATETIME NOT NULL,
clip NVARCHAR(500) NOT NULL
)
""")
except:
echo getCurrentExceptionMsg()
return db
proc clearHistory() =
let db = openDBConn()
defer: db.close()
try:
db.exec(sql"drop table if exists clip_items")
except:
echo getCurrentExceptionMsg()
proc getCurrentClipboardContent(): string =
var str = ""
if wayland:
let cur = execCmdEx("wl-paste")
if cur.exitcode == 0:
str = cur[0]
else:
echo cur
return str
proc maintainDB() =
let db = openDBConn()
try:
db.exec(sql"""BEGIN""")
db.exec(sql"delete from clip_items order by timestamp desc offset ?", KEEP_ITEMS)
db.exec(sql"""COMMIT""")
except:
echo getCurrentExceptionMsg()
proc escapeClip(str: string): string =
var clip = str
clip = clip.replace("`","\\`")
clip = escape(clip)
return clip
proc unescapeClip(str: string): string =
var clip = str
try:
clip = unescape(clip)
except:
echo getCurrentExceptionMsg()
return clip
proc readClipFile(): seq[string] =
var clips: seq[string] = @[]
let db = openDBConn()
defer: db.close()
try:
for row in db.fastRows(sql"select clip from clip_items order by timestamp desc"):
var str = unescapeClip(row[0])
clips.add(str)
except:
echo getCurrentExceptionMsg()
return clips
proc addClip(str: string) =
if str == "":
return
let db = openDBConn()
defer: db.close()
try:
db.exec(sql"""BEGIN""")
db.exec(sql"""insert into clip_items (timestamp, clip)
values (CURRENT_TIMESTAMP, ?)
""", escapeClip(str))
db.exec(sql"""COMMIT""")
except:
echo getCurrentExceptionMsg()
return
proc showClips() =
let clips = readClipFile()
let info = newInfo("Clips")
let option = outputData(info, clips)
if option != "":
copyToClipboard(option)
return
proc main() =
for idx, arg in args:
if arg == "set":
addClip(getCurrentClipboardContent())
return
if arg == "clear":
clearHistory()
return
showClips()
return
block start:
if isMainModule:
if not wayland:
echo "Not a wayland session, exiting..."
break start
else:
main()
maintainDB()

View file

@ -1,7 +1,7 @@
import base import base
import std/[os,strutils,sequtils,times] import std/[os,strutils,sequtils,times]
const note_dir = getHomeDir() & "Nextcloud/.notes.dmenu/" # Putting it in Nextcloud so it can sync :-) const note_dir = WM_TOOLS_DIR & ".notes.dmenu/" # Putting it in Nextcloud so it can sync :-)
const default_bg = white const default_bg = white
const default_fg = black const default_fg = black

View file

@ -3,12 +3,18 @@ import std/[os,osproc,tables,algorithm]
import configparser import configparser
const REMMINA_DIR = getHomeDir() & ".local/share/remmina" const REMMINA_DIR = getHomeDir() & ".local/share/remmina"
const REMMINA_WS = "4"
var sessions = initTable[string,string]() var sessions = initTable[string,string]()
var names: seq[string] = @[] var names: seq[string] = @[]
proc main() proc main()
proc switchWorkspace() =
if REMMINA_WS != "":
discard execCmd("i3-msg workspace number " & REMMINA_WS)
discard execCmd("swaymsg workspace number " & REMMINA_WS)
proc getRemminaFiles(): seq[string] = proc getRemminaFiles(): seq[string] =
if len(names) < 1: if len(names) < 1:
for file in walkFiles(REMMINA_DIR & "/*.remmina"): for file in walkFiles(REMMINA_DIR & "/*.remmina"):
@ -40,12 +46,15 @@ proc selectRemmina(conn: string) =
case output: case output:
of "connect": of "connect":
startRemmina(conn) startRemmina(conn)
switchWorkspace()
of "edit": of "edit":
editRemmina(conn) editRemmina(conn)
switchWorkspace()
of "back": of "back":
main() main()
proc main() = proc main() =
var info = newInfo("Remmina") var info = newInfo("Remmina")
var args: seq[string] = getRemminaFiles() var args: seq[string] = getRemminaFiles()