diff --git a/config/.bash_profile b/config/.bash_profile index f5c063190..527a0386f 100644 --- a/config/.bash_profile +++ b/config/.bash_profile @@ -28,6 +28,36 @@ export VISUAL="st -n editor -c editor -e $EDITOR" export BROWSER="flatpak run com.brave.Browser" export VIEWER="zathura" +# Dev Tools Envs +export GOPATH="$HOME/.go" +export DOTNET_ROOT="$HOME/.dotnet" + +# Set path +if [ -d "$HOME/.bin" ] ; + then PATH="$HOME/.bin:$PATH" +fi +if [ -d "$HOME/.local/bin" ] ; + then PATH="$HOME/.local/bin:$PATH" +fi +if [ -d "$HOME/.cargo/bin" ] ; + then PATH="$HOME/.cargo/bin:$PATH" +fi +if [ -d "$HOME/Applications" ] ; + then PATH="$HOME/Applications:$PATH" +fi +if [ -d "$HOME/.go/bin" ] ; + then PATH="$HOME/.go/bin:$PATH" +fi +if [ -d $XDG_DATA_HOME/JetBrains/Toolbox/scripts ]; + then PATH="$XDG_DATA_HOME/JetBrains/Toolbox/scripts:$PATH" +fi +if [ -d $HOME/.dotnet/ ]; + then PATH="$HOME/.dotnet/:$PATH" +fi +if [ -d $HOME/.dotnet/tools/ ]; + then PATH="$HOME/.dotnet/tools/:$PATH" +fi + # Bashrc source "$BASHRC" @@ -35,7 +65,6 @@ source "$BASHRC" if [ ! -d "$WGETDIR" ] || [ ! -d "$GNUPGHOME" ]; then mkdir -p "$WGETDIR" "$GNUPGHOME" fi - if [ ! -f "$WGETRC" ]; then touch "$WGETRC" fi @@ -45,4 +74,3 @@ if [ -z "$DISPLAY" ] && [ "$(tty)" = "/dev/tty1" ]; then startx "$XINITRC" -- vt1 -keeptty &>> /dev/null logout fi - diff --git a/config/.bashrc b/config/.bashrc index 4b15c5f50..851b8b771 100644 --- a/config/.bashrc +++ b/config/.bashrc @@ -1,7 +1,6 @@ ### EXPORT ### export TERM="xterm-256color" # getting proper colors export HISTCONTROL=ignoredups:erasedups # no duplicate entries -export GOPATH="$HOME/.go" ### "bat" as manpager export MANPAGER="bat -p" @@ -19,27 +18,6 @@ set -o vi bind -m vi-command 'Control-l: clear-screen' bind -m vi-insert 'Control-l: clear-screen' -### PATH ### -if [ -d "$HOME/.bin" ] ; - then PATH="$HOME/.bin:$PATH" -fi -if [ -d "$HOME/.local/bin" ] ; - then PATH="$HOME/.local/bin:$PATH" -fi -if [ -d "$HOME/.cargo/bin" ] ; - then PATH="$HOME/.cargo/bin:$PATH" -fi -if [ -d "$HOME/Applications" ] ; - then PATH="$HOME/Applications:$PATH" -fi -if [ -d "$HOME/.go/bin" ] ; - then PATH="$HOME/.go/bin:$PATH" -fi -if [ -d $XDG_DATA_HOME/JetBrains/Toolbox/scripts ]; - then PATH="$XDG_DATA_HOME/JetBrains/Toolbox/scripts:$PATH" -fi - - ### CHANGE TITLE OF TERMINALS ### case ${TERM} in xterm*|rxvt*|Eterm*|aterm|kterm|gnome*|alacritty|st|konsole*) @@ -130,6 +108,9 @@ alias \ # bat as cat [ -x "$(command -v bat)" ] && alias cat="bat" +# fastfetch as neofetch +[ -x "$(command -v fastfetch)" ] && alias neofetch="fastfetch" + # use lunarvim or neovim for vim if present. if [ -x "$(command -v $HOME/.local/bin/lvim)" ]; then alias vim="$HOME/.local/bin/lvim" @@ -229,6 +210,10 @@ alias \ yt="ytfzf -ftsl" \ ytm="ytfzf -mtsl" +# distrobox +alias \ + dv="distrobox enter devbox" + # network and bluetooth alias \ netstats="nmcli dev" \ diff --git a/config/.config/doom/config.el b/config/.config/doom/config.el index 189f71dcf..e89e29b12 100644 --- a/config/.config/doom/config.el +++ b/config/.config/doom/config.el @@ -82,6 +82,28 @@ :desc "Clippy describes function under point" "f" #'clippy-describe-function :desc "Clippy describes variable under point" "v" #'clippy-describe-variable)) +(require 'dap-netcore) +(require 'dap-dlv-go) +(map! :leader + (:prefix ("d" . "dap-mode") + :desc "Toggle breakpoint" "t" #'dap-breakpoint-toggle + :desc "Continue execution" "c" #'dap-continue + :desc "Step in" "n" #'dap-step-in + :desc "Step out" "N" #'dap-step-out + :desc "See all breakpoints" "b" #'dap-ui-breakpoints-toggle + :desc "Change variable value" "s" #'dap-ui-set-variable-value + :desc "Evaluate expression at point" "e" #'dap-eval-thing-at-point + :desc "Evaluate expression" "E" #'dap-eval + :desc "Run debugger" "r" #'dap-debug + :desc "Restart debugger" "R" #'dap-debug-restart + :desc "Stop debugger" "d" #'dap-disconnect)) +(use-package dap-mode + :init + (dap-auto-configure-mode) + + :custom + (dap-netcore-download-url "https://github.com/Samsung/netcoredbg/releases/download/3.1.0-1031/netcoredbg-linux-amd64.tar.gz")) + ;; With dired-open plugin, you can launch external programs for certain ;; extensions For example, I set all .png files to open in 'vimiv' and all .mp4 ;; files to open in 'mpv' @@ -89,6 +111,7 @@ ("jpg" . "vimiv") ("png" . "vimiv") ("mkv" . "mpv") + ("mp3" . "mpv") ("mp4" . "mpv"))) (evil-define-key 'normal peep-dired-mode-map @@ -167,6 +190,12 @@ :desc "Toggle line highlight globally" "H" #'global-hl-line-mode :desc "Toggle truncate lines" "t" #'toggle-truncate-lines)) +(add-hook 'csharp-mode-hook #'lsp-deferred) + +(add-hook 'go-mode-hook #'lsp-deferred) + +(add-hook 'rust-mode-hook #'lsp-deferred) + (custom-set-faces '(markdown-header-face ((t (:inherit font-lock-function-name-face :weight bold :family "Mononoki Nerd Font")))) '(markdown-header-face-1 ((t (:inherit markdown-header-face :height 1.7)))) @@ -308,3 +337,5 @@ (set-frame-parameter nil 'alpha-background 98) ; For current frame (add-to-list 'default-frame-alist '(alpha-background . 98)) ; For all new frames henceforth +(when (daemonp) + (exec-path-from-shell-initialize)) diff --git a/config/.config/doom/config.org b/config/.config/doom/config.org index 965e5107f..074984901 100644 --- a/config/.config/doom/config.org +++ b/config/.config/doom/config.org @@ -14,6 +14,7 @@ - [[#keybindings-within-ibuffer-mode][Keybindings within ibuffer mode]] - [[#calendar][CALENDAR]] - [[#clippy][CLIPPY]] +- [[#dap-mode][DAP MODE]] - [[#dired][DIRED]] - [[#keybindings-within-dired-with-peep-dired-mode-enabled][Keybindings Within Dired With Peep-Dired-Mode Enabled]] - [[#making-deleted-files-go-to-trash-can][Making deleted files go to trash can]] @@ -25,6 +26,7 @@ - [[#ivy-posframe][IVY-POSFRAME]] - [[#ivy-keybindings][IVY KEYBINDINGS]] - [[#line-settings][LINE SETTINGS]] +- [[#lsp][LSP]] - [[#markdown][MARKDOWN]] - [[#modeline][MODELINE]] - [[#mouse-support][MOUSE SUPPORT]] @@ -216,6 +218,33 @@ describe-variable respectively). :desc "Clippy describes variable under point" "v" #'clippy-describe-variable)) #+end_src +* DAP MODE +dap-mode is a debugger manager for emacs that supports multiple languages. + +#+begin_src emacs-lisp +(require 'dap-netcore) +(require 'dap-dlv-go) +(map! :leader + (:prefix ("d" . "dap-mode") + :desc "Toggle breakpoint" "t" #'dap-breakpoint-toggle + :desc "Continue execution" "c" #'dap-continue + :desc "Step in" "n" #'dap-step-in + :desc "Step out" "N" #'dap-step-out + :desc "See all breakpoints" "b" #'dap-ui-breakpoints-toggle + :desc "Change variable value" "s" #'dap-ui-set-variable-value + :desc "Evaluate expression at point" "e" #'dap-eval-thing-at-point + :desc "Evaluate expression" "E" #'dap-eval + :desc "Run debugger" "r" #'dap-debug + :desc "Restart debugger" "R" #'dap-debug-restart + :desc "Stop debugger" "d" #'dap-disconnect)) +(use-package dap-mode + :init + (dap-auto-configure-mode) + + :custom + (dap-netcore-download-url "https://github.com/Samsung/netcoredbg/releases/download/3.1.0-1031/netcoredbg-linux-amd64.tar.gz")) +#+end_src + * DIRED Dired is the file manager within Emacs. @@ -227,6 +256,7 @@ Dired is the file manager within Emacs. ("jpg" . "vimiv") ("png" . "vimiv") ("mkv" . "mpv") + ("mp3" . "mpv") ("mp4" . "mpv"))) #+end_src @@ -411,6 +441,24 @@ commands, so I choose 'SPC t' plus 'key' for those bindings. :desc "Toggle truncate lines" "t" #'toggle-truncate-lines)) #+END_SRC +* LSP +Autostart lsp for programming languages + +- C#: +#+begin_src emacs-lisp +(add-hook 'csharp-mode-hook #'lsp-deferred) +#+end_src + +- Go: +#+begin_src emacs-lisp +(add-hook 'go-mode-hook #'lsp-deferred) +#+end_src + +- Rust: +#+begin_src emacs-lisp +(add-hook 'rust-mode-hook #'lsp-deferred) +#+end_src + * MARKDOWN #+begin_src emacs-lisp @@ -700,11 +748,12 @@ the second occurrence of 'e'. :desc "Zap up to char" "Z" #'zap-up-to-char) #+END_SRC - * TRANSPARENT Transparent window #+BEGIN_SRC emacs-lisp (set-frame-parameter nil 'alpha-background 98) ; For current frame (add-to-list 'default-frame-alist '(alpha-background . 98)) ; For all new frames henceforth +(when (daemonp) + (exec-path-from-shell-initialize)) #+END_SRC diff --git a/config/.config/doom/packages.el b/config/.config/doom/packages.el index cc5de0ef7..fca966e48 100644 --- a/config/.config/doom/packages.el +++ b/config/.config/doom/packages.el @@ -80,3 +80,4 @@ (package! csproj-mode) (package! dap-mode) (package! vimrc-mode) +(package! exec-path-from-shell) diff --git a/source/dmenu/scripts/dmenu_power b/source/dmenu/scripts/dmenu_power index 30e939f27..252b370ec 100755 --- a/source/dmenu/scripts/dmenu_power +++ b/source/dmenu/scripts/dmenu_power @@ -86,7 +86,7 @@ case "$action" in fi ;; "$option4") - slock -b "$currentwall" systemctl suspend + slock -b "$currentwall" loginctl suspend ;; "$option5") slock -b "$currentwall" diff --git a/source/dwm/config.h b/source/dwm/config.h index 30ae97ebf..27bb790d5 100644 --- a/source/dwm/config.h +++ b/source/dwm/config.h @@ -19,7 +19,7 @@ static const unsigned int baralpha = 0xd0; static const unsigned int borderalpha = OPAQUE; static const XPoint stickyicon[] = { {0,0}, {4,0}, {4,8}, {2,6}, {0,8}, {0,0} }; /* represents the icon as an array of vertices */ static const XPoint stickyiconbb = {4,8}; /* defines the bottom right corner of the polygon's bounding box (speeds up scaling) */ -static const char start_script[] = "$HOME/.config/suckless/dwm/scripts/autostart"; +static const char start_script[] = "$HOME/.config/suckless/dwm/scripts/autostart"; #define ICONSIZE 16 /* window icon size */ #define ICONSPACING 5 /* space between window icon and title (only when text is truncated) */ @@ -85,8 +85,8 @@ static const char *tags[] = { /* Window Rules */ static const Rule rules[] = { /* xprop(1): - * WM_CLASS(STRING) = instance, class - * WM_NAME(STRING) = title + * WM_CLASS(STRING) = instance, class + * WM_NAME(STRING) = title */ /* CLASS - INSTANCE - TITLE - TAGS MASK - ISFLOATING - MONITOR */ /* 0 - No Tag */ @@ -225,16 +225,16 @@ static const Layout layouts[] = { #define TAGKEYS(KEY,TAG) \ &((Keychord){1, {{MODKEY, KEY}}, comboview, {.ui = 1 << TAG} }), \ &((Keychord){1, {{MODKEY|ControlMask, KEY}}, toggleview, {.ui = 1 << TAG} }), \ - &((Keychord){1, {{MODKEY|ShiftMask, KEY}}, combotag, {.ui = 1 << TAG} }), \ - &((Keychord){1, {{MODKEY|ControlMask|ShiftMask, KEY}}, toggletag, {.ui = 1 << TAG} }), + &((Keychord){1, {{MODKEY|ShiftMask, KEY}}, combotag, {.ui = 1 << TAG} }), \ + &((Keychord){1, {{MODKEY|ControlMask|ShiftMask, KEY}}, toggletag, {.ui = 1 << TAG} }), /* Helper for spawning shell commands in the pre dwm-5.0 fashion */ -#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } +#define SHCMD(cmd) { .v = (const char*[]){ "/bin/bash", "-c", cmd, NULL } } /* Main commands */ static const char *dmenucmd[] = { "dmenu_run", "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL }; static const char *termcmd[] = { "st", NULL }; -static const char *editor[] = { "st", "-n", "editor", "-c", "editor", "-e", ".local/bin/lvim", NULL }; +static const char *editor[] = { "emacsclient", "-c", "-a", "'emacs'", NULL }; static const char *browser[] = { "flatpak", "run", "com.brave.Browser", NULL }; static const char *chat[] = { "flatpak", "run", "org.signal.Signal", NULL }; static const char *vm[] = { "virt-manager", NULL }; @@ -332,17 +332,17 @@ static Keychord *keychords[] = { /* Scratchpads */ &((Keychord){2, {{MODKEY, XK_s}, {0, XK_Return}}, togglescratch, {.ui = 0 } }), /* Toggle scratch terminal */ &((Keychord){2, {{MODKEY, XK_s}, {0, XK_b}}, togglescratch, {.ui = 1 } }), /* Toggle system monitor scratchpad */ - &((Keychord){2, {{MODKEY, XK_s}, {0, XK_p}}, togglescratch, {.ui = 2 } }), /* Toggle audio mixer scratchpad */ - &((Keychord){2, {{MODKEY, XK_s}, {0, XK_f}}, togglescratch, {.ui = 3 } }), /* Toggle flix-cli scratchpad */ - &((Keychord){2, {{MODKEY, XK_s}, {0, XK_a}}, togglescratch, {.ui = 4 } }), /* Toggle ani-cli scratchpad */ - &((Keychord){2, {{MODKEY, XK_s}, {0, XK_y}}, togglescratch, {.ui = 5 } }), /* Toggle ytfzf scratchpad */ - &((Keychord){2, {{MODKEY, XK_s}, {0, XK_n}}, togglescratch, {.ui = 6 } }), /* Toggle ytfzf (music) scratchpad */ - &((Keychord){2, {{MODKEY, XK_s}, {0, XK_m}}, togglescratch, {.ui = 7 } }), /* Toggle cmus scratchpad */ - &((Keychord){2, {{MODKEY, XK_s}, {0, XK_v}}, togglescratch, {.ui = 8 } }), /* Toggle vifm scratchpad */ - &((Keychord){2, {{MODKEY, XK_s}, {0, XK_r}}, togglescratch, {.ui = 9 } }), /* Toggle newsboat scratchpad */ - &((Keychord){2, {{MODKEY, XK_s}, {0, XK_k}}, togglescratch, {.ui = 10 } }), /* Toggle Bitwarden scratchpad */ - &((Keychord){2, {{MODKEY, XK_s}, {0, XK_c}}, togglescratch, {.ui = 11 } }), /* Toggle Qalculate scratchpad */ - &((Keychord){2, {{MODKEY, XK_s}, {0, XK_d}}, togglescratch, {.ui = 12 } }), /* Toggle lxrandr scratchpad */ + &((Keychord){2, {{MODKEY, XK_s}, {0, XK_p}}, togglescratch, {.ui = 2 } }), /* Toggle audio mixer scratchpad */ + &((Keychord){2, {{MODKEY, XK_s}, {0, XK_f}}, togglescratch, {.ui = 3 } }), /* Toggle flix-cli scratchpad */ + &((Keychord){2, {{MODKEY, XK_s}, {0, XK_a}}, togglescratch, {.ui = 4 } }), /* Toggle ani-cli scratchpad */ + &((Keychord){2, {{MODKEY, XK_s}, {0, XK_y}}, togglescratch, {.ui = 5 } }), /* Toggle ytfzf scratchpad */ + &((Keychord){2, {{MODKEY, XK_s}, {0, XK_n}}, togglescratch, {.ui = 6 } }), /* Toggle ytfzf (music) scratchpad */ + &((Keychord){2, {{MODKEY, XK_s}, {0, XK_m}}, togglescratch, {.ui = 7 } }), /* Toggle cmus scratchpad */ + &((Keychord){2, {{MODKEY, XK_s}, {0, XK_v}}, togglescratch, {.ui = 8 } }), /* Toggle vifm scratchpad */ + &((Keychord){2, {{MODKEY, XK_s}, {0, XK_r}}, togglescratch, {.ui = 9 } }), /* Toggle newsboat scratchpad */ + &((Keychord){2, {{MODKEY, XK_s}, {0, XK_k}}, togglescratch, {.ui = 10 } }), /* Toggle Bitwarden scratchpad */ + &((Keychord){2, {{MODKEY, XK_s}, {0, XK_c}}, togglescratch, {.ui = 11 } }), /* Toggle Qalculate scratchpad */ + &((Keychord){2, {{MODKEY, XK_s}, {0, XK_d}}, togglescratch, {.ui = 12 } }), /* Toggle lxrandr scratchpad */ /* Session Management */ &((Keychord){1, {{MODKEY|ControlMask|ShiftMask, XK_q}}, quit, {0} }), @@ -370,21 +370,31 @@ static const int scrollsensetivity = 30; /* 1 means resize window by 1 pixel for /* Resizemousescroll direction argument list */ static const int scrollargs[][2] = { /* width change height change */ - { +scrollsensetivity, 0 }, - { -scrollsensetivity, 0 }, - { 0, +scrollsensetivity }, - { 0, -scrollsensetivity }, + { +scrollsensetivity, 0 }, + { -scrollsensetivity, 0 }, + { 0, +scrollsensetivity }, + { 0, -scrollsensetivity }, }; /* Mouse Bindings */ /* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */ static const Button buttons[] = { - /* click event mask button function argument */ + /* click event mask button function argument */ { ClkLtSymbol, 0, Button1, setlayout, {0} }, { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} }, { ClkWinTitle, 0, Button2, zoom, {0} }, { ClkStatusText, 0, Button2, spawn, {.v = termcmd } }, - { ClkClientWin, MODKEY, Button1, movemouse, {0} }, + /* placemouse options, choose which feels more natural: + * 0 - tiled position is relative to mouse cursor + * 1 - tiled postiion is relative to window center + * 2 - mouse pointer warps to window center + * + * The moveorplace uses movemouse or placemouse depending on the floating state + * of the selected client. Set up individual keybindings for the two if you want + * to control these separately (i.e. to retain the feature to move a tiled window + * into a floating position). + */ + { ClkClientWin, MODKEY, Button1, moveorplace, {.i = 1} }, { ClkClientWin, MODKEY, Button2, togglefloating, {0} }, { ClkClientWin, MODKEY, Button3, resizemouse, {0} }, { ClkClientWin, MODKEY, Button4, resizemousescroll, {.v = &scrollargs[0]} }, @@ -396,5 +406,3 @@ static const Button buttons[] = { { ClkTagBar, MODKEY, Button1, tag, {0} }, { ClkTagBar, MODKEY, Button3, toggletag, {0} }, }; - - diff --git a/source/dwm/dwm.c b/source/dwm/dwm.c index 547e96323..d75a38baa 100644 --- a/source/dwm/dwm.c +++ b/source/dwm/dwm.c @@ -51,6 +51,8 @@ #define CLEANMASK(mask) (mask & ~(numlockmask|LockMask) & (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask)) #define INTERSECT(x,y,w,h,m) (MAX(0, MIN((x)+(w),(m)->wx+(m)->ww) - MAX((x),(m)->wx)) \ * MAX(0, MIN((y)+(h),(m)->wy+(m)->wh) - MAX((y),(m)->wy))) +#define INTERSECTC(x,y,w,h,z) (MAX(0, MIN((x)+(w),(z)->x+(z)->w) - MAX((x),(z)->x)) \ + * MAX(0, MIN((y)+(h),(z)->y+(z)->h) - MAX((y),(z)->y))) #define ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags]) || C->issticky) #define LENGTH(X) (sizeof X / sizeof X[0]) #define MOUSEMASK (BUTTONMASK|PointerMotionMask) @@ -104,7 +106,7 @@ struct Client { int basew, baseh, incw, inch, maxw, maxh, minw, minh, hintsvalid; int bw, oldbw; unsigned int tags; - int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen, issticky; + int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen, issticky, beingmoved; unsigned int icw, ich; Picture icon; Client *next; Client *snext; @@ -224,13 +226,16 @@ static void fibonacci (Monitor *m, int s); static void keyrelease(XEvent *e); static void motionnotify(XEvent *e); static void movemouse(const Arg *arg); +static void moveorplace(const Arg *arg); static void movestack(const Arg *arg); static unsigned int nexttag(void); static Client *nexttiled(Client *c); +static void placemouse(const Arg *arg); static void pop(Client *c); static unsigned int prevtag(void); static void propertynotify(XEvent *e); static void quit(const Arg *arg); +static Client *recttoclient(int x, int y, int w, int h); static Monitor *recttomon(int x, int y, int w, int h); static void resize(Client *c, int x, int y, int w, int h, int interact); static void resizeclient(Client *c, int x, int y, int w, int h); @@ -1610,6 +1615,13 @@ void movemouse(const Arg *arg) { } } +void moveorplace(const Arg *arg) { + if ((!selmon->lt[selmon->sellt]->arrange || (selmon->sel && selmon->sel->isfloating))) + movemouse(arg); + else + placemouse(arg); +} + unsigned int nexttag(void) { unsigned int seltag = selmon->tagset[selmon->seltags]; return seltag == (1 << (LENGTH(tags) - 1)) ? 1 : seltag << 1; @@ -1669,6 +1681,137 @@ Client * nexttiled(Client *c) { return c; } +void placemouse(const Arg *arg) { + int x, y, px, py, ocx, ocy, nx = -9999, ny = -9999, freemove = 0; + Client *c, *r = NULL, *at, *prevr; + Monitor *m; + XEvent ev; + XWindowAttributes wa; + Time lasttime = 0; + int attachmode, prevattachmode; + attachmode = prevattachmode = -1; + + if (!(c = selmon->sel) || !c->mon->lt[c->mon->sellt]->arrange) /* no support for placemouse when floating layout is used */ + return; + if (c->isfullscreen) /* no support placing fullscreen windows by mouse */ + return; + restack(selmon); + prevr = c; + if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, + None, cursor[CurMove]->cursor, CurrentTime) != GrabSuccess) + return; + + c->isfloating = 0; + c->beingmoved = 1; + + XGetWindowAttributes(dpy, c->win, &wa); + ocx = wa.x; + ocy = wa.y; + + if (arg->i == 2) // warp cursor to client center + XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, WIDTH(c) / 2, HEIGHT(c) / 2); + + if (!getrootptr(&x, &y)) + return; + + do { + XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev); + switch (ev.type) { + case ConfigureRequest: + case Expose: + case MapRequest: + handler[ev.type](&ev); + break; + case MotionNotify: + if ((ev.xmotion.time - lasttime) <= (1000 / 60)) + continue; + lasttime = ev.xmotion.time; + + nx = ocx + (ev.xmotion.x - x); + ny = ocy + (ev.xmotion.y - y); + + if (!freemove && (abs(nx - ocx) > snap || abs(ny - ocy) > snap)) + freemove = 1; + + if (freemove) + XMoveWindow(dpy, c->win, nx, ny); + + if ((m = recttomon(ev.xmotion.x, ev.xmotion.y, 1, 1)) && m != selmon) + selmon = m; + + if (arg->i == 1) { // tiled position is relative to the client window center point + px = nx + wa.width / 2; + py = ny + wa.height / 2; + } else { // tiled position is relative to the mouse cursor + px = ev.xmotion.x; + py = ev.xmotion.y; + } + + r = recttoclient(px, py, 1, 1); + + if (!r || r == c) + break; + + attachmode = 0; // below + if (((float)(r->y + r->h - py) / r->h) > ((float)(r->x + r->w - px) / r->w)) { + if (abs(r->y - py) < r->h / 2) + attachmode = 1; // above + } else if (abs(r->x - px) < r->w / 2) + attachmode = 1; // above + + if ((r && r != prevr) || (attachmode != prevattachmode)) { + detachstack(c); + detach(c); + if (c->mon != r->mon) { + arrangemon(c->mon); + c->tags = r->mon->tagset[r->mon->seltags]; + } + + c->mon = r->mon; + r->mon->sel = r; + + if (attachmode) { + if (r == r->mon->clients) + attach(c); + else { + for (at = r->mon->clients; at->next != r; at = at->next); + c->next = at->next; + at->next = c; + } + } else { + c->next = r->next; + r->next = c; + } + + attachstack(c); + arrangemon(r->mon); + prevr = r; + prevattachmode = attachmode; + } + break; + } + } while (ev.type != ButtonRelease); + XUngrabPointer(dpy, CurrentTime); + + if ((m = recttomon(ev.xmotion.x, ev.xmotion.y, 1, 1)) && m != c->mon) { + detach(c); + detachstack(c); + arrangemon(c->mon); + c->mon = m; + c->tags = m->tagset[m->seltags]; + attach(c); + attachstack(c); + selmon = m; + } + + focus(c); + c->beingmoved = 0; + + if (nx != -9999) + resize(c, nx, ny, c->w, c->h, 0); + arrangemon(c->mon); +} + void pop(Client *c) { int i; for (i = 0; !(selmon->tagset[selmon->seltags] & 1 << i); i++); @@ -1731,7 +1874,7 @@ void quit(const Arg *arg) { running = 0; } -Monitor *recttomon(int x, int y, int w, int h) { +Monitor* recttomon(int x, int y, int w, int h) { Monitor *m, *r = selmon; int a, area = 0; @@ -1743,6 +1886,19 @@ Monitor *recttomon(int x, int y, int w, int h) { return r; } +Client* recttoclient(int x, int y, int w, int h) { + Client *c, *r = NULL; + int a, area = 0; + + for (c = nexttiled(selmon->clients); c; c = nexttiled(c->next)) { + if ((a = INTERSECTC(x, y, w, h, c)) > area) { + area = a; + r = c; + } + } + return r; +} + void resize(Client *c, int x, int y, int w, int h, int interact) { if (applysizehints(c, &x, &y, &w, &h, interact)) resizeclient(c, x, y, w, h); @@ -1756,6 +1912,9 @@ void resizeclient(Client *c, int x, int y, int w, int h) { c->oldw = c->w; c->w = wc.width = w; c->oldh = c->h; c->h = wc.height = h; + if (c->beingmoved) + return; + wc.border_width = c->bw; XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc); diff --git a/source/dwm/patches/dwm-placemouse-6.2.diff b/source/dwm/patches/dwm-placemouse-6.2.diff new file mode 100644 index 000000000..cb109f124 --- /dev/null +++ b/source/dwm/patches/dwm-placemouse-6.2.diff @@ -0,0 +1,259 @@ +From ca26e9e8533da2657fcbb56a407eb5a6d2735719 Mon Sep 17 00:00:00 2001 +From: Bakkeby +Date: Fri, 28 Jun 2024 10:08:07 +0200 +Subject: [PATCH] placemouse patch + +--- + config.def.h | 12 +++- + dwm.c | 166 +++++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 177 insertions(+), 1 deletion(-) + +diff --git a/config.def.h b/config.def.h +index 1c0b587..86f878a 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -104,7 +104,17 @@ static Button buttons[] = { + { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} }, + { ClkWinTitle, 0, Button2, zoom, {0} }, + { ClkStatusText, 0, Button2, spawn, {.v = termcmd } }, +- { ClkClientWin, MODKEY, Button1, movemouse, {0} }, ++ /* placemouse options, choose which feels more natural: ++ * 0 - tiled position is relative to mouse cursor ++ * 1 - tiled postiion is relative to window center ++ * 2 - mouse pointer warps to window center ++ * ++ * The moveorplace uses movemouse or placemouse depending on the floating state ++ * of the selected client. Set up individual keybindings for the two if you want ++ * to control these separately (i.e. to retain the feature to move a tiled window ++ * into a floating position). ++ */ ++ { ClkClientWin, MODKEY, Button1, moveorplace, {.i = 1} }, + { ClkClientWin, MODKEY, Button2, togglefloating, {0} }, + { ClkClientWin, MODKEY, Button3, resizemouse, {0} }, + { ClkTagBar, 0, Button1, view, {0} }, +diff --git a/dwm.c b/dwm.c +index 4465af1..8a0ae73 100644 +--- a/dwm.c ++++ b/dwm.c +@@ -49,6 +49,8 @@ + #define CLEANMASK(mask) (mask & ~(numlockmask|LockMask) & (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask)) + #define INTERSECT(x,y,w,h,m) (MAX(0, MIN((x)+(w),(m)->wx+(m)->ww) - MAX((x),(m)->wx)) \ + * MAX(0, MIN((y)+(h),(m)->wy+(m)->wh) - MAX((y),(m)->wy))) ++#define INTERSECTC(x,y,w,h,z) (MAX(0, MIN((x)+(w),(z)->x+(z)->w) - MAX((x),(z)->x)) \ ++ * MAX(0, MIN((y)+(h),(z)->y+(z)->h) - MAX((y),(z)->y))) + #define ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags])) + #define LENGTH(X) (sizeof X / sizeof X[0]) + #define MOUSEMASK (BUTTONMASK|PointerMotionMask) +@@ -93,6 +95,7 @@ struct Client { + int bw, oldbw; + unsigned int tags; + int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen; ++ int beingmoved; + Client *next; + Client *snext; + Monitor *mon; +@@ -183,10 +186,13 @@ static void maprequest(XEvent *e); + static void monocle(Monitor *m); + static void motionnotify(XEvent *e); + static void movemouse(const Arg *arg); ++static void moveorplace(const Arg *arg); + static Client *nexttiled(Client *c); ++static void placemouse(const Arg *arg); + static void pop(Client *); + static void propertynotify(XEvent *e); + static void quit(const Arg *arg); ++static Client *recttoclient(int x, int y, int w, int h); + static Monitor *recttomon(int x, int y, int w, int h); + static void resize(Client *c, int x, int y, int w, int h, int interact); + static void resizeclient(Client *c, int x, int y, int w, int h); +@@ -1132,6 +1138,14 @@ motionnotify(XEvent *e) + mon = m; + } + ++void ++moveorplace(const Arg *arg) { ++ if ((!selmon->lt[selmon->sellt]->arrange || (selmon->sel && selmon->sel->isfloating))) ++ movemouse(arg); ++ else ++ placemouse(arg); ++} ++ + void + movemouse(const Arg *arg) + { +@@ -1199,6 +1213,139 @@ nexttiled(Client *c) + return c; + } + ++void ++placemouse(const Arg *arg) ++{ ++ int x, y, px, py, ocx, ocy, nx = -9999, ny = -9999, freemove = 0; ++ Client *c, *r = NULL, *at, *prevr; ++ Monitor *m; ++ XEvent ev; ++ XWindowAttributes wa; ++ Time lasttime = 0; ++ int attachmode, prevattachmode; ++ attachmode = prevattachmode = -1; ++ ++ if (!(c = selmon->sel) || !c->mon->lt[c->mon->sellt]->arrange) /* no support for placemouse when floating layout is used */ ++ return; ++ if (c->isfullscreen) /* no support placing fullscreen windows by mouse */ ++ return; ++ restack(selmon); ++ prevr = c; ++ if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, ++ None, cursor[CurMove]->cursor, CurrentTime) != GrabSuccess) ++ return; ++ ++ c->isfloating = 0; ++ c->beingmoved = 1; ++ ++ XGetWindowAttributes(dpy, c->win, &wa); ++ ocx = wa.x; ++ ocy = wa.y; ++ ++ if (arg->i == 2) // warp cursor to client center ++ XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, WIDTH(c) / 2, HEIGHT(c) / 2); ++ ++ if (!getrootptr(&x, &y)) ++ return; ++ ++ do { ++ XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev); ++ switch (ev.type) { ++ case ConfigureRequest: ++ case Expose: ++ case MapRequest: ++ handler[ev.type](&ev); ++ break; ++ case MotionNotify: ++ if ((ev.xmotion.time - lasttime) <= (1000 / 60)) ++ continue; ++ lasttime = ev.xmotion.time; ++ ++ nx = ocx + (ev.xmotion.x - x); ++ ny = ocy + (ev.xmotion.y - y); ++ ++ if (!freemove && (abs(nx - ocx) > snap || abs(ny - ocy) > snap)) ++ freemove = 1; ++ ++ if (freemove) ++ XMoveWindow(dpy, c->win, nx, ny); ++ ++ if ((m = recttomon(ev.xmotion.x, ev.xmotion.y, 1, 1)) && m != selmon) ++ selmon = m; ++ ++ if (arg->i == 1) { // tiled position is relative to the client window center point ++ px = nx + wa.width / 2; ++ py = ny + wa.height / 2; ++ } else { // tiled position is relative to the mouse cursor ++ px = ev.xmotion.x; ++ py = ev.xmotion.y; ++ } ++ ++ r = recttoclient(px, py, 1, 1); ++ ++ if (!r || r == c) ++ break; ++ ++ attachmode = 0; // below ++ if (((float)(r->y + r->h - py) / r->h) > ((float)(r->x + r->w - px) / r->w)) { ++ if (abs(r->y - py) < r->h / 2) ++ attachmode = 1; // above ++ } else if (abs(r->x - px) < r->w / 2) ++ attachmode = 1; // above ++ ++ if ((r && r != prevr) || (attachmode != prevattachmode)) { ++ detachstack(c); ++ detach(c); ++ if (c->mon != r->mon) { ++ arrangemon(c->mon); ++ c->tags = r->mon->tagset[r->mon->seltags]; ++ } ++ ++ c->mon = r->mon; ++ r->mon->sel = r; ++ ++ if (attachmode) { ++ if (r == r->mon->clients) ++ attach(c); ++ else { ++ for (at = r->mon->clients; at->next != r; at = at->next); ++ c->next = at->next; ++ at->next = c; ++ } ++ } else { ++ c->next = r->next; ++ r->next = c; ++ } ++ ++ attachstack(c); ++ arrangemon(r->mon); ++ prevr = r; ++ prevattachmode = attachmode; ++ } ++ break; ++ } ++ } while (ev.type != ButtonRelease); ++ XUngrabPointer(dpy, CurrentTime); ++ ++ if ((m = recttomon(ev.xmotion.x, ev.xmotion.y, 1, 1)) && m != c->mon) { ++ detach(c); ++ detachstack(c); ++ arrangemon(c->mon); ++ c->mon = m; ++ c->tags = m->tagset[m->seltags]; ++ attach(c); ++ attachstack(c); ++ selmon = m; ++ } ++ ++ focus(c); ++ c->beingmoved = 0; ++ ++ if (nx != -9999) ++ resize(c, nx, ny, c->w, c->h, 0); ++ arrangemon(c->mon); ++} ++ + void + pop(Client *c) + { +@@ -1251,6 +1398,21 @@ quit(const Arg *arg) + running = 0; + } + ++Client * ++recttoclient(int x, int y, int w, int h) ++{ ++ Client *c, *r = NULL; ++ int a, area = 0; ++ ++ for (c = nexttiled(selmon->clients); c; c = nexttiled(c->next)) { ++ if ((a = INTERSECTC(x, y, w, h, c)) > area) { ++ area = a; ++ r = c; ++ } ++ } ++ return r; ++} ++ + Monitor * + recttomon(int x, int y, int w, int h) + { +@@ -1281,6 +1443,10 @@ resizeclient(Client *c, int x, int y, int w, int h) + c->oldy = c->y; c->y = wc.y = y; + c->oldw = c->w; c->w = wc.width = w; + c->oldh = c->h; c->h = wc.height = h; ++ ++ if (c->beingmoved) ++ return; ++ + wc.border_width = c->bw; + XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc); + configure(c); +-- +2.45.2 + diff --git a/source/dwm/scripts/autostart b/source/dwm/scripts/autostart index e4833253d..2d979de34 100755 --- a/source/dwm/scripts/autostart +++ b/source/dwm/scripts/autostart @@ -5,7 +5,10 @@ ## / /_/ / / / /_/ / ,< / __/ Clay Gomera (Drake) ## ## /_____/_/ \__,_/_/|_|\___/ My custom dwm build ## +# activate neccesary env variables for ssh-agent and other stuff dbus-update-activation-environment DISPLAY XAUTHORITY & + +# autostart programs, use pidof || program, to prevent relaunching stuff if dwm is restarted pidof pipewire || pipewire & pidof polkit-gnome-authentication-agent-1 || /usr/libexec/polkit-gnome-authentication-agent-1 & pidof dwmblocks || dwmblocks & @@ -13,28 +16,45 @@ pidof unclutter || unclutter --hide-on-touch & pidof dunst || dunst --config $HOME/.config/dunst/dunstrc & pidof picom || picom & pidof xss-lock || xss-lock $HOME/.config/suckless/dwm/scripts/lock & +pidof emacs || /usr/bin/emacs --daemon & -gsettings set org.gnome.desktop.interface cursor-theme 'Simp1e-Gruvbox-Dark' -gsettings set org.gnome.desktop.interface cursor-size 16 -gsettings set org.gnome.desktop.interface icon-theme 'Papirus-Dark' -gsettings set org.gnome.desktop.interface gtk-theme 'Gruvbox-Dark' -gsettings set org.gnome.desktop.interface color-scheme 'prefer-dark' -gsettings set org.gnome.desktop.interface font-name 'Inter 10' -gsettings set org.gnome.desktop.interface document-font-name 'Liberation Sans 10' -gsettings set org.gnome.desktop.interface monospace-font-name 'Mononoki Nerd Font 10' -gsettings set org.gnome.desktop.interface font-antialiasing 'rgba' -gsettings set org.gnome.desktop.interface font-hinting 'full' - -sleep 3 +# set theming and font thingy +gsettings set org.gnome.desktop.interface cursor-theme 'Simp1e-Gruvbox-Dark' & +gsettings set org.gnome.desktop.interface cursor-size 16 & +gsettings set org.gnome.desktop.interface icon-theme 'Papirus-Dark' & +gsettings set org.gnome.desktop.interface gtk-theme 'Gruvbox-Dark' & +gsettings set org.gnome.desktop.interface color-scheme 'prefer-dark' & +gsettings set org.gnome.desktop.interface font-name 'Inter 10' & +gsettings set org.gnome.desktop.interface document-font-name 'Liberation Sans 10' & +gsettings set org.gnome.desktop.interface monospace-font-name 'Mononoki Nerd Font 10' & +gsettings set org.gnome.desktop.interface font-antialiasing 'rgba' & +gsettings set org.gnome.desktop.interface font-hinting 'full' & +# grab monitor status (varies with the machine) +### T480 monitors monitor1=$(cat /sys/class/drm/card0-DP-1/status) monitor2=$(cat /sys/class/drm/card0-HDMI-A-2/status) +# if monitors are connected, then use xrandr to set desired settings if [ "$monitor1" = "connected" ] && [ "$monitor2" = "connected" ]; then xrandr --output eDP1 --mode 1920x1080 --pos 0x0 --rotate normal \ --output DP1 --primary --mode 1920x1080 --rate 100.00 --pos 1924x0 --rotate normal \ - --output HDMI2 --mode 1280x1024 --rate 75.00 --pos 3844x0 --rotate normal + --output HDMI2 --mode 1280x1024 --rate 75.00 --pos 3844x0 --rotate normal & +elif [ "$monitor1" = "connected" ]; then + xrandr --output eDP1 --primary --auto \ + --output DP1 --auto --scale-from 1920x1080 --same-as eDP1 & +elif [ "$monitor2" = "connected" ]; then + xrandr --output eDP1 --primary --auto \ + --output HDMI2 --auto --scale-from 1920x1080 --same-as eDP1 & +else + xrandr --output eDP1 --primary --auto \ + --output DP1 --off \ + --output HDMI2 --off & fi + +# set wallpaper sh "$HOME"/.fehbg & + +# bind gnome secrets component to currently running gnome-keyring instance launched with PAM on login (this unlocks the keyring) gnome-keyring-daemon --start --components=secrets & diff --git a/source/dwmblocks/scripts/block_wifi b/source/dwmblocks/scripts/block_wifi index 75b0c0231..1f3d51cc5 100755 --- a/source/dwmblocks/scripts/block_wifi +++ b/source/dwmblocks/scripts/block_wifi @@ -32,7 +32,7 @@ constate=$(nmcli dev | grep wifi | sed 's/ \{2,\}/|/g' | cut -d '|' -f3 | head - currentwfi=$(nmcli dev | grep wifi | sed 's/ \{2,\}/|/g' | cut -d '|' -f4 | head -1) # Check Ethernet connection -ethernet_state=$(nmcli dev | grep ethernet | awk '{print $3}') +ethernet_state=$(nmcli dev | grep ethernet | awk '{print $3}' | head -n 1) if [ "$ethernet_state" = "connected" ]; then echo " 󰈀 Ethernet " @@ -46,7 +46,7 @@ elif [ "$constate" = "connected" ]; then # if it's connected "3") icon=" 󰤥 " ;; "4") icon=" 󰤨 " ;; esac - echo "$icon$currentwfi" + echo "$icon$currentwfi " else echo " 󰤮 " # just in case if nmcli isn't available or something weird is happening fi