Browse Source

Initial Commit

main
Yiğit Çolakoğlu 4 years ago
commit
0877ecc694
122 changed files with 16384 additions and 0 deletions
  1. +0
    -0
      arch-setup.sh
  2. +7
    -0
      gtk/gtk-3.0/bookmarks
  3. +16
    -0
      gtk/gtk-3.0/settings.ini
  4. +2
    -0
      gtk/gtk-4.0/settings.ini
  5. +35
    -0
      install.sh
  6. +323
    -0
      misc/dunst/dunstrc
  7. +9
    -0
      misc/dunst/not.svg
  8. BIN
      misc/dunst/notif.png
  9. +149
    -0
      misc/rofi/config.rasi
  10. +10
    -0
      misc/rofi/music_menu
  11. +109
    -0
      misc/rofi/sidebar-mod.rasi
  12. +149
    -0
      misc/rofi/themes/denvit.rasi
  13. +44
    -0
      misc/rofi/themes/dmenu.rasi
  14. +4
    -0
      misc/zathura/a
  15. +64
    -0
      misc/zathura/zathurarc
  16. +163
    -0
      scripts/autotrim
  17. +89
    -0
      scripts/bluetooth_battery.py
  18. +239
    -0
      scripts/convertToHtmlMultipart
  19. +80
    -0
      scripts/dmenu-killall
  20. +61
    -0
      scripts/dmenu-logout
  21. +23
    -0
      scripts/dunst_toggle.sh
  22. +26
    -0
      scripts/gen_tracking_url
  23. +15
    -0
      scripts/mail_tag.sh
  24. +8
    -0
      scripts/mails.sh
  25. +4
    -0
      scripts/newmail.sh
  26. +28
    -0
      scripts/nm_sendmail.sh
  27. +12
    -0
      scripts/status-bar/arch
  28. +17
    -0
      scripts/status-bar/arch-block
  29. +37
    -0
      scripts/status-bar/battery
  30. +49
    -0
      scripts/status-bar/battery-blocks
  31. +14
    -0
      scripts/status-bar/capslock
  32. +12
    -0
      scripts/status-bar/clima
  33. +27
    -0
      scripts/status-bar/clima-icon
  34. +6
    -0
      scripts/status-bar/cpu-temp
  35. +9
    -0
      scripts/status-bar/fecha
  36. +11
    -0
      scripts/status-bar/fecha-block
  37. +10
    -0
      scripts/status-bar/listener
  38. +9
    -0
      scripts/status-bar/red
  39. +14
    -0
      scripts/status-bar/red-texto
  40. +3
    -0
      scripts/status-bar/sep1
  41. +14
    -0
      scripts/status-bar/spotify-bar
  42. +17
    -0
      scripts/status-bar/spotify-block
  43. +122
    -0
      scripts/status-bar/spotify_status.py
  44. +24
    -0
      scripts/status-bar/volume
  45. +29
    -0
      scripts/status-bar/volume-block
  46. +6
    -0
      scripts/toggle_monitor.sh
  47. +9
    -0
      scripts/toggle_touchpad.sh
  48. +3
    -0
      scripts/update_events.sh
  49. +28
    -0
      scripts/welcome.sh
  50. +245
    -0
      suckless/dwm/,
  51. +37
    -0
      suckless/dwm/LICENSE
  52. +51
    -0
      suckless/dwm/Makefile
  53. +50
    -0
      suckless/dwm/Makefile.bak
  54. +32
    -0
      suckless/dwm/README.es.org
  55. +35
    -0
      suckless/dwm/README.org
  56. +262
    -0
      suckless/dwm/config.h
  57. +38
    -0
      suckless/dwm/config.mk
  58. +438
    -0
      suckless/dwm/drw.c
  59. +57
    -0
      suckless/dwm/drw.h
  60. +727
    -0
      suckless/dwm/dwm-systray-20200914-61bb8b2.diff
  61. +185
    -0
      suckless/dwm/dwm.1
  62. +2768
    -0
      suckless/dwm/dwm.c
  63. BIN
      suckless/dwm/dwm.png
  64. +28
    -0
      suckless/dwm/dwm_config_pulseaudio.h
  65. +66
    -0
      suckless/dwm/fibonacci.c
  66. +27
    -0
      suckless/dwm/layouts.c
  67. +49
    -0
      suckless/dwm/movestack.c
  68. +65
    -0
      suckless/dwm/patches/dwm-6.0-winview.diff
  69. +53
    -0
      suckless/dwm/patches/dwm-actualfullscreen-20191112-cb3f58a.diff
  70. +67
    -0
      suckless/dwm/patches/dwm-alttagsdecoration-2020010304-cb3f58a.diff
  71. +12
    -0
      suckless/dwm/patches/dwm-alwayscenter-20200625-f04cac6.diff
  72. +124
    -0
      suckless/dwm/patches/dwm-barpadding-20200720-bb2e722.diff
  73. +142
    -0
      suckless/dwm/patches/dwm-centeredmaster-6.1.diff
  74. +117
    -0
      suckless/dwm/patches/dwm-cfacts-20200913-61bb8b2.diff
  75. +180
    -0
      suckless/dwm/patches/dwm-cfacts_centeredmaster-6.2.diff
  76. +68
    -0
      suckless/dwm/patches/dwm-colorbar-6.2.diff
  77. +93
    -0
      suckless/dwm/patches/dwm-cyclelayouts-20180524-6.2.diff
  78. +90
    -0
      suckless/dwm/patches/dwm-deck-6.0.diff
  79. +340
    -0
      suckless/dwm/patches/dwm-dwmblocks-6.2.diff
  80. +161
    -0
      suckless/dwm/patches/dwm-ewmhtags-6.2.diff
  81. +85
    -0
      suckless/dwm/patches/dwm-fibonacci-5.8.2.diff
  82. +27
    -0
      suckless/dwm/patches/dwm-fixborders-6.2.diff
  83. +73
    -0
      suckless/dwm/patches/dwm-gridmode-20170909-ceac8c9.diff
  84. +108
    -0
      suckless/dwm/patches/dwm-inplacerotate-6.2.diff
  85. +69
    -0
      suckless/dwm/patches/dwm-leftlayout-20180524-c8e9479.diff
  86. +73
    -0
      suckless/dwm/patches/dwm-movestack-6.1.diff
  87. +65
    -0
      suckless/dwm/patches/dwm-netclientliststacking-6.2.diff
  88. +177
    -0
      suckless/dwm/patches/dwm-pertag-20170513-ceac8c9.diff
  89. +113
    -0
      suckless/dwm/patches/dwm-rmaster-6.1.diff
  90. +62
    -0
      suckless/dwm/patches/dwm-statuspadding-20150524-c8e9479.diff
  91. +47
    -0
      suckless/dwm/patches/dwm-switchcol-6.1.diff
  92. +727
    -0
      suckless/dwm/patches/dwm-systray-20200914-61bb8b2.diff
  93. +81
    -0
      suckless/dwm/patches/dwm-uselessgap-6.2.diff
  94. +19
    -0
      suckless/dwm/shiftview.c
  95. +42
    -0
      suckless/dwm/transient.c
  96. +35
    -0
      suckless/dwm/util.c
  97. +8
    -0
      suckless/dwm/util.h
  98. +3
    -0
      suckless/dwmblocks/.gitignore
  99. +32
    -0
      suckless/dwmblocks/GNUmakefile
  100. +7
    -0
      suckless/dwmblocks/LICENSE

+ 0
- 0
arch-setup.sh View File


+ 7
- 0
gtk/gtk-3.0/bookmarks View File

@ -0,0 +1,7 @@
smb://yigitcolakoglu.com;yigitcolakoglu@home.yigitcolakoglu.com/dockerstorage/ dockerstorage on home.yigitcolakoglu.com
file:///home/yigit/Projects Projects
file:///home/yigit/Downloads Downloads
file:///home/yigit/Nextcloud Nextcloud
file:///home/yigit/Pictures Pictures
file:///home/yigit/Documents/
file:///home/yigit/Pictures/

+ 16
- 0
gtk/gtk-3.0/settings.ini View File

@ -0,0 +1,16 @@
[Settings]
gtk-theme-name=Arc-Dark
gtk-icon-theme-name=Numix
gtk-font-name=Cantarell 11
gtk-cursor-theme-name=Adwaita
gtk-cursor-theme-size=0
gtk-toolbar-style=GTK_TOOLBAR_BOTH
gtk-toolbar-icon-size=GTK_ICON_SIZE_LARGE_TOOLBAR
gtk-button-images=1
gtk-menu-images=1
gtk-enable-event-sounds=1
gtk-enable-input-feedback-sounds=1
gtk-xft-antialias=1
gtk-xft-hinting=1
gtk-xft-hintstyle=hintfull
gtk-application-prefer-dark-theme=0

+ 2
- 0
gtk/gtk-4.0/settings.ini View File

@ -0,0 +1,2 @@
[Settings]
gtk-application-prefer-dark-theme=0

+ 35
- 0
install.sh View File

@ -0,0 +1,35 @@
#!/bin/bash
# Vim
ln -s ~/.dotfiles/vim/vimrc ~/.vimrc
ln -s ~/.dotfiles/vim/vim ~/.vim
# GTK
ln -s ~/.dotfiles/gtk/gtk-2.0 ~/.config/gtk-2.0
ln -s ~/.dotfiles/gtk/gtk-3.0 ~/.config/gtk-3.0
ln -s ~/.dotfiles/gtk/gtk-4.0 ~/.config/gtk-4.0
# Miscellaneous
ln -s ~/.dotfiles/misc/dunst ~/.config/dunst
ln -s ~/.dotfiles/misc/rofi ~/.config/rofi
ln -s ~/.dotfiles/misc/zathura ~/.config/zathura
# Scripts
ln -s ~/.dotfiles/scripts ~/.scripts
# Suckless
ln -s ~/.dotfiles/suckless ~/.config/suckless
# Tmux
ln -s ~/.dotfiles/tmux/tmux.conf ~/.tmux.conf
# Xorg
ln -s ~/.dotfiles/xorg/xinitrc ~/.xinitrc
ln -s ~/.dotfiles/xorg/xmodmap ~/.xmodmap
# Zsh
ln -s ~/.dotfiles/zsh/antibody ~/.config/antibody
ln -s ~/.dotfiles/zsh/zshrc ~/.zshrc
ln -s ~/.dotfiles/zsh/cmds ~/.cmds
ln -s ~/.dotfiles/zsh/aliases ~/.aliases

+ 323
- 0
misc/dunst/dunstrc View File

@ -0,0 +1,323 @@
[colors]
## gruvbox
# background = "#282828"
# foreground = "#fbf2c7"
# frame_color = "#282828"
# dracula
background = "#282a36"
foreground = "#f8f8f2"
frame_color = "#282a36"
[global]
frame_width = 0
#font = JetBrains Mono 10
font = Ubuntu 10
follow = none
# Allow a small subset of html markup:
# <b>bold</b>
# <i>italic</i>
# <s>strikethrough</s>
# <u>underline</u>
#
# For a complete reference see
# <http://developer.gnome.org/pango/stable/PangoMarkupFormat.html>.
# If markup is not allowed, those tags will be stripped out of the
# message.
markup = yes
stack_duplicates = true
# The format of the message. Possible variables are:
# %a appname
# %s summary
# %b body
# %i iconname (including its path)
# %I iconname (without its path)
# %p progress value if set ([ 0%] to [100%]) or nothing
# Markup is allowed
format = "<b>%a</b> \n %s %p\n%b"
# Sort messages by urgency.
sort = yes
# Show how many messages are currently hidden (because of geometry).
indicate_hidden = yes
# Alignment of message text.
# Possible values are "left", "center" and "right".
alignment = left
# The frequency with wich text that is longer than the notification
# window allows bounces back and forth.
# This option conflicts with "word_wrap".
# Set to 0 to disable.
bounce_freq = 5
# Show age of message if message is older than show_age_threshold
# seconds.
# Set to -1 to disable.
show_age_threshold = 60
# Split notifications into multiple lines if they don't fit into
# geometry.
word_wrap = yes
# Ignore newlines '\n' in notifications.
ignore_newline = no
# The geometry of the window:
# [{width}]x{height}[+/-{x}+/-{y}]
# The geometry of the message window.
# The height is measured in number of notifications everything else
# in pixels. If the width is omitted but the height is given
# ("-geometry x2"), the message window expands over the whole screen
# (dmenu-like). If width is 0, the window expands to the longest
# message displayed. A positive x is measured from the left, a
# negative from the right side of the screen. Y is measured from
# the top and down respectevly.
# The width can be negative. In this case the actual width is the
# screen width minus the width defined in within the geometry option.
geometry = "500x8-8-8"
# Show how many messages are currently hidden (because of geometry).
indicate_hidden = yes
# Shrink window if it's smaller than the width. Will be ignored if
# width is 0.
shrink = yes
# The transparency of the window. Range: [0; 100].
# This option will only work if a compositing windowmanager is
# present (e.g. xcompmgr, compiz, etc.).
transparency = 0
# Don't remove messages, if the user is idle (no mouse or keyboard input)
# for longer than idle_threshold seconds.
# Set to 0 to disable.
# default 120
idle_threshold = 120
# Which monitor should the notifications be displayed on.
monitor = 0
# Display notification on focused monitor. Possible modes are:
# mouse: follow mouse pointer
# keyboard: follow window with keyboard focus
# none: don't follow anything
#
# "keyboard" needs a windowmanager that exports the
# _NET_ACTIVE_WINDOW property.
# This should be the case for almost all modern windowmanagers.
#
# If this option is set to mouse or keyboard, the monitor option
# will be ignored.
# Should a notification popped up from history be sticky or timeout
# as if it would normally do.
sticky_history = yes
# Maximum amount of notifications kept in history
history_length = 20
# Display indicators for URLs (U) and actions (A).
show_indicators = yes
# The height of a single line. If the height is smaller than the
# font height, it will get raised to the font height.
# This adds empty space above and under the text.
line_height = 0
# Draw a line of "separator_height" pixel height between two
# notifications.
# Set to 0 to disable.
separator_height = 1
# Padding between text and separator.
# padding = 8
padding = 8
# Horizontal padding.
horizontal_padding = 10
# Define a color for the separator.
# possible values are:
# * auto: dunst tries to find a color fitting to the background;
# * foreground: use the same color as the foreground;
# * frame: use the same color as the frame;
# * anything else will be interpreted as a X color.
separator_color = auto
# Print a notification on startup.
# This is mainly for error detection, since dbus (re-)starts dunst
# automatically after a crash.
startup_notification = false
# dmenu path.
dmenu = /usr/bin/dmenu -p dunst:
# Browser for opening urls in context menu.
browser = firefox-developer-edition
# Align icons left/right/off
icon_position = left
# Paths to default icons.
icon_path = /usr/share/icons/Adwaita/16x16/status/:/usr/share/icons/Adwaita/16x16/devices/:/usr/share/icons/Papirus-Dark/16x16/devices/:/usr/share/icons/Papirus-Dark/16x16/status/
# Limit icons size.
max_icon_size=32
[shortcuts]
# Shortcuts are specified as [modifier+][modifier+]...key
# Available modifiers are "ctrl", "mod1" (the alt-key), "mod2",
# "mod3" and "mod4" (windows-key).
# Xev might be helpful to find names for keys.
# Close notification.
# close = mod1+space
# Close all notifications.
# close_all = ctrl+shift+space
close_all = ctrl+mod1+space
# Redisplay last message(s).
# On the US keyboard layout "grave" is normally above TAB and left
# of "1".
history = shift+mod4+h
# Context menu.
context = shift+mod4+space
[urgency_low]
# IMPORTANT: colors have to be defined in quotation marks.
# Otherwise the "#" and following would be interpreted as a comment.
background = "#313D4A"
foreground = "#F9FAF9"
frame_color = "#9DB788"
timeout = 5
[urgency_normal]
background = "#313D4A"
foreground = "#F9FAF9"
frame_color = "#2E2E2D"
timeout = 5
[urgency_critical]
background = "#313D4A"
foreground = "#F9FAF9"
frame_color = "#D62929"
timeout = 0
# Every section that isn't one of the above is interpreted as a rules to
# override settings for certain messages.
# Messages can be matched by "appname", "summary", "body", "icon", "category",
# "msg_urgency" and you can override the "timeout", "urgency", "foreground",
# "background", "new_icon" and "format".
# Shell-like globbing will get expanded.
#
# SCRIPTING
# You can specify a script that gets run when the rule matches by
# setting the "script" option.
# The script will be called as follows:
# script appname summary body icon urgency
# where urgency can be "LOW", "NORMAL" or "CRITICAL".
#
# NOTE: if you don't want a notification to be displayed, set the format
# to "".
# NOTE: It might be helpful to run dunst -print in a terminal in order
# to find fitting options for rules.
#[espeak]
# summary = "*"
# script = dunst_espeak.sh
#[script-test]
# summary = "*script*"
# script = dunst_test.sh
#[ignore]
# # This notification will not be displayed
# summary = "foobar"
# format = ""
#[signed_on]
# appname = Pidgin
# summary = "*signed on*"
# urgency = low
#
#[signed_off]
# appname = Pidgin
# summary = *signed off*
# urgency = low
#
#[says]
# appname = Pidgin
# summary = *says*
# urgency = critical
#
#[twitter]
# appname = Pidgin
# summary = *twitter.com*
# urgency = normal
#
#[Claws Mail]
# appname = claws-mail
# category = email.arrived
# urgency = normal
# background = "#2F899E"
# foreground = "#FFA247"
#
#[mute.sh]
# appname = mute
# category = mute.sound
# script = mute.sh
#
#[JDownloader]
# appname = JDownloader
# category = JD
# background = "#FFA247"
# foreground = "#FFFFFF"
#
#[newsbeuter]
# summary = *Feeds*
# background = "#A8EB41"
# foreground = "#FFFFFF"
#
[irc]
appname = weechat
timeout = 0
background = "#0033bb"
foreground = "#dddddd"
#
[weechat hl]
appname = weechat
category = weechat.HL
background = "#FF5C47"
foreground = "#FFFFFF"
#
[weechat pn]
appname = weechat
category = weechat.PM
background = "#D53B84"
foreground = "#FFFFFF"
#
#[CMUS]
# appname = CMUS
# category = cmus
# background = "#6C4AB7"
# foreground = "#FFE756"
#
#
# background = "#30AB70"
# foreground = "#F67245"
#
[Spotify]
appname = Spotify
frame_color = "#30AB70"
timeout = 5
# vim: ft=cfg

+ 9
- 0
misc/dunst/not.svg View File

@ -0,0 +1,9 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" version="1.1">
<defs>
<style id="current-color-scheme" type="text/css">
.ColorScheme-Text { color:#ffffff; } .ColorScheme-Highlight { color:#5294e2; }
</style>
</defs>
<path style="fill:currentColor" class="ColorScheme-Text" d="M 15.152346,5.6972621 C 12.939574,4.9495219 10.447072,5.8338262 9.2324219,7.9374962 l -2.25,3.8964848 L 4.25,12.566403 4,12.999996 l 1.7324219,1 8.6601561,5 1.732422,1 0.25,-0.433594 -0.732422,-2.732421 1.25,-2.164063 1,-1.732422 c 0.544507,-0.942959 0.731387,-1.983706 0.632813,-2.9863279 -0.151935,0.024132 -0.30464,0.048828 -0.462891,0.048828 -1.64501,0 -3,-1.3549899 -3,-3 0,-0.4361652 0.09915,-0.8486763 0.272585,-1.2218917 0,0 -0.180996,-0.080071 -0.182739,-0.080842 z M 8.0644531,16.499996 c 0,0.71396 0.3800169,1.374952 0.9980469,1.732422 0.61834,0.35531 1.380337,0.354677 1.998047,-0.002 z"/>
<circle style="fill:currentColor" class="ColorScheme-Highlight" cx="18.062" cy="6.999" r="2"/>
</svg>

BIN
misc/dunst/notif.png View File

Before After
Width: 1600  |  Height: 1600  |  Size: 21 KiB

+ 149
- 0
misc/rofi/config.rasi View File

@ -0,0 +1,149 @@
configuration {
modi: "window,run,ssh,drun";
/* width: 50;*/
lines: 15;
/* columns: 1;*/
font: "Cascadia Code 12";
/* bw: 1;*/
/* location: 0;*/
/* padding: 5;*/
/* yoffset: 0;*/
/* xoffset: 0;*/
/* fixed-num-lines: true;*/
/* show-icons: false;*/
/* terminal: "rofi-sensible-terminal";*/
/* ssh-client: "ssh";*/
/* ssh-command: "{terminal} -e {ssh-client} {host} [-p {port}]";*/
/* run-command: "{cmd}";*/
/* run-list-command: "";*/
/* run-shell-command: "{terminal} -e {cmd}";*/
/* window-command: "wmctrl -i -R {window}";*/
/* window-match-fields: "all";*/
/* icon-theme: ;*/
/* drun-match-fields: "name,generic,exec,categories";*/
/* drun-show-actions: false;*/
/* drun-display-format: "{name} [<span weight='light' size='small'><i>({generic})</i></span>]";*/
/* disable-history: false;*/
/* ignored-prefixes: "";*/
/* sort: false;*/
/* sorting-method: ;*/
/* case-sensitive: false;*/
/* cycle: true;*/
/* sidebar-mode: false;*/
/* eh: 1;*/
/* auto-select: false;*/
/* parse-hosts: false;*/
/* parse-known-hosts: true;*/
/* combi-modi: "window,run";*/
/* matching: "normal";*/
/* tokenize: true;*/
/* m: "-5";*/
/* line-margin: 2;*/
/* line-padding: 1;*/
/* filter: ;*/
/* separator-style: "dash";*/
/* hide-scrollbar: false;*/
/* fullscreen: false;*/
/* fake-transparency: false;*/
/* dpi: -1;*/
/* threads: 0;*/
/* scrollbar-width: 8;*/
/* scroll-method: 0;*/
/* fake-background: "screenshot";*/
/* window-format: "{w} {c} {t}";*/
/* click-to-exit: true;*/
/* show-match: true;*/
/* theme: ;*/
/* color-normal: ;*/
/* color-urgent: ;*/
/* color-active: ;*/
/* color-window: ;*/
/* max-history-size: 25;*/
/* combi-hide-mode-prefix: false;*/
/* matching-negate-char: '-' /* unsupported */;*/
/* cache-dir: ;*/
/* pid: "/run/user/1000/rofi.pid";*/
/* display-window: ;*/
/* display-windowcd: ;*/
/* display-run: ;*/
/* display-ssh: ;*/
/* display-drun: ;*/
/* display-combi: ;*/
/* display-keys: ;*/
/* kb-primary-paste: "Control+V,Shift+Insert";*/
/* kb-secondary-paste: "Control+v,Insert";*/
/* kb-clear-line: "Control+w";*/
/* kb-move-front: "Control+a";*/
/* kb-move-end: "Control+e";*/
/* kb-move-word-back: "Alt+b,Control+Left";*/
/* kb-move-word-forward: "Alt+f,Control+Right";*/
/* kb-move-char-back: "Left,Control+b";*/
/* kb-move-char-forward: "Right,Control+f";*/
/* kb-remove-word-back: "Control+Alt+h,Control+BackSpace";*/
/* kb-remove-word-forward: "Control+Alt+d";*/
/* kb-remove-char-forward: "Delete,Control+d";*/
/* kb-remove-char-back: "BackSpace,Shift+BackSpace,Control+h";*/
/* kb-remove-to-eol: "Control+k";*/
/* kb-remove-to-sol: "Control+u";*/
/* kb-accept-entry: "Control+j,Control+m,Return,KP_Enter";*/
/* kb-accept-custom: "Control+Return";*/
/* kb-accept-alt: "Shift+Return";*/
/* kb-delete-entry: "Shift+Delete";*/
/* kb-mode-next: "Shift+Right,Control+Tab";*/
/* kb-mode-previous: "Shift+Left,Control+ISO_Left_Tab";*/
/* kb-row-left: "Control+Page_Up";*/
/* kb-row-right: "Control+Page_Down";*/
/* kb-row-up: "Up,Control+p,ISO_Left_Tab";*/
/* kb-row-down: "Down,Control+n";*/
/* kb-row-tab: "Tab";*/
/* kb-page-prev: "Page_Up";*/
/* kb-page-next: "Page_Down";*/
/* kb-row-first: "Home,KP_Home";*/
/* kb-row-last: "End,KP_End";*/
/* kb-row-select: "Control+space";*/
/* kb-screenshot: "Alt+S";*/
/* kb-ellipsize: "Alt+period";*/
/* kb-toggle-case-sensitivity: "grave,dead_grave";*/
/* kb-toggle-sort: "Alt+grave";*/
/* kb-cancel: "Escape,Control+g,Control+bracketleft";*/
/* kb-custom-1: "Alt+1";*/
/* kb-custom-2: "Alt+2";*/
/* kb-custom-3: "Alt+3";*/
/* kb-custom-4: "Alt+4";*/
/* kb-custom-5: "Alt+5";*/
/* kb-custom-6: "Alt+6";*/
/* kb-custom-7: "Alt+7";*/
/* kb-custom-8: "Alt+8";*/
/* kb-custom-9: "Alt+9";*/
/* kb-custom-10: "Alt+0";*/
/* kb-custom-11: "Alt+exclam";*/
/* kb-custom-12: "Alt+at";*/
/* kb-custom-13: "Alt+numbersign";*/
/* kb-custom-14: "Alt+dollar";*/
/* kb-custom-15: "Alt+percent";*/
/* kb-custom-16: "Alt+dead_circumflex";*/
/* kb-custom-17: "Alt+ampersand";*/
/* kb-custom-18: "Alt+asterisk";*/
/* kb-custom-19: "Alt+parenleft";*/
/* kb-select-1: "Super+1";*/
/* kb-select-2: "Super+2";*/
/* kb-select-3: "Super+3";*/
/* kb-select-4: "Super+4";*/
/* kb-select-5: "Super+5";*/
/* kb-select-6: "Super+6";*/
/* kb-select-7: "Super+7";*/
/* kb-select-8: "Super+8";*/
/* kb-select-9: "Super+9";*/
/* kb-select-10: "Super+0";*/
/* ml-row-left: "ScrollLeft";*/
/* ml-row-right: "ScrollRight";*/
/* ml-row-up: "ScrollUp";*/
/* ml-row-down: "ScrollDown";*/
/* me-select-entry: "MousePrimary";*/
/* me-accept-entry: "MouseDPrimary";*/
/* me-accept-custom: "Control+MouseDPrimary";*/
}
@import "/home/yigit/.config/rofi/themes/dmenu.rasi"
/* vim:ft=css

+ 10
- 0
misc/rofi/music_menu View File

@ -0,0 +1,10 @@
action=$(echo '
' | rofi -dmenu -theme music_actions )
if [ $action = '' ]
then
playerctl previous &
elif [ $action = '' ]
then
playerctl next &
fi

+ 109
- 0
misc/rofi/sidebar-mod.rasi View File

@ -0,0 +1,109 @@
/**
* User: qball
* Copyright: Dave Davenport
*/
* {
text-color: #f4f2f0;
background-color: rgba(0,0,0,0);
dark: #2c2541;
// Black
black: #3d335c;
lightblack: #483c6c;
//
// Red
red: #cd5c5c;
lightred: #cc5533;
//
// Green
green: #86af80;
lightgreen: #88cc22;
//
// Yellow
yellow: #e8ae5b;
lightyellow: #ffa75d;
//
// Blue
blue: #6495ed;
lightblue: #87ceeb;
//
// Magenta
magenta: #deb887;
lightmagenta: #996600;
//
// Cyan
cyan: #b0c4de;
lightcyan: #b0c4de;
//
// White
white: #bbaa99;
lightwhite: #ddccbb;
//
// Bold, Italic, Underline
highlight: bold #ffffff;
}
#window {
height: 50%;
width: 15em;
location: north east;
anchor: north east;
border: 0px 0px 0px 0px;
x-offset: -30px;
y-offset: 39px;
text-color: @lightwhite;
border-radius: 0px 0px 19px 19px;
}
#mode-switcher {
border: 2px 0px 0px 0px;
background-color: @lightblack;
padding: 4px;
}
#button selected {
border-color: @lightgreen;
text-color: @lightgreen;
}
#inputbar {
background-color: #2c2541;
text-color: @lightgreen;
padding: 4px 4px 4px 4px;
border: 0px 0px 0px 0px;
}
#mainbox {
expand: true;
background-color: #1c1c1cee;
spacing: 1em;
}
#listview {
padding: 0em 1em 0em 1em;
dynamic: false;
lines: 0;
}
#prompt {
margin: 0px 6px 0px 0px;
}
#element selected normal {
background-color: #da0f7a;
}
#element normal active {
text-color: @lightblue;
}
#element normal urgent {
text-color: @lightred;
}
#element alternate normal {
}
#element alternate active {
text-color: @lightblue;
}
#element alternate urgent {
text-color: @lightred;
}
#element selected active {
background-color: @lightblue;
text-color: @dark;
}
#element selected urgent {
background-color: @lightred;
text-color: @dark;
}

+ 149
- 0
misc/rofi/themes/denvit.rasi View File

@ -0,0 +1,149 @@
/* vim:ft=css */
/************************************************
* ROFI Color theme
* User: leofa
* Copyright: 2017 leofa
***********************************************/
* {
selected-normal-foreground: rgba ( 249, 249, 249, 100 % );
foreground: rgba ( 248, 248, 242, 100 % );
normal-foreground: @foreground;
alternate-normal-background: rgba ( 35, 49, 63, 95%);
red: rgba ( 189, 147, 249, 100 % );
selected-urgent-foreground: rgba ( 249, 249, 249, 100 % );
blue: rgba ( 38, 139, 210, 100 % );
urgent-foreground: rgba ( 204, 102, 102, 100 % );
alternate-urgent-background: rgba ( 75, 81, 96, 90 % );
active-foreground: rgba ( 101, 172, 255, 100 % );
lightbg: rgba ( 238, 232, 213, 100 % );
selected-active-foreground: rgba ( 249, 249, 249, 100 % );
alternate-active-background: rgba ( 52,73,94, 60%);
background: rgba ( 189, 147, 249, 95 % );
alternate-normal-foreground: @foreground;
normal-background: @background;
lightfg: rgba ( 88, 104, 117, 100 % );
selected-normal-background: rgba ( 189, 147, 249, 100 % );
border-color: rgba ( 124, 131, 137, 100 % );
spacing: 2;
separatorcolor: rgba ( 29, 31, 33, 100 % );
urgent-background: rgba ( 29, 31, 33, 17 % );
selected-urgent-background: rgba ( 189, 147, 249, 100 % );
alternate-urgent-foreground: @urgent-foreground;
background-color: rgba ( 0, 0, 0, 0 % );
alternate-active-foreground: @active-foreground;
active-background: rgba ( 29, 31, 33, 17 % );
selected-active-background: rgba ( 189, 147, 249, 100 % );
}
#window {
background-color: @background;
border: 1;
padding: 5;
}
#mainbox {
border: 0;
padding: 0;
}
#message {
border: 2px 0px 0px ;
border-color: @separatorcolor;
padding: 1px ;
}
#textbox {
text-color: @foreground;
}
#listview {
fixed-height: 0;
border: 0px 0px 0px ;
border-color: @separatorcolor;
spacing: 2px ;
scrollbar: true;
padding: 2px 0px 0px ;
}
#element {
border: 0;
padding: 1px;
}
#element.normal.normal {
background-color: @normal-background;
text-color: @normal-foreground;
}
#element.normal.urgent {
background-color: @urgent-background;
text-color: @urgent-foreground;
}
#element.normal.active {
background-color: @active-background;
text-color: @active-foreground;
}
#element.selected.normal {
background-color: @selected-normal-background;
text-color: @selected-normal-foreground;
}
#element.selected.urgent {
background-color: @selected-urgent-background;
text-color: @selected-urgent-foreground;
}
#element.selected.active {
background-color: @selected-active-background;
text-color: @selected-active-foreground;
}
#element.alternate.normal {
background-color: @alternate-normal-background;
text-color: @alternate-normal-foreground;
}
#element.alternate.urgent {
background-color: @alternate-urgent-background;
text-color: @alternate-urgent-foreground;
}
#element.alternate.active {
background-color: @alternate-active-background;
text-color: @alternate-active-foreground;
}
#scrollbar {
width: 4px ;
border: 0;
handle-color: @normal-foreground;
handle-width: 8px ;
padding: 0;
}
#sidebar {
border: 0px 0px 0px;
padding: 5px 0 0;
border-color: @separatorcolor;
}
#button {
spacing: 0;
text-color: @normal-foreground;
}
#button.selected {
background-color: @selected-normal-background;
text-color: @selected-normal-foreground;
}
#inputbar {
spacing: 0;
text-color: @normal-foreground;
padding: 1px ;
}
#case-indicator {
spacing: 0;
text-color: @normal-foreground;
}
#entry {
spacing: 0;
text-color: @normal-foreground;
}
#prompt {
spacing: 0;
text-color: @normal-foreground;
}
#inputbar {
children: [ prompt,textbox-prompt-colon,entry,case-indicator ];
}
#textbox-prompt-colon {
expand: false;
str: ":";
margin: 0px 0.3em 0em 0em ;
text-color: @normal-foreground;
}

+ 44
- 0
misc/rofi/themes/dmenu.rasi View File

@ -0,0 +1,44 @@
/**
* ROFI Color theme
* User: Qball
* Copyright: Dave Davenport
*/
* {
background-color: rgba(40, 42, 54, 1);
border-color: rgba(248, 248, 242, 1);
text-color: rgba(248, 248, 242, 1);
font: "Hack Nerd Font 10";
}
window {
anchor: north;
location: north;
width: 100%;
padding: 6px;
children: [ horibox ];
}
horibox {
orientation: horizontal;
children: [ prompt, entry, listview ];
}
listview {
layout: horizontal;
spacing: 5px;
lines: 100;
}
entry {
expand: false;
width: 10em;
}
element {
padding: 0px 2px;
}
element selected {
background-color: rgba(189, 147, 249, 1);
}
/* vim:ft=css

+ 4
- 0
misc/zathura/a View File

@ -0,0 +1,4 @@
set synctex true
set synctex-editor-command "vim +%{line} %{input}"
map <C-i> recolor

+ 64
- 0
misc/zathura/zathurarc View File

@ -0,0 +1,64 @@
# Zathura configuration file
# See man `man zathurarc'
# Open document in fit-width mode by default
set adjust-open "best-fit"
# One page per row by default
set pages-per-row 1
#stop at page boundries
set scroll-page-aware "true"
set smooth-scroll "true"
set scroll-full-overlap 0.01
set scroll-step 100
#zoom settings
set zoom-min 10
set guioptions ""
# zathurarc-dark
set font "inconsolata 15"
set default-bg "#000000" #00
set default-fg "#F7F7F6" #01
set statusbar-fg "#B0B0B0" #04
set statusbar-bg "#202020" #01
set inputbar-bg "#151515" #00 currently not used
set inputbar-fg "#FFFFFF" #02
set notification-error-bg "#AC4142" #08
set notification-error-fg "#151515" #00
set notification-warning-bg "#AC4142" #08
set notification-warning-fg "#151515" #00
set highlight-color "#F4BF75" #0A
set highlight-active-color "#6A9FB5" #0D
set completion-highlight-fg "#151515" #02
set completion-highlight-bg "#90A959" #0C
set completion-bg "#303030" #02
set completion-fg "#E0E0E0" #0C
set notification-bg "#90A959" #0B
set notification-fg "#151515" #00
set recolor "true"
set recolor-lightcolor "#000000" #00
set recolor-darkcolor "#E0E0E0" #06
set recolor-reverse-video "true"
set recolor-keephue "true"
map <C-i> recolor
set render-loading "false"
set scroll-step 50
unmap f
map f toggle_fullscreen
map [fullscreen] f toggle_fullscreen
set selection-clipboard clipboard

+ 163
- 0
scripts/autotrim View File

@ -0,0 +1,163 @@
#!/usr/bin/perl
#
# "Beautify" quoted message and make it "ready-to-reply" by Michael Velten
use utf8;
# keep quotes nested up to 3rd level
my $ind_max = 4;
my $name = '[[:alpha:]]+([\'`-][[:alpha:]]+|[.])*';
my $fullname = '\b(' . $name . '[,]?\s+)*' . $name . '\b';
# Possible reply greetings (regexes) (note that '> ' will be prefixed)
my @greetings = (
'Dear\s+' . $fullname . '([,.]|\s*!)?',
'[Hh](ello|i|ey)' . '(\s+' . $fullname . ')?' . '([,.]|\s*!)?',
'Sehr geehrter?\s+' . $fullname . '([,.]|\s*!)?',
'Lieber?\s+' . $fullname . '([,.]|\s*!)?',
'Guten Tag' . '(\s+' . $fullname . ')?' . '([,.]|\s*!)?',
'[Hh]allo' . '(\s+' . $fullname . ')?' . '([,.]|\s*!)?',
'[Mm]oin' . '(\s+' . $fullname . ')?' . '([,.]|\s*!)?',
'[Mm]esdames(,| et) [Mm]essieurs([,.]|\s*!)?',
'M(adame)\s+' . $fullname . '([,.]|\s*!)?',
'M(onsieur)\s+' . $fullname . '([,.]|\s*!)?',
'[Cc]her\s+' . $fullname . '([,.]|\s*!)?',
'[Cc]h[eè]re\s+' . $fullname . '([,.]|\s*!)?',
'[Bb]onjour' . '(\s+' . $fullname . ')?' . '([,.]|\s*!)?',
'[Ss]alut' . '(\s+' . $fullname . ')?' . '([,.]|\s*!)?',
'Senhor(ita|a)?' . '(\s+' . $fullname . ')?' . '([,.]|\s*!)?',
'Sra?\.?' . '(\s+' . $fullname . ')?' . '([,.]|\s*!)?',
'Car([ií]ssim)?[ao]s?' . '(\s+' . $fullname . ')?' . '([,.]|\s*!)?',
'Prezad([ií]ssim)?[ao]s?' . '(\s+' . $fullname . ')?' . '([,.]|\s*!)?',
'Estimad([ií]ssim)?[ao]s?' . '(\s+' . $fullname . ')?' . '([,.]|\s*!)?',
'[Bb]om [Dd]ia' . '(\s+' . $fullname . ')?' . '([,.]|\s*!)?',
'[Bb]oa ([Tt]arde|[Nn]oite)' . '(\s+' . $fullname . ')?' . '([,.]|\s*!)?',
'[Oo](i|l[aá])' . '(\s+' . $fullname . ')?' . '([,.]|\s*!)?',
'[Aa]l[ôo]' . '(\s+' . $fullname . ')?' . '([,.]|\s*!)?',
'[Hh]ola' . '(\s+' . $fullname . ')?' . '([,.]|\s*!)?',
'Se[nñ]or(ita|a)?' . '(\s+' . $fullname . ')?' . '([,.]|\s*!)?',
);
# Possible reply "greetouts" (regexes) (note that '> ' will be prefixed)
my @greetouts = (
'([Ww]ith )?(([Kk]ind|[Bb]est|[Ww]arm) )?([Rr]egards|[Ww]ishes)([,.]|\s*!)?',
'[Bb]est([,.]|\s*!)?',
'[Cc]heers([,.]|\s*!)?',
'[Mm]it ([Vv]iel|[Bb]est|[Ll]ieb|[Ff]reundlich)en [Gg]r([ü]|ue)([ß]|ss)en([,.]|\s*!)?',
'(([Vv]iel|[Bb]est|[Ll]ieb|[Ff]reundlich)e )?[Gg]r([ü]|ue)([ß]|ss)e([,.]|\s*!)?',
'(([[Bb]est|[Ll]ieb|[Ff]reundlich)e[rn] )?[Gg]ru([ß]|ss)([,.]|\s*!)?',
'[Mm]it (([[Bb]est|[Ll]ieb|[Ff]reundlich)em )?[Gg]ru([ß]|ss)([,.]|\s*!)?',
'([LV]|MF)G([,.]|\s*!)?',
'(([Tt]r[eè]s|[Bb]ien) )?([Cc]ordi|[Aa]mic)alement([,.]|\s*!)?',
'[Aa]miti[eé]s?([,.]|\s*!)?',
'[Aa]tenciosamente([,.]|\s*!)?',
'[Aa]tt([,.]|\s*!)?',
'[Aa]bra[cç]os?([,.]|\s*!)?',
'[Aa]tentamente([,.]|\s*!)?',
'[Cc]ordialmente([,.]|\s*!)?',
);
my $word = '[[:alpha:]]+([\'`-][[:alpha:]]+)*';
# my $saw_greeting = 0;
# my $saw_greetout = 0;
my $saw_own_sig = 0;
my $saw_blank_line = 0;
my $inds_other_sig = 0;
my $quote_header = 0;
my $extra_pref = '';
my (@mail, @purged_mail);
my $msg = shift;
die "Usage: $0 MAIL" unless $msg;
open(MAIL, "+<:encoding(UTF-8)", $msg) or die "$0: Can't open $msg: $!";
push(@mail, $_) while <MAIL>; # Read whole mail
# Process whole mail
LINE:
foreach my $line (@mail) {
# Treat non-quoted lines as is
if ($line !~ /^>/) {
push(@purged_mail, $line);
next LINE;
}
# Keep all lines after my own signature unmodified
if ($line =~ /^--\s?$/ || $saw_own_sig) {
$saw_own_sig = 1;
push(@purged_mail, $line);
next LINE;
}
# $line =~ tr/\xA0/ /;
# tighten "> > " to ">> "
my ($pref, $suff) = $line =~ /^([>[:space:]]+)(.*)$/;
$pref =~ s/(>\s*(?!$))/>/g;
# reduce multiple pre- and post-blanks to one post-blank
$pref =~ s/^\s*(>+)\s*/$1 /;
$line = $pref . $suff . "\n";
# prepend additional '>' for each Outlook quote header
if ($line =~ /^>+ [-_=]{3,}\s*$word(\s+$word)*\s*[-_=]{3,}$/) {
$quote_header = 1;
next LINE;
}
# first line after Outlook quote header that does not start with ...:
if ($quote_header == 1 && $line !~ /^>+ ([-*]\s*)?$word(\s+$word)*\s*:\s+/) {
$extra_pref = '>' . $extra_pref;
$quote_header = 0;
}
$pref = $extra_pref . $pref;
$line = $pref . $suff . "\n";
# skip line if number of '>'s is greater than $ind_max
my $inds = $pref =~ tr/>//;
next LINE if $inds > $ind_max;
# Remove other signatures
if ($line =~ /^>+ --\s?$/) {
$inds_other_sig = $inds;
}
if ($inds == $inds_other_sig) {
next LINE;
} else {
$inds_other_sig = 0;
}
# Remove quoted greeting
# unless ($saw_greeting) {
foreach my $greeting (@greetings) {
if ($line =~ /^>+ $greeting$/) {
# $saw_greeting = 1;
next LINE;
}
}
# }
# Remove quoted "greetout"
# unless ($saw_greetout) {
foreach my $greetout (@greetouts) {
if ($line =~ /^>+ $greetout$/) {
# $saw_greetout = 1;
next LINE;
}
}
# }
# Remove quoted filler lines
if ($line =~ /^>+ \s*(-*|_*|=*|\+*|#*|\**)$/) {
next LINE;
}
# Save purged line
push(@purged_mail, $line);
}
# Overwrite original mail with purged mail
truncate(MAIL, 0);
seek(MAIL, 0, 0);
print MAIL @purged_mail;
close(MAIL);

+ 89
- 0
scripts/bluetooth_battery.py View File

@ -0,0 +1,89 @@
#!/usr/bin/env python3
"""
A python script to get battery level from Bluetooth headsets
"""
# License: GPL-3.0
# Author: @TheWeirdDev
# 29 Sept 2019
import errno
import bluetooth
import sys
def send(sock, message):
sock.send(b"\r\n" + message + b"\r\n")
def getATCommand(sock, line, device):
blevel = -1
if b"BRSF" in line:
send(sock, b"+BRSF: 1024")
send(sock, b"OK")
elif b"CIND=" in line:
send(sock, b"+CIND: (\"battchg\",(0-5))")
send(sock, b"OK")
elif b"CIND?" in line:
send(sock, b"+CIND: 5")
send(sock, b"OK")
elif b"BIND=?" in line:
# Announce that we support the battery level HF indicator
# https://www.bluetooth.com/specifications/assigned-numbers/hands-free-profile/
send(sock, b"+BIND: (2)")
send(sock, b"OK")
elif b"BIND?" in line:
# Enable battery level HF indicator
send(sock, b"+BIND: 2,1")
send(sock, b"OK")
elif b"XAPL=" in line:
send(sock, b"+XAPL: iPhone,7")
send(sock, b"OK")
elif b"IPHONEACCEV" in line:
parts = line.strip().split(b',')[1:]
if len(parts) > 1 and (len(parts) % 2) == 0:
parts = iter(parts)
params = dict(zip(parts, parts))
if b'1' in params:
blevel = (int(params[b'1']) + 1) * 10
elif b"BIEV=" in line:
params = line.strip().split(b"=")[1].split(b",")
if params[0] == b"2":
blevel = int(params[1])
else:
send(sock, b"OK")
if blevel != -1:
print(f"Battery level for {device} is {blevel}%")
return False
return True
def main():
if (len(sys.argv) < 2):
print("Usage: bl_battery.py <BT_MAC_ADDRESS_1>[.PORT] ...")
print(" Port number is optional (default = 4)")
exit()
else:
for device in sys.argv[1:]:
i = device.find('.')
if i == -1:
port = 4
else:
port = int(device[i+1:])
device = device[:i]
try:
s = bluetooth.BluetoothSocket(bluetooth.RFCOMM)
s.connect((device, port))
while getATCommand(s, s.recv(128), device):
pass
s.close()
except OSError as e:
print(f"{device} is offline", e)
if __name__ == "__main__":
main()

+ 239
- 0
scripts/convertToHtmlMultipart View File

@ -0,0 +1,239 @@
#!/usr/bin/env python3
# Original Source: https://github.com/oblitum/dotfiles/blob/ArchLinux/.local/bin/MIMEmbellish
import re
import sys
import email
import shlex
import mimetypes
import subprocess
from copy import copy
from hashlib import md5
from email import charset
from email import encoders
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.nonmultipart import MIMENonMultipart
from os.path import basename, splitext, expanduser
charset.add_charset('utf-8', charset.SHORTEST, '8bit')
def pandoc(from_format, to_format='markdown', plain='markdown', title=None):
markdown = ('markdown'
'-blank_before_blockquote')
if from_format == 'plain':
from_format = plain
if from_format == 'markdown':
from_format = markdown
if to_format == 'markdown':
to_format = markdown
command = 'pandoc -f {} -t {} --standalone --highlight-style=tango'
if to_format in ('html', 'html5'):
if title is not None:
command += ' --variable=pagetitle:{}'.format(shlex.quote(title))
command += ' --webtex --template={}'.format(
expanduser('~/.pandoc/templates/email.html'))
return command.format(from_format, to_format)
def gmailfy(payload):
return payload.replace('<blockquote>',
'<blockquote class="gmail_quote" style="'
'padding: 0 7px 0 7px;'
'border-left: 2px solid #cccccc;'
'font-style: italic;'
'margin: 0 0 7px 3px;'
'">')
def make_alternative(message, part):
alternative = convert(part, 'html',
pandoc(part.get_content_subtype(),
to_format='html',
title=message.get('Subject')))
alternative.set_payload(gmailfy(alternative.get_payload()))
return alternative
def make_replacement(message, part):
return convert(part, 'plain', pandoc(part.get_content_subtype()))
def convert(part, to_subtype, command):
payload = part.get_payload()
if isinstance(payload, str):
payload = payload.encode('utf-8')
else:
payload = part.get_payload(None, True)
if not isinstance(payload, bytes):
payload = payload.encode('utf-8')
process = subprocess.run(
shlex.split(command),
input=payload, stdout=subprocess.PIPE, check=True)
return MIMEText(process.stdout, to_subtype, 'utf-8')
def with_alternative(parent, part, from_signed,
make_alternative=make_alternative,
make_replacement=None):
try:
alternative = make_alternative(parent or part, from_signed or part)
replacement = (make_replacement(parent or part, part)
if from_signed is None and make_replacement is not None
else part)
except:
return parent or part
envelope = MIMEMultipart('alternative')
if parent is None:
for k, v in part.items():
if (k.lower() != 'mime-version'
and not k.lower().startswith('content-')):
envelope.add_header(k, v)
del part[k]
envelope.attach(replacement)
envelope.attach(alternative)
if parent is None:
return envelope
payload = parent.get_payload()
payload[payload.index(part)] = envelope
return parent
def tag_attachments(message):
if message.get_content_type() == 'multipart/mixed':
for part in message.get_payload():
if (part.get_content_maintype() in ['image']
and 'Content-ID' not in part):
filename = part.get_param('filename',
header='Content-Disposition')
if isinstance(filename, tuple):
filename = str(filename[2], filename[0] or 'us-ascii')
if filename:
filename = splitext(basename(filename))[0]
if filename:
part.add_header('Content-ID', '<{}>'.format(filename))
return message
def attachment_from_file_path(attachment_path):
try:
mime, encoding = mimetypes.guess_type(attachment_path, strict=False)
maintype, subtype = mime.split('/')
with open(attachment_path, 'rb') as payload:
attachment = MIMENonMultipart(maintype, subtype)
attachment.set_payload(payload.read())
encoders.encode_base64(attachment)
if encoding:
attachment.add_header('Content-Encoding', encoding)
return attachment
except:
return None
attachment_path_pattern = re.compile(r'\]\s*\(\s*file://(/[^)]*\S)\s*\)|'
r'\]\s*:\s*file://(/.*\S)\s*$',
re.MULTILINE)
def link_attachments(payload):
attached = []
attachments = []
def on_match(match):
if match.group(1):
attachment_path = match.group(1)
cid_fmt = '](cid:{})'
else:
attachment_path = match.group(2)
cid_fmt = ']: cid:{}'
attachment_id = md5(attachment_path.encode()).hexdigest()
if attachment_id in attached:
return cid_fmt.format(attachment_id)
attachment = attachment_from_file_path(attachment_path)
if attachment:
attachment.add_header('Content-ID', '<{}>'.format(attachment_id))
attachments.append(attachment)
attached.append(attachment_id)
return cid_fmt.format(attachment_id)
return match.group()
return attachments, attachment_path_pattern.sub(on_match, payload)
def with_local_attachments(parent, part, from_signed,
link_attachments=link_attachments):
if from_signed is None:
attachments, payload = link_attachments(part.get_payload())
part.set_payload(payload)
else:
attachments, payload = link_attachments(from_signed.get_payload())
from_signed = copy(from_signed)
from_signed.set_payload(payload)
if not attachments:
return parent, part, from_signed
if parent is None:
parent = MIMEMultipart('mixed')
for k, v in part.items():
if (k.lower() != 'mime-version'
and not k.lower().startswith('content-')):
parent.add_header(k, v)
del part[k]
parent.attach(part)
for attachment in attachments:
parent.attach(attachment)
return parent, part, from_signed
def is_target(part, target_subtypes):
return (part.get('Content-Disposition', 'inline') == 'inline'
and part.get_content_maintype() == 'text'
and part.get_content_subtype() in target_subtypes)
def pick_from_signed(part, target_subtypes):
for from_signed in part.get_payload():
if is_target(from_signed, target_subtypes):
return from_signed
def seek_target(message, target_subtypes=['plain', 'markdown']):
if message.is_multipart():
if message.get_content_type() == 'multipart/signed':
part = pick_from_signed(message, target_subtypes)
if part is not None:
return None, message, part
elif message.get_content_type() == 'multipart/mixed':
for part in message.get_payload():
if part.is_multipart():
if part.get_content_type() == 'multipart/signed':
from_signed = pick_from_signed(part, target_subtypes)
if from_signed is not None:
return message, part, from_signed
elif is_target(part, target_subtypes):
return message, part, None
else:
if is_target(message, target_subtypes):
return None, message, None
return None, None, None
def main():
try:
message = email.message_from_file(sys.stdin)
parent, part, from_signed = seek_target(message)
if (parent, part, from_signed) == (None, None, None):
print(message)
return
tag_attachments(message)
print(with_alternative(
*with_local_attachments(parent, part, from_signed)))
except (BrokenPipeError, KeyboardInterrupt):
pass
if __name__ == '__main__':
main()

+ 80
- 0
scripts/dmenu-killall View File

@ -0,0 +1,80 @@
#!/bin/sh
#description: dmenu for killall
#usage: dmenu-killall is best suited for launching from a shortcut
#example: dmenu-killall
#a gui menu appears asking for which app to kill
progname="$(expr "${0}" : '.*/\([^/]*\)')"
#variables are impractical to save complex cmds because of shell expantion
#therefore functions are required: http://mywiki.wooledge.org/BashFAQ/050
DMENU() { dmenu -p 'Kill'; }
#looks better on xft powered dmenu:
#https://bugs.launchpad.net/ubuntu/+source/suckless-tools/+bug/1093745
_usage() {
printf "%s\\n" "Usage: ${progname} [PATTERN]"
printf "%s\\n" "Dmenu window selector for i3-wm."
printf "%s\\n"
printf "%s\\n" " -h, --help show this message and exit"
}
_die() {
[ -n "${1}" ] && _die_msg="${1}" || exit 1
printf "%b%b\\n" "${_die_msg}" ", press <Enter> to exit" | DMENU
exit 1
}
_notify() {
[ -z "${1}" ] && return 1
kill -9 $(pgrep notify-osd) >/dev/null 2>&1
if ! DISPLAY=${DISPLAY:-:0} notify-send -t 1000 "${1}" "${2}"; then
if command -v "gxmessage" 2>/dev/null; then
font="Monaco 9"
DISPLAY=${DISPLAY:-:0} gxmessage "${font:+-fn "$font"}" "${1}" "ok"
elif command -v "xmessage" 2>/dev/null; then
font="fixed"
DISPLAY=${DISPLAY:-:0} xmessage "${font:+-fn "$font"}" "${1}" "ok"
fi
fi
}
_get_process_names() {
printf "%s\\n" "$(command ps xo command= | sed \
-e "s: .*::; s:.*/::; s/:$//;" \
-e "s:^\[.*\]$::" -e "/^$/d" \
-e "s:^<defunct>$::")" | sort | uniq
}
if [ ! -t 0 ]; then
#add input comming from pipe or file to $@
set -- "${@}" $(cat)
fi
for arg in "${@}"; do #parse options
case "${arg}" in
-h|--help) _usage && exit ;;
esac
done
if [ -z "${1}" ]; then
if ! command -v "dmenu" >/dev/null 2>&1; then
printf "%s\\n" "${progname}: install 'dmenu' to run this program" >&2
exit 1
fi
process_name="$(_get_process_names | DMENU)"
else
process_name="$(_get_process_names | grep -i "${@}" 2>/dev/null | head -1 )"
fi
if [ -z "${process_name}" ]; then
_die
else
error_msg="$(kill -9 $(pgrep -x "${process_name}") 2>&1 1>/dev/null)"
if [ X"${?}" != X"0" ]; then
_notify "Error" "${error_msg}"
exit 1
fi
fi
#vim:ft=sh

+ 61
- 0
scripts/dmenu-logout View File

@ -0,0 +1,61 @@
#!/bin/sh
# Set environment
export BSPWM_CONFIG="${XDG_CONFIG_HOME:-$HOME/.config}/bspwm"
# Function to kill programs
killprogs() {
# Kill udisks-glue
pkill -x udisks-glue
# Kill panel
pkill -x panel
# Kill Redshift
pkill -x redshift
}
# Restart function
# shellcheck source=/dev/null
restart() {
reboot
}
# Logout function
logout() {
pkill dwm
}
# Load dmenu config
# shellcheck source=/dev/null
[ -f "$HOME/.dmenurc" ] && . "$HOME/.dmenurc" || DMENU='dmenu -i'
# Menu items
items="logout
suspend
reboot
poweroff"
# Open menu
selection=$(printf '%s' "$items" | $DMENU)
case $selection in
restart)
restart
;;
logout)
logout
;;
hibernate)
systemctl hibernate
;;
suspend)
systemctl suspend
;;
reboot)
reboot
;;
halt|poweroff|shutdown)
shutdown -h now
;;
esac
exit

+ 23
- 0
scripts/dunst_toggle.sh View File

@ -0,0 +1,23 @@
#!/bin/zsh
getargs() {
while getopts "se" opt
do
case $opt in
s) start="true";;
e) end="true";;
esac
done
}
start_dnd() {
notify-send "DUNST_COMMAND_PAUSE";
}
end_dnd() {
notify-send "DUNST_COMMAND_RESUME";
notify-send "Do Not Disturb" "Do Not Disturb mode ended. Notifications will be shown.";
}
main() {
getargs "$@";
[[ "$start" ]] && start_dnd;
[[ "$end" ]] && end_dnd;
}
main "$@"

+ 26
- 0
scripts/gen_tracking_url View File

@ -0,0 +1,26 @@
#!/bin/python
import sys
from base64 import b64decode
from hashlib import sha256
from urllib.parse import quote
message = b64decode(sys.argv[1]).decode()
userid = "1"
key = "Rwb3pUUG8fQAZUs3Q3qwdHH25Fdq8dyJyzUQqERzrCfxavKExfSExQbr8dZXho57abGvTZGdBmSbyXdVM59jDVi4L5ien9xoVHskMdx4FxNXyq7uBPYaAeA62JXzMZT9"
domain = "https://hermes.yigitcolakoglu.com/read"
subject = "NIL"
recipient = "NIL"
for i in message.split("\n"):
if i.split(" ")[0] == "Subject:":
subject = i[9:]
elif i.split(" ")[0] == "To:":
recipient = i[4:]
identifier = subject + recipient + userid + key
identifier_hash = sha256(identifier.encode("utf-8")).hexdigest()
url = "{}/{}/{}/{}/{}".format(domain,userid,quote(subject),quote(recipient),identifier_hash)
print('![Hermes]({})'.format(url))

+ 15
- 0
scripts/mail_tag.sh View File

@ -0,0 +1,15 @@
notmuch tag +g_draft path:"Gmail/draft/**"
notmuch tag +g_sent path:"Gmail/sent/**"
notmuch tag +g_spam path:"Gmail/spam/**"
notmuch tag +g_archive path:"Gmail/archived/**"
notmuch tag +o_draft path:"Outlook/draft/**"
notmuch tag +o_sent path:"Outlook/sent/**"
notmuch tag +o_spam path:"Outlook/spam/**"
notmuch tag +o_archive path:"Outlook/archive/**"
notmuch tag +p_draft path:"Private/draft/**"
notmuch tag +p_sent path:"Private/sent/**"
notmuch tag +p_spam path:"Private/spam/**"
notmuch tag +p_archive path:"Private/archive/**"

+ 8
- 0
scripts/mails.sh View File

@ -0,0 +1,8 @@
new=$(notmuch search 'tag:inbox and tag:unread and NOT path:*/archive NOT tag:archive and NOT tag:spam and NOT tag:sent and NOT tag:draft' | wc -l)
if [[ $new != 0 ]]
then
dunstify --icon='/home/yigit/.icons/mail.png' -a 'New Email' "You have $new new mail."
fi
echo $new > /home/yigit/.config/mail_num

+ 4
- 0
scripts/newmail.sh View File

@ -0,0 +1,4 @@
#!/bin/bash
mbsync $1
notmuch new
notmuch tag --batch --input=/home/yigit/.notmuch_tag

+ 28
- 0
scripts/nm_sendmail.sh View File

@ -0,0 +1,28 @@
#!/bin/bash
# Put the message, send to stdin, in a variable
m="$(cat -)"
m64="$(echo -e "$m" | base64)"
echo "$m64" > /tmp/test2
tracking_url=$(/home/yigit/.scripts/gen_tracking_url "$m64" 2> /tmp/testerr)
echo $tracking_url > /tmp/test3
# Look at the first argument,
# Use it to determine the account to use
# If not set, assume work
# All remaining arguments should be recipient addresses which should be passed to msmtp
account="$1"
shift 1
cleanHeaders(){
# In the headers, delete any lines starting with markdown
cat - | sed '0,/^$/{/^markdown/Id;}'
}
echo "$@"
echo "$message" | cleanHeaders > /tmp/headers
echo "msmtp -a $account $@"
echo "$message" | sed '/^$/q' | grep -q -i 'markdown: true' \
&& msg=$(echo "$message \n$tracking_url" | cleanHeaders | /home/yigit/.scripts/convertToHtmlMultipart && echo 1 >> /tmp/state) || msg=$(echo "$message" | cleanHeaders)
echo "$msg" > /tmp/test
echo "$msg" | notmuch insert --folder="$account/sent" +sent -inbox
echo "$msg" | msmtp -a $account $@

+ 12
- 0
scripts/status-bar/arch View File

@ -0,0 +1,12 @@
#!/bin/sh
icon=󰮯
if ! updates=$(checkupdates 2> /dev/null | wc -l ); then
updates=0
fi
echo $updates > ~/.cache/pacman_updates
#echo "$ifg $icon $tfg$(cat ~/.cache/pacman_updates)"
echo "$icon $(cat ~/.cache/pacman_updates)"

+ 17
- 0
scripts/status-bar/arch-block View File

@ -0,0 +1,17 @@
#!/bin/sh
icon=󰮯
ibg=^b#705B86^
ifg=^c#fabd2f^
tfg=^c#292541^
tbg=^b#cdabb8^
reset=^d^
if ! updates=$(checkupdates 2> /dev/null | wc -l ); then
updates=0t
fi
echo $updates > ~/.cache/pacman_updates
echo "$ibg$ifg $icon $tfg$tbg $(cat ~/.cache/pacman_updates) $reset"

+ 37
- 0
scripts/status-bar/battery View File

@ -0,0 +1,37 @@
#! /bin/sh
bat=$(cat /sys/class/power_supply/BAT0/capacity)
status=$(cat /sys/class/power_supply/BAT0/status)
ramp10=󰁺
ramp20=󰁻
ramp30=󰁼
ramp40=󰁽
ramp50=󰁾
ramp60=󰁿
ramp70=󰂀
ramp80=󰂁
ramp90=󰂂
ramp100=󰁹
if [[ $bat -lt 10 ]]; then
echo " $ramp10 $bat% "
elif [[ $bat -lt 20 ]]; then
echo " $ramp20 $bat% "
elif [[ $bat -lt "30" ]]; then
echo " $ramp30 $bat% "
elif [[ $bat -lt "40" ]]; then
echo " $ramp40 $bat% "
elif [[ $bat -lt "50" ]]; then
echo " $ramp50 $bat% "
elif [[ $bat -lt "60" ]]; then
echo " $ramp60 $bat% "
elif [[ $bat -lt "70" ]]; then
echo " $ramp70 $bat% "
elif [[ $bat -lt "80" ]]; then
echo " $ramp80 $bat% "
elif [[ $bat -lt "90" ]]; then
echo " $ramp90 $bat% "
elif [[ $bat -le "100" ]]; then
echo " $ramp100 $bat% "
fi

+ 49
- 0
scripts/status-bar/battery-blocks View File

@ -0,0 +1,49 @@
#! /bin/sh
bat=$(cat /sys/class/power_supply/BAT0/capacity)
status=$(cat /sys/class/power_supply/BAT0/status)
ramp10=󰁺
ramp20=󰁻
ramp30=󰁼
ramp40=󰁽
ramp50=󰁾
ramp60=󰁿
ramp70=󰂀
ramp80=󰂁
ramp90=󰂂
ramp100=󰁹
tbg=^b#cdabb8^
tfg=^c#292541^
reset=^d^
if [[ $status == "Discharging" ]]; then
ibg=^b#705b86^
elif [[ $status == "Full" ]]; then
ibg=^b#50FA7B^
else
ibg=^b#50FA7B^
fi
if [[ $bat -lt 10 ]]; then
echo "$ibg$tfg $ramp10 $tbg $bat% $reset"
elif [[ $bat -lt 20 ]]; then
echo "$ibg$tfg $ramp20 $tbg $bat% $reset"
elif [[ $bat -lt "30" ]]; then
echo "$ibg$tfg $ramp30 $tbg $bat% $reset"
elif [[ $bat -lt "40" ]]; then
echo "$ibg$tfg $ramp40 $tbg $bat% $reset"
elif [[ $bat -lt "50" ]]; then
echo "$ibg$tfg $ramp50 $tbg $bat% $reset"
elif [[ $bat -lt "60" ]]; then
echo "$ibg$tfg $ramp60 $tbg $bat% $reset"
elif [[ $bat -lt "70" ]]; then
echo "$ibg$tfg $ramp70 $tbg $bat% $reset"
elif [[ $bat -lt "80" ]]; then
echo "$ibg$tfg $ramp80 $tbg $bat% $reset"
elif [[ $bat -lt "90" ]]; then
echo "$ibg$tfg $ramp90 $tbg $bat% $reset"
elif [[ $bat -le "100" ]]; then
echo "$ibg$tfg $ramp100 $tbg $bat% $reset"
fi

+ 14
- 0
scripts/status-bar/capslock View File

@ -0,0 +1,14 @@
#! /bin/sh
icon=󰘲
bfg=^b#292541^
tfg=^c#cc241d^
reset=^d^
cmd=$(cat /sys/class/leds/input3::capslock/brightness)
if [[ "$cmd" == "1" ]]; then
echo "$tfg$tbg $icon $reset"
else
echo ""
fi

+ 12
- 0
scripts/status-bar/clima View File

@ -0,0 +1,12 @@
#! /bin/sh
#localización
#initloc=$(curl -s ifconfig.co/city)
#if [ "$initloc" == "La Paz" ]; then
# loc="LAP"
#else
# loc=init-loc
#fi
# obtener clima
#curl -s "wttr.in/$loc?format=%t"
curl -s "wttr.in/?format=%t"

+ 27
- 0
scripts/status-bar/clima-icon View File

@ -0,0 +1,27 @@
#! /bin/sh
estado=$(curl -s "wttr.in/?format=%C" )
case $estado in
Unknown) icon="";;
Cloudy) icon="";;
Fog) icon="";;
"Heavy rain") icon="";;
"Heavy showers") icon="";;
"Heavy snow") icon="";;
"Heavy snow showers") icon="";;
"Light rain") icon="";;
"Light showers") icon="";;
"Light sleet") icon="";;
"Light sleet showers") icon="";;
"Light snow") icon="";;
"Light snow showers") icon="";;
"Partly cloudy") icon="";;
"Sunny") icon="";;
"Clear") icon="";;
"Thundery heavy rain") icon="";;
"Thundery showers") icon="";;
"Thundery snow showers") icon="";;
"Very cloudy") icon="";;
esac
echo $icon

+ 6
- 0
scripts/status-bar/cpu-temp View File

@ -0,0 +1,6 @@
#! /bin/sh
temp=$(sed 's/000$/°C/' /sys/class/thermal/thermal_zone0/temp)
icon=󰔏
echo "$icon $temp "

+ 9
- 0
scripts/status-bar/fecha View File

@ -0,0 +1,9 @@
#! /bin/sh
icon=󰸘
cmd=$(date +"%b %e, %R")
#echo "$ifg $icon $tfg$cmd"
echo "$icon $cmd"

+ 11
- 0
scripts/status-bar/fecha-block View File

@ -0,0 +1,11 @@
#! /bin/sh
icon=󰸘
tfg=^c#292541^
ibg=^b#705b86^
tbg=^b#cdabb8^
reset=^d^
cmd=$(date +"%b %e, %R")
echo "$tfg$ibg$ifg $icon $tbg $cmd $reset"

+ 10
- 0
scripts/status-bar/listener View File

@ -0,0 +1,10 @@
#! /bin/sh
while true; do
read -t 1 -n 1 key
if [[ $key == o ]]; then
notify-send "presionaste la o"
fi
done

+ 9
- 0
scripts/status-bar/red View File

@ -0,0 +1,9 @@
#! /bin/sh
if [[ $(cat /sys/class/net/wlp*/operstate) == "up" ]]; then
echo " 󰤨 "
else
echo " 󰤮 "
fi

+ 14
- 0
scripts/status-bar/red-texto View File

@ -0,0 +1,14 @@
#! /bin/sh
if [[ $(cat /sys/class/net/wlp*/operstate) == "up" ]]; then
echo " WiFi "
else
ping -c 1 google.com
if [[ $? == 0 ]]; then
echo "Eth"
else
" "
fi
fi

+ 3
- 0
scripts/status-bar/sep1 View File

@ -0,0 +1,3 @@
#! /bin/sh
echo ""

+ 14
- 0
scripts/status-bar/spotify-bar View File

@ -0,0 +1,14 @@
#! /bin/sh
icon=" 󰓇"
#status=$(~/.local/bin/status-bar/spotify_status.py -f '{artist} - {song}')
status=$(playerctl metadata --format '{{artist}} - {{title}}' | cut -c 1-50)
runstate=$(playerctl status)
if [[ $runstate == "Playing" ]]; then
echo " $icon $status"
else
echo ""
fi

+ 17
- 0
scripts/status-bar/spotify-block View File

@ -0,0 +1,17 @@
#! /bin/sh
icon="󰓇"
ibg=^b#875B82^
ifg=^c#1DB954^
tfg=^c#292541^
tbg=^b#cdabb8^
reset=^d^
status=$(~/.local/bin/status-bar/spotify_status.py)
runstate=$(pgrep -c spotify)
if [[ $runstate -le 1 ]]; then
echo ""
else
echo "$ibg$ifg $icon $tbg$tfg $status $reset"
fi

+ 122
- 0
scripts/status-bar/spotify_status.py View File

@ -0,0 +1,122 @@
#!/bin/python
import sys
import dbus
import argparse
parser = argparse.ArgumentParser()
parser.add_argument(
'-t',
'--trunclen',
type=int,
metavar='trunclen'
)
parser.add_argument(
'-f',
'--format',
type=str,
metavar='custom format',
dest='custom_format'
)
parser.add_argument(
'-p',
'--playpause',
type=str,
metavar='play-pause indicator',
dest='play_pause'
)
parser.add_argument(
'--font',
type=str,
metavar='the index of the font to use for the main label',
dest='font'
)
parser.add_argument(
'--playpause-font',
type=str,
metavar='the index of the font to use to display the playpause indicator',
dest='play_pause_font'
)
args = parser.parse_args()
def fix_string(string):
# corrects encoding for the python version used
if sys.version_info.major == 3:
return string
else:
return string.encode('utf-8')
# Default parameters
output = fix_string(u'{play_pause} {artist}: {song}')
trunclen = 35
play_pause = fix_string(u'\u25B6,\u23F8') # first character is play, second is paused
label_with_font = '%{{T{font}}}{label}%{{T-}}'
font = args.font
play_pause_font = args.play_pause_font
# parameters can be overwritten by args
if args.trunclen is not None:
trunclen = args.trunclen
if args.custom_format is not None:
output = args.custom_format
if args.play_pause is not None:
play_pause = args.play_pause
try:
session_bus = dbus.SessionBus()
spotify_bus = session_bus.get_object(
'org.mpris.MediaPlayer2.spotify',
'/org/mpris/MediaPlayer2'
)
spotify_properties = dbus.Interface(
spotify_bus,
'org.freedesktop.DBus.Properties'
)
metadata = spotify_properties.Get('org.mpris.MediaPlayer2.Player', 'Metadata')
status = spotify_properties.Get('org.mpris.MediaPlayer2.Player', 'PlaybackStatus')
# Handle play/pause label
play_pause = play_pause.split(',')
if status == 'Playing':
play_pause = play_pause[0]
elif status == 'Paused':
play_pause = play_pause[1]
else:
play_pause = str()
if play_pause_font:
play_pause = label_with_font.format(font=play_pause_font, label=play_pause)
# Handle main label
artist = fix_string(metadata['xesam:artist'][0]) if metadata['xesam:artist'] else ''
song = fix_string(metadata['xesam:title']) if metadata['xesam:title'] else ''
if not artist and not song:
print('')
else:
if len(song) > trunclen:
song = song[0:trunclen]
song += '...'
if ('(' in song) and (')' not in song):
song += ')'
if font:
artist = label_with_font.format(font=font, label=artist)
song = label_with_font.format(font=font, label=song)
print(output.format(artist=artist, song=song, play_pause=play_pause))
except Exception as e:
if isinstance(e, dbus.exceptions.DBusException):
print('')
else:
print(e)

+ 24
- 0
scripts/status-bar/volume View File

@ -0,0 +1,24 @@
#! /bin/sh
#mute=$(amixer get Master | awk -F'[][]' 'END{ print $6 }' )
#vol=$(amixer get Master | awk -F'[][]' 'END{ print $2 }' )
mute=$(pamixer --get-mute)
vol=$(pamixer --get-volume)
iconmute=󰖁
ramp1=󰕿
ramp2=󰖀
ramp3=󰕾
#if [[ $mute == "true" ]]; then
# echo " $iconmute $vol% "
if [[ $mute == "true" ]]; then
echo " $iconmute mute"
elif [[ "$vol" -ge "100" ]]; then
echo "$ramp3 $vol% "
elif [[ "$vol" -le "33" ]]; then
echo "$ramp1 $vol% "
elif [[ "$vol" -le "66" ]]; then
echo "$ramp2 $vol% "
elif [[ "$vol" -ge "66" ]]; then
echo "$ramp3 $vol% "
fi

+ 29
- 0
scripts/status-bar/volume-block View File

@ -0,0 +1,29 @@
#! /bin/sh
#mute=$(amixer get Master | awk -F'[][]' 'END{ print $6 }' )
#vol=$(amixer get Master | awk -F'[][]' 'END{ print $2 }' )
mute=$(pamixer --get-mute)
vol=$(pamixer --get-volume)
iconmute=󰖁
ramp1=󰕿
ramp2=󰖀
ramp3=󰕾
mbg=^b#cc241d^
tfg=^c#292541^
ibg=^b#875b82^
tbg=^b#cdabb8^
reset=^d^
if [[ $mute == "true" ]]; then
echo "$mbg$tfg $iconmute $tbg$tfg $vol% $reset"
elif [[ "$vol" == "100" ]]; then
echo "$ibg$tfg $ramp3 $tbg$tfg $vol% $reset"
elif [[ "$vol" < "33" ]]; then
echo "$ibg$tfg $ramp1 $tbg$tfg $vol% $reset"
elif [[ "$vol" < "66" ]]; then
echo "$ibg$tfg $ramp2 $tbg$tfg $vol% $reset"
elif [[ "$vol" = "66" ]]; then
echo "$ibg$tfg $ramp2 $tbg$tfg $vol% $reset"
elif [[ "$vol" > "66" ]]; then
echo "$ibg$tfg $ramp3 $tbg$tfg $vol% $reset"
fi

+ 6
- 0
scripts/toggle_monitor.sh View File

@ -0,0 +1,6 @@
#!/bin/bash
extern=HDMI1
if xrandr | grep -v "$extern disconnected"; then
xrandr --output eDP1 --mode 1920x1080 --pos 0x0 --rotate normal --output DP1 --off --output HDMI1 --primary --mode 1920x1080 --pos 1920x0 --rotate normal --output HDMI2 --off --output VIRTUAL1 --off
fi

+ 9
- 0
scripts/toggle_touchpad.sh View File

@ -0,0 +1,9 @@
#!/bin/bash
if xinput list-props "MSFT0001:00 06CB:7E7E Touchpad" | grep "Device Enabled ([0-9]*):.*1" >/dev/null
then
xinput disable "MSFT0001:00 06CB:7E7E Touchpad"
notify-send -u low -i mouse "Trackpad disabled"
else
xinput enable "MSFT0001:00 06CB:7E7E Touchpad"
notify-send -u low -i mouse "Trackpad enabled"
fi

+ 3
- 0
scripts/update_events.sh View File

@ -0,0 +1,3 @@
#!/bin/bash
echo $((($(khal list -f \"{uid}\" | wc -l) - 1))) > /home/yigit/.cache/events

+ 28
- 0
scripts/welcome.sh View File

@ -0,0 +1,28 @@
NC='\033[0m'
RED='\033[0;31m'
GREEN='\033[0;32m'
ORANGE='\033[0;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
CYAN='\033[0;36m'
LIGHTGRAY='\033[0;37m'
DARKGRAY='\033[1;30m'
LIGHTRED='\033[1;31m'
LIGHTGREEN='\033[1;32m'
YELLOW='\033[1;33m'
LIGHTBLUE='\033[1;34m'
LIGHTPURPLE='\033[1;35m'
LIGHTCYAN='\033[1;36m'
WHITE='\033[1;37m'
COLUMNS=$(tput cols)
PADDING="\t"
echo -en "\n${CYAN}"
figlet -w $COLUMNS -c -f nancyj "Fr1nge"
echo -en ${NC}
footer="${BLUE}$(whoami)${NC}${YELLOW}@${NC}${RED}$(hostname)${NC}"
footer_nc="$(whoami)@$(hostname)"
printf "%*s" $((($COLUMNS-${#footer_nc})/2)) ""
echo -e "$footer"
echo ""

+ 245
- 0
suckless/dwm/, View File

@ -0,0 +1,245 @@
/* See LICENSE file for copyright and license details. */
#include <X11/XF86keysym.h>
/* appearance */
static const unsigned int borderpx = 3; /* border pixel of windows */
static const unsigned int gappx = 6;
static const unsigned int snap = 32; /* snap pixel */
static const int rmaster = 0; /* 1 = master at right*/
static const int showbar = 1; /* 0 means no bar */
static const int topbar = 1; /* 0 means bottom bar */
static const int user_bh = 27; /* 0 means that dwm will calculate bar height, >= 1 means dwm will user_bh as bar height */
static const int tag_padding = 0;
static const int vertpad = 0; /* vertical padding of bar */
static const int sidepad = 0; /* horizontal padding of bar */
static const char *fonts[] = {"Hack Nerd Font:Regular:size=10", "Material Design Icons:Regular:pixelsize=16:antialias=true"};
static const char dmenufont[] = "Hack Nerd Font:size=10";
static const char fore[] = "#f8f8f2";
static const char back[] = "#282a36";
static const char border[] = "#f8f8f2";
static const char col0[] = "#000000";
static const char col1[] = "#FF5555";
static const char col2[] = "#50FA7B";
static const char col3[] = "#F1FA8C";
static const char col4[] = "#BD93F9";
static const char col5[] = "#FF79C6";
static const char col6[] = "#8BE9FD";
static const char col7[] = "#BFBFBF";
static const char col8[] = "#4D4D4D";
static const char col9[] = "#FF6E67";
static const char col10[] = "#5AF78E";
static const char col11[] = "#F4F99D";
static const char col12[] = "#CAA9FA";
static const char col13[] = "#FF92D0";
static const char col14[] = "#9AEDFE";
static const char col15[] = "#E6E6E6";
static const char spotify[]= "#1FC167";
static const char *colors[][3] = {
/* fg bg border */
[SchemeNorm] = { fore, back, back }, // \x0b
[SchemeSel] = { fore, back, border }, // \x0c
[SchemeStatus] = { fore, back, border }, // \x0d Statusbar right
[SchemeTagsSel] = { col4, back, border }, // \x0e Tagbar left selected
[SchemeTagsNorm] = { fore, back, border }, // \x0f Tagbar left unselected
[SchemeInfoSel] = { fore, back, border }, // \x10 infobar middle selected
[SchemeInfoNorm] = { fore, back, border }, // \x11 infobar middle unselected
[SchemeCol1] = { col1, back, col0 }, // \x12
[SchemeCol2] = { col2, back, col0 }, // \x13
[SchemeCol3] = { col3, back, col0 }, // \x14
[SchemeCol4] = { col4, back, col0 }, // \x15
[SchemeCol5] = { col5, back, col0 }, // \x16
[SchemeCol6] = { col6, back, col0 }, // \x17
[SchemeCol7] = { col7, back, col0 }, // \x18
[SchemeCol8] = { col8, back, col0 }, // \x19
[SchemeCol9] = { col9, back, col0 }, // \x1a
[SchemeCol10] = { col10, back, col0 }, // \x1b
[SchemeCol11] = { col11, back, col0 }, // \x1c
[SchemeCol12] = { spotify, back, col0 }, // \x1d Spotify
};
/* tagging */
static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "0"};
//static const char *alttags[] = { "󰄯", "󰄯", "󰄯", "󰄯"};
static const Rule rules[] = {
/* xprop(1):
* WM_CLASS(STRING) = instance, class
* WM_NAME(STRING) = title
*/
/* class instance title tags mask isfloating monitor */
{ "discord", NULL, NULL, 1 << 8, 0, -1 },
{ "Termite", NULL, NULL, 1 << 0, 0, -1 },
{ "firefoxdeveloperedition", NULL, NULL, 1 << 1, 0, -1 },
{ "Tor Browser", NULL, NULL, 1 << 1, 0, -1 },
{ "Chromium", NULL, NULL, 1 << 1, 0, -1 },
{ "zoom", NULL, NULL, 1 << 4, 0, -1 },
{ "TelegramDesktop", NULL, NULL, 1 << 8, 0, -1 },
{ "whatsapp-nativefier-d52542", NULL, NULL, 1 << 8, 0, -1 },
{ "neomutt", NULL, NULL, 1 << 7, 0, -1 },
{ "Sublime_Text", NULL, NULL, 1 << 2, 0, -1 },
{ "code-oss", NULL, NULL, 1 << 2, 0, -1 },
{ "jetbrains-idea", NULL, NULL, 1 << 2, 0, -1 },
{ "Nemo", NULL, NULL, 1 << 3, 1, -1 },
{ "Spotify", NULL, NULL, 1 << 9, 0, -1 },
};
/* layout(s) */
static const float mfact = 0.5; /* factor of master area size [0.05..0.95] */
static const int nmaster = 1; /* number of clients in master area */
static const int resizehints = 0; /* 1 means respect size hints in tiled resizals */
#include "fibonacci.c"
#include "layouts.c"
static const Layout layouts[] = {
/* symbol arrange function */
{ "鉶", tile }, /* first entry is default */
{ "", dwindle },
{ "ﱖ", grid },
{ "", centeredmaster },
{ "", centeredfloatingmaster },
{ "[M]", monocle },
{ "[D]", deck },
{ NULL, NULL },
};
/* key definitions */
#define MODKEY Mod4Mask
#define TAGKEYS(KEY,TAG) \
{ MODKEY, KEY, view, {.ui = 1 << TAG} }, \
{ MODKEY|Mod1Mask, KEY, toggleview, {.ui = 1 << TAG} }, \
{ MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \
{ MODKEY|ControlMask, KEY, toggletag, {.ui = 1 << TAG} },
/* COSAS QUE TENGO QUE AVERIGUAR COMO QUITAR */
/* helper for spawning shell commands in the pre dwm-5.0 fashion */
#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */
static const char *dmenucmd[] = { "/usr/bin/rofi","-show","drun", NULL };
static const char *termcmd[] = { "/usr/bin/termite", "--title", "Terminal", NULL };
static const char *upvol[] = { "/usr/bin/pactl", "set-sink-volume", "0", "+5%", NULL };
static const char *downvol[] = { "/usr/bin/pactl", "set-sink-volume", "0", "-5%", NULL };
static const char *mutevol[] = { "/usr/bin/pactl", "set-sink-mute", "0", "toggle", NULL };
static const char *upbright[] = {"/usr/bin/xbacklight","-inc","10",NULL};
static const char *downbright[] = {"/usr/bin/xbacklight","-dec","10",NULL};
static const char *lock[] = {"/usr/bin/betterlockscreen","-l","-t","Stay the fuck out!",NULL};
static const char *clipmenu[] = {"/usr/bin/clipmenu","-i",NULL};
static const char *play[] = {"/usr/bin/playerctl","play-pause",NULL};
static const char *prev[] = {"/usr/bin/playerctl","previous",NULL};
static const char *next[] = {"/usr/bin/playerctl","next",NULL};
static const char *outmenu[] = {"/home/yigit/.scripts/dmenu-logout"};
static const char *bwmenu[] = {"/usr/bin/bwmenu", "--auto-lock", "-1"};
static const char *trackpad[] = {"/home/yigit/.scripts/toggle_touchpad.sh"};
static const char *screenshot[] = { "scrot","-d","3", "%Y-%m-%d-%s_$wx$h.jpg", "-e","xclip -selection clipboard -t image/jpg < $f; mv $f ~/Pictures/Screenshots/;dunstify -a 'SNAP' 'Email taken'", NULL };
static const char *windowshot[] = { "scrot", "-u", "-d","3", "%Y-%m-%d-%s_$wx$h.jpg", "-e","xclip -selection clipboard -t image/jpg < $f; mv $f ~/Pictures/Screenshots/;dunstify -a 'SNAP' 'Email taken'", NULL };
/* commands */
#include "movestack.c"
#include "shiftview.c"
static Key keys[] = {
/* modifier key function argument */
{ MODKEY, XK_d, spawn, {.v = dmenucmd } },
{ MODKEY, XK_p, spawn, {.v = bwmenu } },
{ MODKEY, XK_Return, spawn, {.v = termcmd } },
{ MODKEY, XK_b, togglebar, {0} },
{ MODKEY, XK_j, focusstack, {.i = +1 } },
{ MODKEY, XK_k, focusstack, {.i = -1 } },
{ MODKEY, XK_i, incnmaster, {.i = +1 } },
{ MODKEY, XK_s, incnmaster, {.i = -1 } },
{ MODKEY, XK_h, setmfact, {.f = -0.05} },
{ MODKEY, XK_l, setmfact, {.f = +0.05} },
{ MODKEY|ShiftMask, XK_Return, zoom, {0} },
{ MODKEY, XK_Tab, view, {0} },
{ MODKEY, XK_q, killclient, {0} },
{ MODKEY|ShiftMask, XK_j, movestack, {.i = +1 } }, /*Mover ventana hacia abajo*/
{ MODKEY|ShiftMask, XK_k, movestack, {.i = -1 } }, /*Mover ventana hacia arriba*/
{ MODKEY, XK_t, setlayout, {.v = &layouts[0]} }, /*tiled*/
{ MODKEY|Mod1Mask, XK_f, setlayout, {.v = &layouts[1]} }, /*Spiral*/
{ MODKEY|Mod1Mask, XK_g, setlayout, {.v = &layouts[2]} }, /*Grid*/
{ MODKEY|Mod1Mask, XK_c, setlayout, {.v = &layouts[3]} }, /*center*/
{ MODKEY, XK_m, setlayout, {.v = &layouts[5]} }, /*monocle*/
{ MODKEY|ShiftMask, XK_m, setlayout, {.v = &layouts[6]} }, /*Deck*/
{ MODKEY, XK_s, togglefloating, {0} }, /*float*/
{ MODKEY, XK_f, togglefullscr, {0} }, /*Fullscreen*/
{ MODKEY|Mod1Mask, XK_comma, cyclelayout, {.i = -1 } }, /*Ciclar layouts*/
{ MODKEY|Mod1Mask, XK_period, cyclelayout, {.i = +1 } }, /*Ciclar layouts*/
{ MODKEY, XK_a, view, {.ui = ~0 } },
{ MODKEY|ShiftMask, XK_a, tag, {.ui = ~0 } },
{ MODKEY, XK_comma, focusmon, {.i = -1 } },
{ MODKEY, XK_period, focusmon, {.i = +1 } },
{ MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } },
{ MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } },
/*Monitores*/
{ MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, /*Mandar ventana a monitor anterior*/
{ MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, /*Mandar ventana a monitor siguiente*/
TAGKEYS( XK_1, 0)
TAGKEYS( XK_2, 1)
TAGKEYS( XK_3, 2)
TAGKEYS( XK_4, 3)
TAGKEYS( XK_5, 4)
TAGKEYS( XK_6, 5)
TAGKEYS( XK_7, 6)
TAGKEYS( XK_8, 7)
TAGKEYS( XK_9, 8)
TAGKEYS( XK_0, 9)
{ MODKEY|ShiftMask, XK_q, spawn, {.v = outmenu} },
{ MODKEY|ShiftMask, XK_t, spawn, {.v = trackpad} },
{ MODKEY, XK_x, spawn, {.v = lock } },
{ MODKEY, XK_c, spawn, {.v = clipmenu } },
{ 0, XF86XK_AudioLowerVolume, spawn, {.v = downvol } },
{ 0, XF86XK_MonBrightnessUp, spawn, {.v = upbright } },
{ 0, XF86XK_MonBrightnessDown, spawn, {.v = downbright } },
{ 0, XF86XK_AudioMute, spawn, {.v = mutevol } },
{ 0, XF86XK_AudioRaiseVolume, spawn, {.v = upvol } },
{ 0, XF86XK_AudioPrev, spawn, {.v = prev } },
{ 0, XF86XK_AudioPlay, spawn, {.v = play } },
{ 0, XF86XK_AudioNext, spawn, {.v = next } },
{ 0, XK_Print, spawn, {.v = screenshot } },
{ MODKEY, XK_Print, spawn, {.v = windowshot } },
};
/* button definitions */
/* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */
static Button buttons[] = {
/* 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} },
{ ClkClientWin, MODKEY, Button2, togglefloating, {0} },
{ ClkClientWin, MODKEY, Button3, resizemouse, {0} },
{ ClkTagBar, 0, Button1, view, {0} },
{ ClkTagBar, 0, Button3, toggleview, {0} },
{ ClkTagBar, MODKEY, Button1, tag, {0} },
{ ClkTagBar, MODKEY, Button3, toggletag, {0} },
};
/*
static Button buttons[] = {
// click event mask button function argument
{ ClkLtSymbol, 0, Button1, cyclelayout, {.i = +1 } },
{ ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[5]} },
{ ClkWinTitle, 0, Button2, zoom, {0} },
{ ClkStatusText, 0, Button1, sigdwmblocks, {.i = 1} },
{ ClkStatusText, 0, Button2, sigdwmblocks, {.i = 2} },
{ ClkStatusText, 0, Button3, sigdwmblocks, {.i = 3} },
{ ClkClientWin, MODKEY, Button1, movemouse, {0} },
{ ClkClientWin, MODKEY, Button2, togglefloating, {0} },
{ ClkClientWin, MODKEY, Button3, resizemouse, {0} },
{ ClkTagBar, 0, Button1, view, {0} },
{ ClkTagBar, 0, Button3, toggleview, {0} },
{ ClkTagBar, MODKEY, Button1, tag, {0} },
{ ClkTagBar, MODKEY, Button3, toggletag, {0} },
{ ClkClientWin, 0, Button1, winview, {0} },
};
*/

+ 37
- 0
suckless/dwm/LICENSE View File

@ -0,0 +1,37 @@
MIT/X Consortium License
© 2006-2019 Anselm R Garbe <anselm@garbe.ca>
© 2006-2009 Jukka Salmi <jukka at salmi dot ch>
© 2006-2007 Sander van Dijk <a dot h dot vandijk at gmail dot com>
© 2007-2011 Peter Hartlich <sgkkr at hartlich dot com>
© 2007-2009 Szabolcs Nagy <nszabolcs at gmail dot com>
© 2007-2009 Christof Musik <christof at sendfax dot de>
© 2007-2009 Premysl Hruby <dfenze at gmail dot com>
© 2007-2008 Enno Gottox Boland <gottox at s01 dot de>
© 2008 Martin Hurton <martin dot hurton at gmail dot com>
© 2008 Neale Pickett <neale dot woozle dot org>
© 2009 Mate Nagy <mnagy at port70 dot net>
© 2010-2016 Hiltjo Posthuma <hiltjo@codemadness.org>
© 2010-2012 Connor Lane Smith <cls@lubutu.com>
© 2011 Christoph Lohmann <20h@r-36.net>
© 2015-2016 Quentin Rameau <quinq@fifth.space>
© 2015-2016 Eric Pruitt <eric.pruitt@gmail.com>
© 2016-2017 Markus Teich <markus.teich@stusta.mhn.de>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

+ 51
- 0
suckless/dwm/Makefile View File

@ -0,0 +1,51 @@
# dwm - dynamic window manager
# See LICENSE file for copyright and license details.
include config.mk
SRC = drw.c dwm.c util.c
OBJ = ${SRC:.c=.o}
all: options dwm
options:
@echo dwm build options:
@echo "CFLAGS = ${CFLAGS}"
@echo "LDFLAGS = ${LDFLAGS}"
@echo "CC = ${CC}"
.c.o:
${CC} -c ${CFLAGS} $<
${OBJ}: config.h config.mk
config.h:
cp config.def.h $@
dwm: ${OBJ}
${CC} -o $@ ${OBJ} ${LDFLAGS}
clean:
rm -f dwm ${OBJ} dwm-${VERSION}.tar.gz
dist: clean
mkdir -p dwm-${VERSION}
cp -R LICENSE Makefile README config.def.h config.mk\
dwm.1 drw.h util.h ${SRC} dwm.png transient.c dwm-${VERSION}
tar -cf dwm-${VERSION}.tar dwm-${VERSION}
gzip dwm-${VERSION}.tar
rm -rf dwm-${VERSION}
install: all
mkdir -p ${DESTDIR}${PREFIX}/bin
cp -f dwm ${DESTDIR}${PREFIX}/bin
chmod 755 ${DESTDIR}${PREFIX}/bin/dwm
mkdir -p ${DESTDIR}${MANPREFIX}/man1
sed "s/VERSION/${VERSION}/g" < dwm.1 > ${DESTDIR}${MANPREFIX}/man1/dwm.1
chmod 644 ${DESTDIR}${MANPREFIX}/man1/dwm.1
uninstall:
rm -f ${DESTDIR}${PREFIX}/bin/dwm\
${DESTDIR}${MANPREFIX}/man1/dwm.1
.PHONY: all options clean dist install uninstall

+ 50
- 0
suckless/dwm/Makefile.bak View File

@ -0,0 +1,50 @@
# dwm - dynamic window manager
# See LICENSE file for copyright and license details.
include config.mk
SRC = drw.c dwm.c util.c
OBJ = ${SRC:.c=.o}
all: options dwm
options:
@echo dwm build options:
@echo "CFLAGS = ${CFLAGS}"
@echo "LDFLAGS = ${LDFLAGS}"
@echo "CC = ${CC}"
.c.o:
${CC} -c ${CFLAGS} $<
${OBJ}: config.h config.mk
config.h:
cp config.def.h $@
dwm: ${OBJ}
${CC} -o $@ ${OBJ} ${LDFLAGS}
clean:
rm -f dwm ${OBJ} dwm-${VERSION}.tar.gz
dist: clean
mkdir -p dwm-${VERSION}
cp -R LICENSE Makefile README config.def.h config.mk\
dwm.1 drw.h util.h ${SRC} dwm.png transient.c dwm-${VERSION}
tar -cf dwm-${VERSION}.tar dwm-${VERSION}
gzip dwm-${VERSION}.tar
rm -rf dwm-${VERSION}
install: all
mkdir -p ~/.local
cp -f dwm ~/.local
chmod 755 ~/.local/dwm
# pkill dwm
# ~/.local/dwmblocks &
uninstall:
rm -f ${DESTDIR}${PREFIX}/bin/dwm\
${DESTDIR}${MANPREFIX}/man1/dwm.1
.PHONY: all options clean dist install uninstall

+ 32
- 0
suckless/dwm/README.es.org View File

@ -0,0 +1,32 @@
* Dynamic Window Manager
Este es mi propio build de DWM, con algunos parches y configuraciones.
*** Parches
**** Funcionales
Aquellos parches que añaden nuevas funciones a DWM, algunas de ellas son funciones sencillas que están presentes en otros TWM.
- [[https://dwm.suckless.org/patches/actualfullscreen/dwm-actualfullscreen-20191112-cb3f58a.diff][actualfullscreen:]] Permite activar verdadera pantalla completa en lugar de solo activar el modo monocle y esconder el panel.
- [[https://dwm.suckless.org/patches/alwayscenter/][alwayscenter]]: Las ventanas flotantes siempre se colocan al centro de la pantalla.
- [[https://dwm.suckless.org/patches/cyclelayouts/dwm-cyclelayouts-20180524-6.2.diff][cyclelayouts:]] Pasa por la lista de layouts con una combinación de botones.
- [[https://dwm.suckless.org/patches/inplacerotate/][inplacerotate]]: Permite rotar las ventanas en el stack sin cambiar master.
- [[https://dwm.suckless.org/patches/movestack/dwm-movestack-6.1.diff][movestack:]] Permite mover las ventanas en la parte stack, cuando se usa el esquema por defecto.
- [[https://dwm.suckless.org/patches/pertag/dwm-pertag-20170513-ceac8c9.diff][pertag:]] Por defecto, dwm usa el mismo esquema para todos los tags. Con este parche cada tag tiene un esquema diferente (el esquema inicial es tile).
- [[https://dwm.suckless.org/patches/switchcol/][switchcol:]] Permite cambiar el foco entre master y stack con un solo /keybinding/. Útil con el layout /deck/.
- [[https://dwm.suckless.org/patches/winview/][winview]]: Si están viendo varios tags a la vez, al presionar un /keybinding/ se cambia al tag de la ventana enfocada.
**** Layouts
Son aquellas /layouts/ nuevas que he agregado a DWM.
- [[https://dwm.suckless.org/patches/centeredmaster/][centeredmaster:]] La ventana /master/ se coloca en el centro mientras las otras aparecen en rejilla alrededor.
- [[https://dwm.suckless.org/patches/deck/][deck:]] La parte /stack/ solo muestra una ventana a la vez. Si se usa con /inplacerotate/ es posible cambiar la ventana en el /stack/ sin mover /master/.
- [[https://dwm.suckless.org/patches/fibonacci/dwm-fibonacci-5.8.2.diff][fibonacci:]] Dos esquemas nuevos: spiral y dwindle (à la bspwm).
- [[https://dwm.suckless.org/patches/gridmode/dwm-gridmode-20170909-ceac8c9.diff][gridmode:]] Esquema de rejilla para.
- [[https://dwm.suckless.org/patches/rmaster/dwm-rmaster-6.1.diff][rmaster:]] Permite invertir el orden del esquema tile: master a la izquierda y stack a la derecha.
**** Estéticos
Parches que unicamente sirven para mejorar el aspecto estético del WM y aportan poco o nada al aspecto funcional.
- [[https://dwm.suckless.org/patches/alttagsdecoration/][alttagsdecoration]]: Permite declarar íconos diferentes para cada tag cuando están ocupados.
- [[https://dwm.suckless.org/patches/colorbar/][colorbar]]: Añade esquemas de colores nuevos para cada sección del panel.
- [[https://github.com/ashish-yadav11/dwmblocks][dwmblocks]]: Agrega soporte para texto coloreado y poder presionar en los módulos.
- [[https://dwm.suckless.org/patches/alpha/dwm-fixborders-6.2.diff][fixborders]]: Arregla los bordes transparentes cuando se usa compton/picom.
- [[https://dwm.suckless.org/patches/uselessgap/dwm-uselessgap-6.2.diff][uselessgap:]] Añade separaciones inútiles entre ventanas. Apesar de no ser el único parche, si es el más sencillo de aplicar.

+ 35
- 0
suckless/dwm/README.org View File

@ -0,0 +1,35 @@
#+TITLE:DWM: Dynamic Window Manager
This is my own build of DWM with some patches and configurations.
*** Patches
**** Feature related
Those patches that add new features to DWM, some of them are simple features that are present in other TWMs.
- [[https://dwm.suckless.org/patches/actualfullscreen/dwm-actualfullscreen-20191112-cb3f58a.diff][actualfullscreen:]] Allows to activate true fullscreen instead of just change to monocle layout and hide the bar.
- [[https://dwm.suckless.org/patches/alwayscenter/][alwayscenter]]: Floating windows are always placed at the center of the screen.
- [[https://dwm.suckless.org/patches/cyclelayouts/dwm-cyclelayouts-20180524-6.2.diff][cyclelayouts:]] Go through the layout list with a button combination.
- [[https://dwm.suckless.org/patches/inplacerotate/][inplacerotate]]: Allows to rotate the windows in the stack without changing master.
- [[https://dwm.suckless.org/patches/movestack/dwm-movestack-6.1.diff][movestack:]] Allows to move the windows in the stack part, when using the default layout.
- [[https://dwm.suckless.org/patches/pertag/dwm-pertag-20170513-ceac8c9.diff][pertag:]] By default, dwm uses the same layout for all tags. With this patch each tag has a different layout (the initial scheme is tile).
- [[https://dwm.suckless.org/patches/switchcol/][switchcol:]] It allows to change the focus between master and stack with a single keybinding. Useful with the /deck/ layout.
- [[https://dwm.suckless.org/patches/winview/][winview]]: If you are seeing several tags at once, pressing a keybinding switches to the tag in the focused window.
**** Layouts
New layout I've added to DWM.
- [[https://dwm.suckless.org/patches/centeredmaster/][centeredmaster:]] The /master/ window is placed in the center while the others appear in a grid around it.
- [[https://dwm.suckless.org/patches/deck/][deck:]] The /stack/ part only shows one window at a time. If used with /inplacerotate/ it is possible to change the window in /stack/ without moving /master/.
- [[https://dwm.suckless.org/patches/fibonacci/dwm-fibonacci-5.8.2.diff][fibonacci:]] Two new layouts: spiral y dwindle (à la bspwm).
- [[https://dwm.suckless.org/patches/gridmode/dwm-gridmode-20170909-ceac8c9.diff][gridmode:]] Grid layout.
- [[https://dwm.suckless.org/patches/rmaster/dwm-rmaster-6.1.diff][rmaster:]] Allows to reverse the order of the tile scheme: master on the left and stack on the right.
**** Aesthetic related
Patches that only serve to improve the aesthetic aspect of the WM and contribute little or nothing to the functional aspect.
- [[https://dwm.suckless.org/patches/alttagsdecoration/][alttagsdecoration]]: Allows you to declare different icons for each tag when they are busy.
- [[https://dwm.suckless.org/patches/barpadding/][barpadding:]] Add vertical andhorizontal padding to the bar from the screen.
- [[https://dwm.suckless.org/patches/colorbar/][colorbar]]: Add new color schemes for each section of the panel.
- [[https://github.com/ashish-yadav11/dwmblocks][dwmblocks]]: Add support for colored text and click on the dwmblocks modules.
- [[https://dwm.suckless.org/patches/alpha/dwm-fixborders-6.2.diff][fixborders]]: Fix the transparent borders when using compton/picom.
- [[https://dwm.suckless.org/patches/uselessgap/dwm-uselessgap-6.2.diff][uselessgap:]] Add useless gaps between windows. Although it is not the only patch, it is the easiest to apply.

+ 262
- 0
suckless/dwm/config.h View File

@ -0,0 +1,262 @@
/* See LICENSE file for copyright and license details. */
#include <X11/XF86keysym.h>
/* appearance */
static const unsigned int borderpx = 3; /* border pixel of windows */
static const unsigned int gappx = 6;
static const unsigned int snap = 32; /* snap pixel */
static const int rmaster = 0; /* 1 = master at right*/
static const int showbar = 1; /* 0 means no bar */
static const unsigned int systraypinning = 0; /* 0: sloppy systray follows selected monitor, >0: pin systray to monitor X */
static const unsigned int systrayspacing = 2; /* systray spacing */
static const int systraypinningfailfirst = 1; /* 1: if pinning fails, display systray on the first monitor, False: display systray on the last monitor*/
static const int showsystray = 1; /* 0 means no systray */
static const int topbar = 1; /* 0 means bottom bar */
static const int user_bh = 27; /* 0 means that dwm will calculate bar height, >= 1 means dwm will user_bh as bar height */
static const int tag_padding = 0;
static const int vertpad = 0; /* vertical padding of bar */
static const int sidepad = 0; /* horizontal padding of bar */
static const char *fonts[] = {"Hack Nerd Font:Regular:size=10", "Material Design Icons:Regular:pixelsize=16:antialias=true"};
static const char dmenufont[] = "Hack Nerd Font:size=10";
static const char fore[] = "#f8f8f2";
static const char back[] = "#282a36";
static const char border[] = "#f8f8f2";
static const char col0[] = "#000000";
static const char col1[] = "#FF5555";
static const char col2[] = "#50FA7B";
static const char col3[] = "#F1FA8C";
static const char col4[] = "#BD93F9";
static const char col5[] = "#FF79C6";
static const char col6[] = "#8BE9FD";
static const char col7[] = "#BFBFBF";
static const char col8[] = "#4D4D4D";
static const char col9[] = "#FF6E67";
static const char col10[] = "#5AF78E";
static const char col11[] = "#F4F99D";
static const char col12[] = "#CAA9FA";
static const char col13[] = "#FF92D0";
static const char col14[] = "#9AEDFE";
static const char col15[] = "#E6E6E6";
static const char spotify[]= "#1FC167";
static const char *colors[][3] = {
/* fg bg border */
[SchemeNorm] = { fore, back, back }, // \x0b
[SchemeSel] = { fore, back, border }, // \x0c
[SchemeStatus] = { fore, back, border }, // \x0d Statusbar right
[SchemeTagsSel] = { col4, back, border }, // \x0e Tagbar left selected
[SchemeTagsNorm] = { fore, back, border }, // \x0f Tagbar left unselected
[SchemeInfoSel] = { fore, back, border }, // \x10 infobar middle selected
[SchemeInfoNorm] = { fore, back, border }, // \x11 infobar middle unselected
[SchemeCol1] = { col1, back, col0 }, // \x12
[SchemeCol2] = { col2, back, col0 }, // \x13
[SchemeCol3] = { col3, back, col0 }, // \x14
[SchemeCol4] = { col4, back, col0 }, // \x15
[SchemeCol5] = { col5, back, col0 }, // \x16
[SchemeCol6] = { col6, back, col0 }, // \x17
[SchemeCol7] = { col7, back, col0 }, // \x18
[SchemeCol8] = { col8, back, col0 }, // \x19
[SchemeCol9] = { col9, back, col0 }, // \x1a
[SchemeCol10] = { col10, back, col0 }, // \x1b
[SchemeCol11] = { col11, back, col0 }, // \x1c
[SchemeCol12] = { spotify, back, col0 }, // \x1d Spotify
};
/* tagging */
static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "0"};
//static const char *alttags[] = { "󰄯", "󰄯", "󰄯", "󰄯"};
static const Rule rules[] = {
/* xprop(1):
* WM_CLASS(STRING) = instance, class
* WM_NAME(STRING) = title
*/
/* class instance title tags mask isfloating monitor */
{ "discord", NULL, NULL, 1 << 8, 0, -1 },
{ "mailspring", NULL, NULL, 1 << 8, 0, -1 },
{ "Termite", NULL, NULL, 1 << 0, 0, -1 },
{ "firefoxdeveloperedition", NULL, NULL, 1 << 1, 0, -1 },
{ "Tor Browser", NULL, NULL, 1 << 1, 0, -1 },
{ "Chromium", NULL, NULL, 1 << 1, 0, -1 },
// { "zoom", NULL, NULL, 1 << 4, 0, -1 },
{ "TelegramDesktop", NULL, NULL, 1 << 8, 0, -1 },
{ "whatsapp-nativefier-d52542", NULL, NULL, 1 << 8, 0, -1 },
{ "neomutt", NULL, NULL, 1 << 7, 0, -1 },
{ "Sublime_Text", NULL, NULL, 1 << 2, 0, -1 },
{ "code-oss", NULL, NULL, 1 << 2, 0, -1 },
{ "jetbrains-idea", NULL, NULL, 1 << 2, 0, -1 },
{ "Nemo", NULL, NULL, 1 << 3, 0, -1 },
{ "Spotify", NULL, NULL, 1 << 9, 0, -1 },
};
/* layout(s) */
static const float mfact = 0.5; /* factor of master area size [0.05..0.95] */
static const int nmaster = 1; /* number of clients in master area */
static const int resizehints = 0; /* 1 means respect size hints in tiled resizals */
#include "fibonacci.c"
#include "layouts.c"
static const Layout layouts[] = {
/* symbol arrange function */
{ "", tile }, /* first entry is default */
{ "", dwindle },
{ "", grid },
{ "", centeredmaster },
{ "", centeredfloatingmaster },
{ "[M]", monocle },
{ "[D]", deck },
{ NULL, NULL },
};
/* key definitions */
#define MODKEY Mod4Mask
#define TAGKEYS(KEY,TAG) \
{ MODKEY, KEY, view, {.ui = 1 << TAG} }, \
{ MODKEY|Mod1Mask, KEY, toggleview, {.ui = 1 << TAG} }, \
{ MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \
{ MODKEY|ControlMask, KEY, toggletag, {.ui = 1 << TAG} },
/* COSAS QUE TENGO QUE AVERIGUAR COMO QUITAR */
/* helper for spawning shell commands in the pre dwm-5.0 fashion */
#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */
static const char *dmenucmd[] = { "/usr/bin/rofi","-show","drun", NULL };
static const char *termcmd[] = { "/usr/bin/termite", "--title", "Terminal", NULL };
static const char *upvol[] = { "/usr/bin/pactl", "set-sink-volume", "0", "+5%", NULL };
static const char *downvol[] = { "/usr/bin/pactl", "set-sink-volume", "0", "-5%", NULL };
static const char *mutevol[] = { "/usr/bin/pactl", "set-sink-mute", "0", "toggle", NULL };
static const char *upbright[] = {"/usr/bin/xbacklight","-inc","10",NULL};
static const char *downbright[] = {"/usr/bin/xbacklight","-dec","10",NULL};
static const char *lock[] = {"/usr/bin/betterlockscreen","-l","-t","Stay the fuck out!",NULL};
static const char *clipmenu[] = {"/usr/bin/clipmenu","-i",NULL};
static const char *play[] = {"/usr/bin/playerctl","play-pause",NULL};
static const char *prev[] = {"/usr/bin/playerctl","previous",NULL};
static const char *next[] = {"/usr/bin/playerctl","next",NULL};
static const char *outmenu[] = {"/home/yigit/.scripts/dmenu-logout"};
static const char *notification_off[] = {"/home/yigit/.scripts/dunst_toggle.sh","-s",NULL};
static const char *notification_on[] = {"/home/yigit/.scripts/dunst_toggle.sh", "-e",NULL};
static const char *bwmenu[] = {"/usr/bin/bwmenu", "--auto-lock", "-1", NULL};
static const char *trackpad[] = {"/home/yigit/.scripts/toggle_touchpad.sh"};
static const char *kdeconnect[] = {"/home/yigit/.local/bin/dmenu_kdeconnect.sh", NULL};
static const char *bluetooth[] = {"/usr/bin/rofi-bluetooth", NULL};
static const char *screenshot[] = { "scrot","-d","3", "%Y-%m-%d-%s_$wx$h.jpg", "-e","xclip -selection clipboard -t image/jpg < $f; mv $f ~/Pictures/Screenshots/;dunstify --icon='/home/yigit/.icons/Numix-Circle/48/apps/camera.svg' -a 'SNAP' 'Screenshot taken'", NULL };
static const char *windowshot[] = { "scrot", "-u", "-d","3", "%Y-%m-%d-%s_$wx$h.jpg", "-e","xclip -selection clipboard -t image/jpg < $f; mv $f ~/Pictures/Screenshots/;dunstify --icon='/home/yigit/.icons/Numix-Circle/48/apps/camera.svg' -a 'SNAP' 'Screenshot taken'", NULL };
/* commands */
#include "movestack.c"
#include "shiftview.c"
static Key keys[] = {
/* modifier key function argument */
{ MODKEY, XK_d, spawn, {.v = dmenucmd } },
{ MODKEY, XK_p, spawn, {.v = bwmenu } },
{ MODKEY, XK_Return, spawn, {.v = termcmd } },
{ MODKEY, XK_b, togglebar, {0} },
{ MODKEY, XK_j, focusstack, {.i = +1 } },
{ MODKEY, XK_n, spawn, {.v = notification_off} },
{ MODKEY|ShiftMask, XK_n, spawn, {.v = notification_on } },
{ MODKEY, XK_k, focusstack, {.i = -1 } },
{ MODKEY, XK_i, incnmaster, {.i = +1 } },
{ MODKEY, XK_s, incnmaster, {.i = -1 } },
{ MODKEY, XK_h, setmfact, {.f = -0.05} },
{ MODKEY, XK_l, setmfact, {.f = +0.05} },
{ MODKEY|ShiftMask, XK_Return, zoom, {0} },
{ MODKEY, XK_Tab, view, {0} },
{ MODKEY, XK_q, killclient, {0} },
{ MODKEY|ShiftMask, XK_j, movestack, {.i = +1 } }, /*Mover ventana hacia abajo*/
{ MODKEY|ShiftMask, XK_k, movestack, {.i = -1 } }, /*Mover ventana hacia arriba*/
{ MODKEY, XK_t, setlayout, {.v = &layouts[0]} }, /*tiled*/
{ MODKEY|Mod1Mask, XK_f, setlayout, {.v = &layouts[1]} }, /*Spiral*/
{ MODKEY|Mod1Mask, XK_g, setlayout, {.v = &layouts[2]} }, /*Grid*/
{ MODKEY|Mod1Mask, XK_c, setlayout, {.v = &layouts[3]} }, /*center*/
{ MODKEY, XK_m, setlayout, {.v = &layouts[5]} }, /*monocle*/
{ MODKEY|ShiftMask, XK_m, setlayout, {.v = &layouts[6]} }, /*Deck*/
{ MODKEY, XK_s, togglefloating, {0} }, /*float*/
{ MODKEY, XK_f, togglefullscr, {0} }, /*Fullscreen*/
{ MODKEY|Mod1Mask, XK_comma, cyclelayout, {.i = -1 } }, /*Ciclar layouts*/
{ MODKEY|Mod1Mask, XK_period, cyclelayout, {.i = +1 } }, /*Ciclar layouts*/
{ MODKEY, XK_a, view, {.ui = ~0 } },
{ MODKEY|ShiftMask, XK_a, tag, {.ui = ~0 } },
{ MODKEY, XK_comma, focusmon, {.i = -1 } },
{ MODKEY, XK_period, focusmon, {.i = +1 } },
{ MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } },
{ MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } },
/*Monitores*/
{ MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, /*Mandar ventana a monitor anterior*/
{ MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, /*Mandar ventana a monitor siguiente*/
TAGKEYS( XK_1, 0)
TAGKEYS( XK_2, 1)
TAGKEYS( XK_3, 2)
TAGKEYS( XK_4, 3)
TAGKEYS( XK_5, 4)
TAGKEYS( XK_6, 5)
TAGKEYS( XK_7, 6)
TAGKEYS( XK_8, 7)
TAGKEYS( XK_9, 8)
TAGKEYS( XK_0, 9)
{ MODKEY|ShiftMask, XK_q, spawn, {.v = outmenu} },
{ MODKEY|ShiftMask, XK_t, spawn, {.v = trackpad} },
{ MODKEY, XK_x, spawn, {.v = lock } },
{ MODKEY, XK_c, spawn, {.v = clipmenu } },
{ MODKEY|ShiftMask, XK_p, spawn, {.v = kdeconnect } },
{ MODKEY|ShiftMask, XK_b, spawn, {.v = bluetooth } },
{ 0, XF86XK_AudioLowerVolume, spawn, {.v = downvol } },
{ 0, XF86XK_MonBrightnessUp, spawn, {.v = upbright } },
{ 0, XF86XK_MonBrightnessDown, spawn, {.v = downbright } },
{ 0, XF86XK_AudioMute, spawn, {.v = mutevol } },
{ 0, XF86XK_AudioRaiseVolume, spawn, {.v = upvol } },
{ 0, XF86XK_AudioPrev, spawn, {.v = prev } },
{ 0, XF86XK_AudioPlay, spawn, {.v = play } },
{ 0, XF86XK_AudioNext, spawn, {.v = next } },
{ 0, XK_Print, spawn, {.v = screenshot } },
{ MODKEY, XK_Print, spawn, {.v = windowshot } },
};
/* button definitions */
/* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */
static Button buttons[] = {
/* 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} },
{ ClkClientWin, MODKEY, Button2, togglefloating, {0} },
{ ClkClientWin, MODKEY, Button3, resizemouse, {0} },
{ ClkTagBar, 0, Button1, view, {0} },
{ ClkTagBar, 0, Button3, toggleview, {0} },
{ ClkTagBar, MODKEY, Button1, tag, {0} },
{ ClkTagBar, MODKEY, Button3, toggletag, {0} },
};
/*
static Button buttons[] = {
// click event mask button function argument
{ ClkLtSymbol, 0, Button1, cyclelayout, {.i = +1 } },
{ ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[5]} },
{ ClkWinTitle, 0, Button2, zoom, {0} },
{ ClkStatusText, 0, Button1, sigdwmblocks, {.i = 1} },
{ ClkStatusText, 0, Button2, sigdwmblocks, {.i = 2} },
{ ClkStatusText, 0, Button3, sigdwmblocks, {.i = 3} },
{ ClkClientWin, MODKEY, Button1, movemouse, {0} },
{ ClkClientWin, MODKEY, Button2, togglefloating, {0} },
{ ClkClientWin, MODKEY, Button3, resizemouse, {0} },
{ ClkTagBar, 0, Button1, view, {0} },
{ ClkTagBar, 0, Button3, toggleview, {0} },
{ ClkTagBar, MODKEY, Button1, tag, {0} },
{ ClkTagBar, MODKEY, Button3, toggletag, {0} },
{ ClkClientWin, 0, Button1, winview, {0} },
};
*/

+ 38
- 0
suckless/dwm/config.mk View File

@ -0,0 +1,38 @@
# dwm version
VERSION = 6.2
# Customize below to fit your system
# paths
PREFIX = /usr/local
MANPREFIX = ${PREFIX}/share/man
X11INC = /usr/X11R6/include
X11LIB = /usr/X11R6/lib
# Xinerama, comment if you don't want it
XINERAMALIBS = -lXinerama
XINERAMAFLAGS = -DXINERAMA
# freetype
FREETYPELIBS = -lfontconfig -lXft
FREETYPEINC = /usr/include/freetype2
# OpenBSD (uncomment)
#FREETYPEINC = ${X11INC}/freetype2
# includes and libs
INCS = -I${X11INC} -I${FREETYPEINC}
LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS}
# flags
CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
#CFLAGS = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS}
CFLAGS = -std=c99 -pedantic -Wall -Wno-deprecated-declarations -Os ${INCS} ${CPPFLAGS}
LDFLAGS = ${LIBS}
# Solaris
#CFLAGS = -fast ${INCS} -DVERSION=\"${VERSION}\"
#LDFLAGS = ${LIBS}
# compiler and linker
CC = cc

+ 438
- 0
suckless/dwm/drw.c View File

@ -0,0 +1,438 @@
/* See LICENSE file for copyright and license details. */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <X11/Xlib.h>
#include <X11/Xft/Xft.h>
#include "drw.h"
#include "util.h"
#define UTF_INVALID 0xFFFD
#define UTF_SIZ 4
static const unsigned char utfbyte[UTF_SIZ + 1] = {0x80, 0, 0xC0, 0xE0, 0xF0};
static const unsigned char utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8};
static const long utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000};
static const long utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF};
static long
utf8decodebyte(const char c, size_t *i)
{
for (*i = 0; *i < (UTF_SIZ + 1); ++(*i))
if (((unsigned char)c & utfmask[*i]) == utfbyte[*i])
return (unsigned char)c & ~utfmask[*i];
return 0;
}
static size_t
utf8validate(long *u, size_t i)
{
if (!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF))
*u = UTF_INVALID;
for (i = 1; *u > utfmax[i]; ++i)
;
return i;
}
static size_t
utf8decode(const char *c, long *u, size_t clen)
{
size_t i, j, len, type;
long udecoded;
*u = UTF_INVALID;
if (!clen)
return 0;
udecoded = utf8decodebyte(c[0], &len);
if (!BETWEEN(len, 1, UTF_SIZ))
return 1;
for (i = 1, j = 1; i < clen && j < len; ++i, ++j) {
udecoded = (udecoded << 6) | utf8decodebyte(c[i], &type);
if (type)
return j;
}
if (j < len)
return 0;
*u = udecoded;
utf8validate(u, len);
return len;
}
Drw *
drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h)
{
Drw *drw = ecalloc(1, sizeof(Drw));
drw->dpy = dpy;
drw->screen = screen;
drw->root = root;
drw->w = w;
drw->h = h;
drw->drawable = XCreatePixmap(dpy, root, w, h, DefaultDepth(dpy, screen));
drw->gc = XCreateGC(dpy, root, 0, NULL);
XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter);
return drw;
}
void
drw_resize(Drw *drw, unsigned int w, unsigned int h)
{
if (!drw)
return;
drw->w = w;
drw->h = h;
if (drw->drawable)
XFreePixmap(drw->dpy, drw->drawable);
drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, DefaultDepth(drw->dpy, drw->screen));
}
void
drw_free(Drw *drw)
{
XFreePixmap(drw->dpy, drw->drawable);
XFreeGC(drw->dpy, drw->gc);
drw_fontset_free(drw->fonts);
free(drw);
}
/* This function is an implementation detail. Library users should use
* drw_fontset_create instead.
*/
static Fnt *
xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern)
{
Fnt *font;
XftFont *xfont = NULL;
FcPattern *pattern = NULL;
if (fontname) {
/* Using the pattern found at font->xfont->pattern does not yield the
* same substitution results as using the pattern returned by
* FcNameParse; using the latter results in the desired fallback
* behaviour whereas the former just results in missing-character
* rectangles being drawn, at least with some fonts. */
if (!(xfont = XftFontOpenName(drw->dpy, drw->screen, fontname))) {
fprintf(stderr, "error, cannot load font from name: '%s'\n", fontname);
return NULL;
}
if (!(pattern = FcNameParse((FcChar8 *) fontname))) {
fprintf(stderr, "error, cannot parse font name to pattern: '%s'\n", fontname);
XftFontClose(drw->dpy, xfont);
return NULL;
}
} else if (fontpattern) {
if (!(xfont = XftFontOpenPattern(drw->dpy, fontpattern))) {
fprintf(stderr, "error, cannot load font from pattern.\n");
return NULL;
}
} else {
die("no font specified.");
}
/* Do not allow using color fonts. This is a workaround for a BadLength
* error from Xft with color glyphs. Modelled on the Xterm workaround. See
* https://bugzilla.redhat.com/show_bug.cgi?id=1498269
* https://lists.suckless.org/dev/1701/30932.html
* https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=916349
* and lots more all over the internet.
*/
FcBool iscol;
if(FcPatternGetBool(xfont->pattern, FC_COLOR, 0, &iscol) == FcResultMatch && iscol) {
XftFontClose(drw->dpy, xfont);
return NULL;
}
font = ecalloc(1, sizeof(Fnt));
font->xfont = xfont;
font->pattern = pattern;
font->h = xfont->ascent + xfont->descent;
font->dpy = drw->dpy;
return font;
}
static void
xfont_free(Fnt *font)
{
if (!font)
return;
if (font->pattern)
FcPatternDestroy(font->pattern);
XftFontClose(font->dpy, font->xfont);
free(font);
}
Fnt*
drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount)
{
Fnt *cur, *ret = NULL;
size_t i;
if (!drw || !fonts)
return NULL;
for (i = 1; i <= fontcount; i++) {
if ((cur = xfont_create(drw, fonts[fontcount - i], NULL))) {
cur->next = ret;
ret = cur;
}
}
return (drw->fonts = ret);
}
void
drw_fontset_free(Fnt *font)
{
if (font) {
drw_fontset_free(font->next);
xfont_free(font);
}
}
void
drw_clr_create(Drw *drw, Clr *dest, const char *clrname)
{
if (!drw || !dest || !clrname)
return;
if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen),
DefaultColormap(drw->dpy, drw->screen),
clrname, dest))
die("error, cannot allocate color '%s'", clrname);
dest->pixel |= 0xff << 24;
}
/* Wrapper to create color schemes. The caller has to call free(3) on the
* returned color scheme when done using it. */
Clr *
drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount)
{
size_t i;
Clr *ret;
/* need at least two colors for a scheme */
if (!drw || !clrnames || clrcount < 2 || !(ret = ecalloc(clrcount, sizeof(XftColor))))
return NULL;
for (i = 0; i < clrcount; i++)
drw_clr_create(drw, &ret[i], clrnames[i]);
return ret;
}
void
drw_setfontset(Drw *drw, Fnt *set)
{
if (drw)
drw->fonts = set;
}
void
drw_setscheme(Drw *drw, Clr *scm)
{
if (drw)
drw->scheme = scm;
}
void
drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert)
{
if (!drw || !drw->scheme)
return;
XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme[ColBg].pixel : drw->scheme[ColFg].pixel);
if (filled)
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
else
XDrawRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w - 1, h - 1);
}
int
drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert)
{
char buf[1024];
int ty;
unsigned int ew;
XftDraw *d = NULL;
Fnt *usedfont, *curfont, *nextfont;
size_t i, len;
int utf8strlen, utf8charlen, render = x || y || w || h;
long utf8codepoint = 0;
const char *utf8str;
FcCharSet *fccharset;
FcPattern *fcpattern;
FcPattern *match;
XftResult result;
int charexists = 0;
if (!drw || (render && !drw->scheme) || !text || !drw->fonts)
return 0;
if (!render) {
w = ~w;
} else {
XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel);
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
d = XftDrawCreate(drw->dpy, drw->drawable,
DefaultVisual(drw->dpy, drw->screen),
DefaultColormap(drw->dpy, drw->screen));
x += lpad;
w -= lpad;
}
usedfont = drw->fonts;
while (1) {
utf8strlen = 0;
utf8str = text;
nextfont = NULL;
while (*text) {
utf8charlen = utf8decode(text, &utf8codepoint, UTF_SIZ);
for (curfont = drw->fonts; curfont; curfont = curfont->next) {
charexists = charexists || XftCharExists(drw->dpy, curfont->xfont, utf8codepoint);
if (charexists) {
if (curfont == usedfont) {
utf8strlen += utf8charlen;
text += utf8charlen;
} else {
nextfont = curfont;
}
break;
}
}
if (!charexists || nextfont)
break;
else
charexists = 0;
}
if (utf8strlen) {
drw_font_getexts(usedfont, utf8str, utf8strlen, &ew, NULL);
/* shorten text if necessary */
for (len = MIN(utf8strlen, sizeof(buf) - 1); len && ew > w; len--)
drw_font_getexts(usedfont, utf8str, len, &ew, NULL);
if (len) {
memcpy(buf, utf8str, len);
buf[len] = '\0';
if (len < utf8strlen)
for (i = len; i && i > len - 3; buf[--i] = '.')
; /* NOP */
if (render) {
ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent;
XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg],
usedfont->xfont, x, ty, (XftChar8 *)buf, len);
}
x += ew;
w -= ew;
}
}
if (!*text) {
break;
} else if (nextfont) {
charexists = 0;
usedfont = nextfont;
} else {
/* Regardless of whether or not a fallback font is found, the
* character must be drawn. */
charexists = 1;
fccharset = FcCharSetCreate();
FcCharSetAddChar(fccharset, utf8codepoint);
if (!drw->fonts->pattern) {
/* Refer to the comment in xfont_create for more information. */
die("the first font in the cache must be loaded from a font string.");
}
fcpattern = FcPatternDuplicate(drw->fonts->pattern);
FcPatternAddCharSet(fcpattern, FC_CHARSET, fccharset);
FcPatternAddBool(fcpattern, FC_SCALABLE, FcTrue);
FcPatternAddBool(fcpattern, FC_COLOR, FcFalse);
FcConfigSubstitute(NULL, fcpattern, FcMatchPattern);
FcDefaultSubstitute(fcpattern);
match = XftFontMatch(drw->dpy, drw->screen, fcpattern, &result);
FcCharSetDestroy(fccharset);
FcPatternDestroy(fcpattern);
if (match) {
usedfont = xfont_create(drw, NULL, match);
if (usedfont && XftCharExists(drw->dpy, usedfont->xfont, utf8codepoint)) {
for (curfont = drw->fonts; curfont->next; curfont = curfont->next)
; /* NOP */
curfont->next = usedfont;
} else {
xfont_free(usedfont);
usedfont = drw->fonts;
}
}
}
}
if (d)
XftDrawDestroy(d);
return x + (render ? w : 0);
}
void
drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h)
{
if (!drw)
return;
XCopyArea(drw->dpy, drw->drawable, win, drw->gc, x, y, w, h, x, y);
XSync(drw->dpy, False);
}
unsigned int
drw_fontset_getwidth(Drw *drw, const char *text)
{
if (!drw || !drw->fonts || !text)
return 0;
return drw_text(drw, 0, 0, 0, 0, 0, text, 0);
}
void
drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h)
{
XGlyphInfo ext;
if (!font || !text)
return;
XftTextExtentsUtf8(font->dpy, font->xfont, (XftChar8 *)text, len, &ext);
if (w)
*w = ext.xOff;
if (h)
*h = font->h;
}
Cur *
drw_cur_create(Drw *drw, int shape)
{
Cur *cur;
if (!drw || !(cur = ecalloc(1, sizeof(Cur))))
return NULL;
cur->cursor = XCreateFontCursor(drw->dpy, shape);
return cur;
}
void
drw_cur_free(Drw *drw, Cur *cursor)
{
if (!cursor)
return;
XFreeCursor(drw->dpy, cursor->cursor);
free(cursor);
}

+ 57
- 0
suckless/dwm/drw.h View File

@ -0,0 +1,57 @@
/* See LICENSE file for copyright and license details. */
typedef struct {
Cursor cursor;
} Cur;
typedef struct Fnt {
Display *dpy;
unsigned int h;
XftFont *xfont;
FcPattern *pattern;
struct Fnt *next;
} Fnt;
enum { ColFg, ColBg, ColBorder }; /* Clr scheme index */
typedef XftColor Clr;
typedef struct {
unsigned int w, h;
Display *dpy;
int screen;
Window root;
Drawable drawable;
GC gc;
Clr *scheme;
Fnt *fonts;
} Drw;
/* Drawable abstraction */
Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h);
void drw_resize(Drw *drw, unsigned int w, unsigned int h);
void drw_free(Drw *drw);
/* Fnt abstraction */
Fnt *drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount);
void drw_fontset_free(Fnt* set);
unsigned int drw_fontset_getwidth(Drw *drw, const char *text);
void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h);
/* Colorscheme abstraction */
void drw_clr_create(Drw *drw, Clr *dest, const char *clrname);
Clr *drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount);
/* Cursor abstraction */
Cur *drw_cur_create(Drw *drw, int shape);
void drw_cur_free(Drw *drw, Cur *cursor);
/* Drawing context manipulation */
void drw_setfontset(Drw *drw, Fnt *set);
void drw_setscheme(Drw *drw, Clr *scm);
/* Drawing functions */
void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert);
int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert);
/* Map functions */
void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h);

+ 727
- 0
suckless/dwm/dwm-systray-20200914-61bb8b2.diff View File

@ -0,0 +1,727 @@
diff --git a/config.def.h b/config.def.h
index 1c0b587..2d824d1 100644
--- a/config.def.h
+++ b/config.def.h
@@ -3,6 +3,10 @@
/* appearance */
static const unsigned int borderpx = 1; /* border pixel of windows */
static const unsigned int snap = 32; /* snap pixel */
+static const unsigned int systraypinning = 0; /* 0: sloppy systray follows selected monitor, >0: pin systray to monitor X */
+static const unsigned int systrayspacing = 2; /* systray spacing */
+static const int systraypinningfailfirst = 1; /* 1: if pinning fails, display systray on the first monitor, False: display systray on the last monitor*/
+static const int showsystray = 1; /* 0 means no systray */
static const int showbar = 1; /* 0 means no bar */
static const int topbar = 1; /* 0 means bottom bar */
static const char *fonts[] = { "monospace:size=10" };
diff --git a/dwm.c b/dwm.c
index 664c527..abce13d 100644
--- a/dwm.c
+++ b/dwm.c
@@ -57,12 +57,30 @@
#define TAGMASK ((1 << LENGTH(tags)) - 1)
#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad)
+#define SYSTEM_TRAY_REQUEST_DOCK 0
+
+/* XEMBED messages */
+#define XEMBED_EMBEDDED_NOTIFY 0
+#define XEMBED_WINDOW_ACTIVATE 1
+#define XEMBED_FOCUS_IN 4
+#define XEMBED_MODALITY_ON 10
+
+#define XEMBED_MAPPED (1 << 0)
+#define XEMBED_WINDOW_ACTIVATE 1
+#define XEMBED_WINDOW_DEACTIVATE 2
+
+#define VERSION_MAJOR 0
+#define VERSION_MINOR 0
+#define XEMBED_EMBEDDED_VERSION (VERSION_MAJOR << 16) | VERSION_MINOR
+
/* enums */
enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
enum { SchemeNorm, SchemeSel }; /* color schemes */
enum { NetSupported, NetWMName, NetWMState, NetWMCheck,
+ NetSystemTray, NetSystemTrayOP, NetSystemTrayOrientation, NetSystemTrayOrientationHorz,
NetWMFullscreen, NetActiveWindow, NetWMWindowType,
NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */
+enum { Manager, Xembed, XembedInfo, XLast }; /* Xembed atoms */
enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */
enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle,
ClkClientWin, ClkRootWin, ClkLast }; /* clicks */
@@ -141,6 +159,12 @@ typedef struct {
int monitor;
} Rule;
+typedef struct Systray Systray;
+struct Systray {
+ Window win;
+ Client *icons;
+};
+
/* function declarations */
static void applyrules(Client *c);
static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact);
@@ -172,6 +196,7 @@ static void focusstack(const Arg *arg);
static Atom getatomprop(Client *c, Atom prop);
static int getrootptr(int *x, int *y);
static long getstate(Window w);
+static unsigned int getsystraywidth();
static int gettextprop(Window w, Atom atom, char *text, unsigned int size);
static void grabbuttons(Client *c, int focused);
static void grabkeys(void);
@@ -189,13 +214,16 @@ static void pop(Client *);
static void propertynotify(XEvent *e);
static void quit(const Arg *arg);
static Monitor *recttomon(int x, int y, int w, int h);
+static void removesystrayicon(Client *i);
static void resize(Client *c, int x, int y, int w, int h, int interact);
+static void resizebarwin(Monitor *m);
static void resizeclient(Client *c, int x, int y, int w, int h);
static void resizemouse(const Arg *arg);
+static void resizerequest(XEvent *e);
static void restack(Monitor *m);
static void run(void);
static void scan(void);
-static int sendevent(Client *c, Atom proto);
+static int sendevent(Window w, Atom proto, int m, long d0, long d1, long d2, long d3, long d4);
static void sendmon(Client *c, Monitor *m);
static void setclientstate(Client *c, long state);
static void setfocus(Client *c);
@@ -207,6 +235,7 @@ static void seturgent(Client *c, int urg);
static void showhide(Client *c);
static void sigchld(int unused);
static void spawn(const Arg *arg);
+static Monitor *systraytomon(Monitor *m);
static void tag(const Arg *arg);
static void tagmon(const Arg *arg);
static void tile(Monitor *);
@@ -224,18 +253,23 @@ static int updategeom(void);
static void updatenumlockmask(void);
static void updatesizehints(Client *c);
static void updatestatus(void);
+static void updatesystray(void);
+static void updatesystrayicongeom(Client *i, int w, int h);
+static void updatesystrayiconstate(Client *i, XPropertyEvent *ev);
static void updatetitle(Client *c);
static void updatewindowtype(Client *c);
static void updatewmhints(Client *c);
static void view(const Arg *arg);
static Client *wintoclient(Window w);
static Monitor *wintomon(Window w);
+static Client *wintosystrayicon(Window w);
static int xerror(Display *dpy, XErrorEvent *ee);
static int xerrordummy(Display *dpy, XErrorEvent *ee);
static int xerrorstart(Display *dpy, XErrorEvent *ee);
static void zoom(const Arg *arg);
/* variables */
+static Systray *systray = NULL;
static const char broken[] = "broken";
static char stext[256];
static int screen;
@@ -258,9 +292,10 @@ static void (*handler[LASTEvent]) (XEvent *) = {
[MapRequest] = maprequest,
[MotionNotify] = motionnotify,
[PropertyNotify] = propertynotify,
+ [ResizeRequest] = resizerequest,
[UnmapNotify] = unmapnotify
};
-static Atom wmatom[WMLast], netatom[NetLast];
+static Atom wmatom[WMLast], netatom[NetLast], xatom[XLast];
static int running = 1;
static Cur *cursor[CurLast];
static Clr **scheme;
@@ -440,7 +475,7 @@ buttonpress(XEvent *e)
arg.ui = 1 << i;
} else if (ev->x < x + blw)
click = ClkLtSymbol;
- else if (ev->x > selmon->ww - (int)TEXTW(stext))
+ else if (ev->x > selmon->ww - (int)TEXTW(stext) - getsystraywidth())
click = ClkStatusText;
else
click = ClkWinTitle;
@@ -483,6 +518,11 @@ cleanup(void)
XUngrabKey(dpy, AnyKey, AnyModifier, root);
while (mons)
cleanupmon(mons);
+ if (showsystray) {
+ XUnmapWindow(dpy, systray->win);
+ XDestroyWindow(dpy, systray->win);
+ free(systray);
+ }
for (i = 0; i < CurLast; i++)
drw_cur_free(drw, cursor[i]);
for (i = 0; i < LENGTH(colors); i++)
@@ -513,9 +553,57 @@ cleanupmon(Monitor *mon)
void
clientmessage(XEvent *e)
{
+ XWindowAttributes wa;
+ XSetWindowAttributes swa;
XClientMessageEvent *cme = &e->xclient;
Client *c = wintoclient(cme->window);
+ if (showsystray && cme->window == systray->win && cme->message_type == netatom[NetSystemTrayOP]) {
+ /* add systray icons */
+ if (cme->data.l[1] == SYSTEM_TRAY_REQUEST_DOCK) {
+ if (!(c = (Client *)calloc(1, sizeof(Client))))
+ die("fatal: could not malloc() %u bytes\n", sizeof(Client));
+ if (!(c->win = cme->data.l[2])) {
+ free(c);
+ return;
+ }
+ c->mon = selmon;
+ c->next = systray->icons;
+ systray->icons = c;
+ if (!XGetWindowAttributes(dpy, c->win, &wa)) {
+ /* use sane defaults */
+ wa.width = bh;
+ wa.height = bh;
+ wa.border_width = 0;
+ }
+ c->x = c->oldx = c->y = c->oldy = 0;
+ c->w = c->oldw = wa.width;
+ c->h = c->oldh = wa.height;
+ c->oldbw = wa.border_width;
+ c->bw = 0;
+ c->isfloating = True;
+ /* reuse tags field as mapped status */
+ c->tags = 1;
+ updatesizehints(c);
+ updatesystrayicongeom(c, wa.width, wa.height);
+ XAddToSaveSet(dpy, c->win);
+ XSelectInput(dpy, c->win, StructureNotifyMask | PropertyChangeMask | ResizeRedirectMask);
+ XReparentWindow(dpy, c->win, systray->win, 0, 0);
+ /* use parents background color */
+ swa.background_pixel = scheme[SchemeNorm][ColBg].pixel;
+ XChangeWindowAttributes(dpy, c->win, CWBackPixel, &swa);
+ sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_EMBEDDED_NOTIFY, 0 , systray->win, XEMBED_EMBEDDED_VERSION);
+ /* FIXME not sure if I have to send these events, too */
+ sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_FOCUS_IN, 0 , systray->win, XEMBED_EMBEDDED_VERSION);
+ sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_WINDOW_ACTIVATE, 0 , systray->win, XEMBED_EMBEDDED_VERSION);
+ sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_MODALITY_ON, 0 , systray->win, XEMBED_EMBEDDED_VERSION);
+ XSync(dpy, False);
+ resizebarwin(selmon);
+ updatesystray();
+ setclientstate(c, NormalState);
+ }
+ return;
+ }
if (!c)
return;
if (cme->message_type == netatom[NetWMState]) {
@@ -568,7 +656,7 @@ configurenotify(XEvent *e)
for (c = m->clients; c; c = c->next)
if (c->isfullscreen)
resizeclient(c, m->mx, m->my, m->mw, m->mh);
- XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh);
+ resizebarwin(m);
}
focus(NULL);
arrange(NULL);
@@ -653,6 +741,11 @@ destroynotify(XEvent *e)
if ((c = wintoclient(ev->window)))
unmanage(c, 1);
+ else if ((c = wintosystrayicon(ev->window))) {
+ removesystrayicon(c);
+ resizebarwin(selmon);
+ updatesystray();
+ }
}
void
@@ -696,19 +789,23 @@ dirtomon(int dir)
void
drawbar(Monitor *m)
{
- int x, w, tw = 0;
+ int x, w, tw = 0, stw = 0;
int boxs = drw->fonts->h / 9;
int boxw = drw->fonts->h / 6 + 2;
unsigned int i, occ = 0, urg = 0;
Client *c;
+ if(showsystray && m == systraytomon(m))
+ stw = getsystraywidth();
+
/* draw status first so it can be overdrawn by tags later */
if (m == selmon) { /* status is only drawn on selected monitor */
drw_setscheme(drw, scheme[SchemeNorm]);
- tw = TEXTW(stext) - lrpad + 2; /* 2px right padding */
- drw_text(drw, m->ww - tw, 0, tw, bh, 0, stext, 0);
+ tw = TEXTW(stext) - lrpad / 2 + 2; /* 2px right padding */
+ drw_text(drw, m->ww - tw - stw, 0, tw, bh, lrpad / 2 - 2, stext, 0);
}
+ resizebarwin(m);
for (c = m->clients; c; c = c->next) {
occ |= c->tags;
if (c->isurgent)
@@ -729,7 +826,7 @@ drawbar(Monitor *m)
drw_setscheme(drw, scheme[SchemeNorm]);
x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0);
- if ((w = m->ww - tw - x) > bh) {
+ if ((w = m->ww - tw - stw - x) > bh) {
if (m->sel) {
drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]);
drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0);
@@ -740,7 +837,7 @@ drawbar(Monitor *m)
drw_rect(drw, x, 0, w, bh, 1, 1);
}
}
- drw_map(drw, m->barwin, 0, 0, m->ww, bh);
+ drw_map(drw, m->barwin, 0, 0, m->ww - stw, bh);
}
void
@@ -777,8 +874,11 @@ expose(XEvent *e)
Monitor *m;
XExposeEvent *ev = &e->xexpose;
- if (ev->count == 0 && (m = wintomon(ev->window)))
+ if (ev->count == 0 && (m = wintomon(ev->window))) {
drawbar(m);
+ if (m == selmon)
+ updatesystray();
+ }
}
void
@@ -863,10 +963,17 @@ getatomprop(Client *c, Atom prop)
unsigned long dl;
unsigned char *p = NULL;
Atom da, atom = None;
+ /* FIXME getatomprop should return the number of items and a pointer to
+ * the stored data instead of this workaround */
+ Atom req = XA_ATOM;
+ if (prop == xatom[XembedInfo])
+ req = xatom[XembedInfo];
- if (XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, XA_ATOM,
+ if (XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, req,
&da, &di, &dl, &dl, &p) == Success && p) {
atom = *(Atom *)p;
+ if (da == xatom[XembedInfo] && dl == 2)
+ atom = ((Atom *)p)[1];
XFree(p);
}
return atom;
@@ -900,6 +1007,16 @@ getstate(Window w)
return result;
}
+unsigned int
+getsystraywidth()
+{
+ unsigned int w = 0;
+ Client *i;
+ if(showsystray)
+ for(i = systray->icons; i; w += i->w + systrayspacing, i = i->next) ;
+ return w ? w + systrayspacing : 1;
+}
+
int
gettextprop(Window w, Atom atom, char *text, unsigned int size)
{
@@ -1004,7 +1121,7 @@ killclient(const Arg *arg)
{
if (!selmon->sel)
return;
- if (!sendevent(selmon->sel, wmatom[WMDelete])) {
+ if (!sendevent(selmon->sel->win, wmatom[WMDelete], NoEventMask, wmatom[WMDelete], CurrentTime, 0 , 0, 0)) {
XGrabServer(dpy);
XSetErrorHandler(xerrordummy);
XSetCloseDownMode(dpy, DestroyAll);
@@ -1092,6 +1209,12 @@ maprequest(XEvent *e)
{
static XWindowAttributes wa;
XMapRequestEvent *ev = &e->xmaprequest;
+ Client *i;
+ if ((i = wintosystrayicon(ev->window))) {
+ sendevent(i->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_WINDOW_ACTIVATE, 0, systray->win, XEMBED_EMBEDDED_VERSION);
+ resizebarwin(selmon);
+ updatesystray();
+ }
if (!XGetWindowAttributes(dpy, ev->window, &wa))
return;
@@ -1216,6 +1339,16 @@ propertynotify(XEvent *e)
Window trans;
XPropertyEvent *ev = &e->xproperty;
+ if ((c = wintosystrayicon(ev->window))) {
+ if (ev->atom == XA_WM_NORMAL_HINTS) {
+ updatesizehints(c);
+ updatesystrayicongeom(c, c->w, c->h);
+ }
+ else
+ updatesystrayiconstate(c, ev);
+ resizebarwin(selmon);
+ updatesystray();
+ }
if ((ev->window == root) && (ev->atom == XA_WM_NAME))
updatestatus();
else if (ev->state == PropertyDelete)
@@ -1266,6 +1399,20 @@ recttomon(int x, int y, int w, int h)
return r;
}
+void
+removesystrayicon(Client *i)
+{
+ Client **ii;
+
+ if (!showsystray || !i)
+ return;
+ for (ii = &systray->icons; *ii && *ii != i; ii = &(*ii)->next);
+ if (ii)
+ *ii = i->next;
+ free(i);
+}
+
+
void
resize(Client *c, int x, int y, int w, int h, int interact)
{
@@ -1273,6 +1420,14 @@ resize(Client *c, int x, int y, int w, int h, int interact)
resizeclient(c, x, y, w, h);
}
+void
+resizebarwin(Monitor *m) {
+ unsigned int w = m->ww;
+ if (showsystray && m == systraytomon(m))
+ w -= getsystraywidth();
+ XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, w, bh);
+}
+
void
resizeclient(Client *c, int x, int y, int w, int h)
{
@@ -1345,6 +1500,19 @@ resizemouse(const Arg *arg)
}
}
+void
+resizerequest(XEvent *e)
+{
+ XResizeRequestEvent *ev = &e->xresizerequest;
+ Client *i;
+
+ if ((i = wintosystrayicon(ev->window))) {
+ updatesystrayicongeom(i, ev->width, ev->height);
+ resizebarwin(selmon);
+ updatesystray();
+ }
+}
+
void
restack(Monitor *m)
{
@@ -1434,26 +1602,36 @@ setclientstate(Client *c, long state)
}
int
-sendevent(Client *c, Atom proto)
+sendevent(Window w, Atom proto, int mask, long d0, long d1, long d2, long d3, long d4)
{
int n;
- Atom *protocols;
+ Atom *protocols, mt;
int exists = 0;
XEvent ev;
- if (XGetWMProtocols(dpy, c->win, &protocols, &n)) {
- while (!exists && n--)
- exists = protocols[n] == proto;
- XFree(protocols);
+ if (proto == wmatom[WMTakeFocus] || proto == wmatom[WMDelete]) {
+ mt = wmatom[WMProtocols];
+ if (XGetWMProtocols(dpy, w, &protocols, &n)) {
+ while (!exists && n--)
+ exists = protocols[n] == proto;
+ XFree(protocols);
+ }
+ }
+ else {
+ exists = True;
+ mt = proto;
}
if (exists) {
ev.type = ClientMessage;
- ev.xclient.window = c->win;
- ev.xclient.message_type = wmatom[WMProtocols];
+ ev.xclient.window = w;
+ ev.xclient.message_type = mt;
ev.xclient.format = 32;
- ev.xclient.data.l[0] = proto;
- ev.xclient.data.l[1] = CurrentTime;
- XSendEvent(dpy, c->win, False, NoEventMask, &ev);
+ ev.xclient.data.l[0] = d0;
+ ev.xclient.data.l[1] = d1;
+ ev.xclient.data.l[2] = d2;
+ ev.xclient.data.l[3] = d3;
+ ev.xclient.data.l[4] = d4;
+ XSendEvent(dpy, w, False, mask, &ev);
}
return exists;
}
@@ -1467,7 +1645,7 @@ setfocus(Client *c)
XA_WINDOW, 32, PropModeReplace,
(unsigned char *) &(c->win), 1);
}
- sendevent(c, wmatom[WMTakeFocus]);
+ sendevent(c->win, wmatom[WMTakeFocus], NoEventMask, wmatom[WMTakeFocus], CurrentTime, 0, 0, 0);
}
void
@@ -1556,6 +1734,10 @@ setup(void)
wmatom[WMTakeFocus] = XInternAtom(dpy, "WM_TAKE_FOCUS", False);
netatom[NetActiveWindow] = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False);
netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False);
+ netatom[NetSystemTray] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_S0", False);
+ netatom[NetSystemTrayOP] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_OPCODE", False);
+ netatom[NetSystemTrayOrientation] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_ORIENTATION", False);
+ netatom[NetSystemTrayOrientationHorz] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_ORIENTATION_HORZ", False);
netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False);
netatom[NetWMState] = XInternAtom(dpy, "_NET_WM_STATE", False);
netatom[NetWMCheck] = XInternAtom(dpy, "_NET_SUPPORTING_WM_CHECK", False);
@@ -1563,6 +1745,9 @@ setup(void)
netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False);
netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False);
netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", False);
+ xatom[Manager] = XInternAtom(dpy, "MANAGER", False);
+ xatom[Xembed] = XInternAtom(dpy, "_XEMBED", False);
+ xatom[XembedInfo] = XInternAtom(dpy, "_XEMBED_INFO", False);
/* init cursors */
cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr);
cursor[CurResize] = drw_cur_create(drw, XC_sizing);
@@ -1571,6 +1756,8 @@ setup(void)
scheme = ecalloc(LENGTH(colors), sizeof(Clr *));
for (i = 0; i < LENGTH(colors); i++)
scheme[i] = drw_scm_create(drw, colors[i], 3);
+ /* init system tray */
+ updatesystray();
/* init bars */
updatebars();
updatestatus();
@@ -1704,7 +1891,18 @@ togglebar(const Arg *arg)
{
selmon->showbar = !selmon->showbar;
updatebarpos(selmon);
- XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh);
+ resizebarwin(selmon);
+ if (showsystray) {
+ XWindowChanges wc;
+ if (!selmon->showbar)
+ wc.y = -bh;
+ else if (selmon->showbar) {
+ wc.y = 0;
+ if (!selmon->topbar)
+ wc.y = selmon->mh - bh;
+ }
+ XConfigureWindow(dpy, systray->win, CWY, &wc);
+ }
arrange(selmon);
}
@@ -1799,11 +1997,18 @@ unmapnotify(XEvent *e)
else
unmanage(c, 0);
}
+ else if ((c = wintosystrayicon(ev->window))) {
+ /* KLUDGE! sometimes icons occasionally unmap their windows, but do
+ * _not_ destroy them. We map those windows back */
+ XMapRaised(dpy, c->win);
+ updatesystray();
+ }
}
void
updatebars(void)
{
+ unsigned int w;
Monitor *m;
XSetWindowAttributes wa = {
.override_redirect = True,
@@ -1814,10 +2019,15 @@ updatebars(void)
for (m = mons; m; m = m->next) {
if (m->barwin)
continue;
- m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, DefaultDepth(dpy, screen),
+ w = m->ww;
+ if (showsystray && m == systraytomon(m))
+ w -= getsystraywidth();
+ m->barwin = XCreateWindow(dpy, root, m->wx, m->by, w, bh, 0, DefaultDepth(dpy, screen),
CopyFromParent, DefaultVisual(dpy, screen),
CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa);
XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor);
+ if (showsystray && m == systraytomon(m))
+ XMapRaised(dpy, systray->win);
XMapRaised(dpy, m->barwin);
XSetClassHint(dpy, m->barwin, &ch);
}
@@ -1993,6 +2203,121 @@ updatestatus(void)
if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext)))
strcpy(stext, "dwm-"VERSION);
drawbar(selmon);
+ updatesystray();
+}
+
+void
+updatesystrayicongeom(Client *i, int w, int h)
+{
+ if (i) {
+ i->h = bh;
+ if (w == h)
+ i->w = bh;
+ else if (h == bh)
+ i->w = w;
+ else
+ i->w = (int) ((float)bh * ((float)w / (float)h));
+ applysizehints(i, &(i->x), &(i->y), &(i->w), &(i->h), False);
+ /* force icons into the systray dimensions if they don't want to */
+ if (i->h > bh) {
+ if (i->w == i->h)
+ i->w = bh;
+ else
+ i->w = (int) ((float)bh * ((float)i->w / (float)i->h));
+ i->h = bh;
+ }
+ }
+}
+
+void
+updatesystrayiconstate(Client *i, XPropertyEvent *ev)
+{
+ long flags;
+ int code = 0;
+
+ if (!showsystray || !i || ev->atom != xatom[XembedInfo] ||
+ !(flags = getatomprop(i, xatom[XembedInfo])))
+ return;
+
+ if (flags & XEMBED_MAPPED && !i->tags) {
+ i->tags = 1;
+ code = XEMBED_WINDOW_ACTIVATE;
+ XMapRaised(dpy, i->win);
+ setclientstate(i, NormalState);
+ }
+ else if (!(flags & XEMBED_MAPPED) && i->tags) {
+ i->tags = 0;
+ code = XEMBED_WINDOW_DEACTIVATE;
+ XUnmapWindow(dpy, i->win);
+ setclientstate(i, WithdrawnState);
+ }
+ else
+ return;
+ sendevent(i->win, xatom[Xembed], StructureNotifyMask, CurrentTime, code, 0,
+ systray->win, XEMBED_EMBEDDED_VERSION);
+}
+
+void
+updatesystray(void)
+{
+ XSetWindowAttributes wa;
+ XWindowChanges wc;
+ Client *i;
+ Monitor *m = systraytomon(NULL);
+ unsigned int x = m->mx + m->mw;
+ unsigned int w = 1;
+
+ if (!showsystray)
+ return;
+ if (!systray) {
+ /* init systray */
+ if (!(systray = (Systray *)calloc(1, sizeof(Systray))))
+ die("fatal: could not malloc() %u bytes\n", sizeof(Systray));
+ systray->win = XCreateSimpleWindow(dpy, root, x, m->by, w, bh, 0, 0, scheme[SchemeSel][ColBg].pixel);
+ wa.event_mask = ButtonPressMask | ExposureMask;
+ wa.override_redirect = True;
+ wa.background_pixel = scheme[SchemeNorm][ColBg].pixel;
+ XSelectInput(dpy, systray->win, SubstructureNotifyMask);
+ XChangeProperty(dpy, systray->win, netatom[NetSystemTrayOrientation], XA_CARDINAL, 32,
+ PropModeReplace, (unsigned char *)&netatom[NetSystemTrayOrientationHorz], 1);
+ XChangeWindowAttributes(dpy, systray->win, CWEventMask|CWOverrideRedirect|CWBackPixel, &wa);
+ XMapRaised(dpy, systray->win);
+ XSetSelectionOwner(dpy, netatom[NetSystemTray], systray->win, CurrentTime);
+ if (XGetSelectionOwner(dpy, netatom[NetSystemTray]) == systray->win) {
+ sendevent(root, xatom[Manager], StructureNotifyMask, CurrentTime, netatom[NetSystemTray], systray->win, 0, 0);
+ XSync(dpy, False);
+ }
+ else {
+ fprintf(stderr, "dwm: unable to obtain system tray.\n");
+ free(systray);
+ systray = NULL;
+ return;
+ }
+ }
+ for (w = 0, i = systray->icons; i; i = i->next) {
+ /* make sure the background color stays the same */
+ wa.background_pixel = scheme[SchemeNorm][ColBg].pixel;
+ XChangeWindowAttributes(dpy, i->win, CWBackPixel, &wa);
+ XMapRaised(dpy, i->win);
+ w += systrayspacing;
+ i->x = w;
+ XMoveResizeWindow(dpy, i->win, i->x, 0, i->w, i->h);
+ w += i->w;
+ if (i->mon != m)
+ i->mon = m;
+ }
+ w = w ? w + systrayspacing : 1;
+ x -= w;
+ XMoveResizeWindow(dpy, systray->win, x, m->by, w, bh);
+ wc.x = x; wc.y = m->by; wc.width = w; wc.height = bh;
+ wc.stack_mode = Above; wc.sibling = m->barwin;
+ XConfigureWindow(dpy, systray->win, CWX|CWY|CWWidth|CWHeight|CWSibling|CWStackMode, &wc);
+ XMapWindow(dpy, systray->win);
+ XMapSubwindows(dpy, systray->win);
+ /* redraw background */
+ XSetForeground(dpy, drw->gc, scheme[SchemeNorm][ColBg].pixel);
+ XFillRectangle(dpy, systray->win, drw->gc, 0, 0, w, bh);
+ XSync(dpy, False);
}
void
@@ -2060,6 +2385,16 @@ wintoclient(Window w)
return NULL;
}
+Client *
+wintosystrayicon(Window w) {
+ Client *i = NULL;
+
+ if (!showsystray || !w)
+ return i;
+ for (i = systray->icons; i && i->win != w; i = i->next) ;
+ return i;
+}
+
Monitor *
wintomon(Window w)
{
@@ -2113,6 +2448,22 @@ xerrorstart(Display *dpy, XErrorEvent *ee)
return -1;
}
+Monitor *
+systraytomon(Monitor *m) {
+ Monitor *t;
+ int i, n;
+ if(!systraypinning) {
+ if(!m)
+ return selmon;
+ return m == selmon ? m : NULL;
+ }
+ for(n = 1, t = mons; t && t->next; n++, t = t->next) ;
+ for(i = 1, t = mons; t && t->next && i < systraypinning; i++, t = t->next) ;
+ if(systraypinningfailfirst && n < systraypinning)
+ return mons;
+ return t;
+}
+
void
zoom(const Arg *arg)
{

+ 185
- 0
suckless/dwm/dwm.1 View File

@ -0,0 +1,185 @@
.TH DWM 1 dwm\-VERSION
.SH NAME
dwm \- dynamic window manager
.SH SYNOPSIS
.B dwm
.RB [ \-v ]
.SH DESCRIPTION
dwm is a dynamic window manager for X. It manages windows in tiled, monocle
and floating layouts. Either layout can be applied dynamically, optimising the
environment for the application in use and the task performed.
.P
In tiled layouts windows are managed in a master and stacking area. The master
area on the left contains one window by default, and the stacking area on the
right contains all other windows. The number of master area windows can be
adjusted from zero to an arbitrary number. In monocle layout all windows are
maximised to the screen size. In floating layout windows can be resized and
moved freely. Dialog windows are always managed floating, regardless of the
layout applied.
.P
Windows are grouped by tags. Each window can be tagged with one or multiple
tags. Selecting certain tags displays all windows with these tags.
.P
Each screen contains a small status bar which displays all available tags, the
layout, the title of the focused window, and the text read from the root window
name property, if the screen is focused. A floating window is indicated with an
empty square and a maximised floating window is indicated with a filled square
before the windows title. The selected tags are indicated with a different
color. The tags of the focused window are indicated with a filled square in the
top left corner. The tags which are applied to one or more windows are
indicated with an empty square in the top left corner.
.P
dwm draws a small border around windows to indicate the focus state.
.SH OPTIONS
.TP
.B \-v
prints version information to stderr, then exits.
.SH USAGE
.SS Status bar
.TP
.B X root window name
is read and displayed in the status text area. It can be set with the
.BR xsetroot (1)
command.
.TP
.B Button1
click on a tag label to display all windows with that tag, click on the layout
label toggles between tiled and floating layout.
.TP
.B Button3
click on a tag label adds/removes all windows with that tag to/from the view.
.TP
.B Mod1\-Button1
click on a tag label applies that tag to the focused window.
.TP
.B Mod1\-Button3
click on a tag label adds/removes that tag to/from the focused window.
.SS Keyboard commands
.TP
.B Mod1\-Shift\-Return
Start
.BR st(1).
.TP
.B Mod1\-p
Spawn
.BR dmenu(1)
for launching other programs.
.TP
.B Mod1\-,
Focus previous screen, if any.
.TP
.B Mod1\-.
Focus next screen, if any.
.TP
.B Mod1\-Shift\-,
Send focused window to previous screen, if any.
.TP
.B Mod1\-Shift\-.
Send focused window to next screen, if any.
.TP
.B Mod1\-b
Toggles bar on and off.
.TP
.B Mod1\-t
Sets tiled layout.
.TP
.B Mod1\-f
Sets floating layout.
.TP
.B Mod1\-m
Sets monocle layout.
.TP
.B Mod1\-space
Toggles between current and previous layout.
.TP
.B Mod1\-Control\-,
Cycles backwards in layout list.
.TP
.B Mod1\-Control\-.
Cycles forwards in layout list.
.TP
.B Mod1\-j
Focus next window.
.TP
.B Mod1\-k
Focus previous window.
.TP
.B Mod1\-i
Increase number of windows in master area.
.TP
.B Mod1\-d
Decrease number of windows in master area.
.TP
.B Mod1\-l
Increase master area size.
.TP
.B Mod1\-h
Decrease master area size.
.TP
.B Mod1\-o
Select view of the window in focus. The list of tags to be displayed is matched to the window tag list.
.TP
.B Mod1\-Return
Zooms/cycles focused window to/from master area (tiled layouts only).
.TP
.B Mod1\-Shift\-c
Close focused window.
.TP
.B Mod1\-Shift\-space
Toggle focused window between tiled and floating state.
.TP
.B Mod1\-Tab
Toggles to the previously selected tags.
.TP
.B Mod1\-Shift\-[1..n]
Apply nth tag to focused window.
.TP
.B Mod1\-Shift\-0
Apply all tags to focused window.
.TP
.B Mod1\-Control\-Shift\-[1..n]
Add/remove nth tag to/from focused window.
.TP
.B Mod1\-[1..n]
View all windows with nth tag.
.TP
.B Mod1\-0
View all windows with any tag.
.TP
.B Mod1\-Control\-[1..n]
Add/remove all windows with nth tag to/from the view.
.TP
.B Mod1\-Shift\-q
Quit dwm.
.SS Mouse commands
.TP
.B Mod1\-Button1
Move focused window while dragging. Tiled windows will be toggled to the floating state.
.TP
.B Mod1\-Button2
Toggles focused window between floating and tiled state.
.TP
.B Mod1\-Button3
Resize focused window while dragging. Tiled windows will be toggled to the floating state.
.SH CUSTOMIZATION
dwm is customized by creating a custom config.h and (re)compiling the source
code. This keeps it fast, secure and simple.
.SH SEE ALSO
.BR dmenu (1),
.BR st (1)
.SH ISSUES
Java applications which use the XToolkit/XAWT backend may draw grey windows
only. The XToolkit/XAWT backend breaks ICCCM-compliance in recent JDK 1.5 and early
JDK 1.6 versions, because it assumes a reparenting window manager. Possible workarounds
are using JDK 1.4 (which doesn't contain the XToolkit/XAWT backend) or setting the
environment variable
.BR AWT_TOOLKIT=MToolkit
(to use the older Motif backend instead) or running
.B xprop -root -f _NET_WM_NAME 32a -set _NET_WM_NAME LG3D
or
.B wmname LG3D
(to pretend that a non-reparenting window manager is running that the
XToolkit/XAWT backend can recognize) or when using OpenJDK setting the environment variable
.BR _JAVA_AWT_WM_NONREPARENTING=1 .
.SH BUGS
Send all bug reports with a patch to hackers@suckless.org.

+ 2768
- 0
suckless/dwm/dwm.c
File diff suppressed because it is too large
View File


BIN
suckless/dwm/dwm.png View File

Before After
Width: 192  |  Height: 80  |  Size: 373 B

+ 28
- 0
suckless/dwm/dwm_config_pulseaudio.h View File

@ -0,0 +1,28 @@
/**
* dwmconfig.h
* Hardware multimedia keys
*/
/* Somewhere at the beginning of config.h include:
#include <X11/XF86keysym.h>
/* Add somewhere in your constants definition section */
static const char *upvol[] = { "/usr/bin/pactl", "set-sink-volume", "0", "+5%", NULL };
static const char *downvol[] = { "/usr/bin/pactl", "set-sink-volume", "0", "-5%", NULL };
static const char *mutevol[] = { "/usr/bin/pactl", "set-sink-mute", "0", "toggle", NULL };
/* Add to keys[] array. With 0 as modifier, you are able to use the keys directly. */
static Key keys[] = {
{ 0, XF86XK_AudioLowerVolume, spawn, {.v = downvol } },
{ 0, XF86XK_AudioMute, spawn, {.v = mutevol } },
{ 0, XF86XK_AudioRaiseVolume, spawn, {.v = upvol } },
};
/* If you have a small laptop keyboard or don't want to spring your fingers too far away. */
static Key keys[] = {
{ MODKEY, XK_F11, spawn, {.v = downvol } },
{ MODKEY, XK_F9, spawn, {.v = mutevol } },
{ MODKEY, XK_F12, spawn, {.v = upvol } },
};

+ 66
- 0
suckless/dwm/fibonacci.c View File

@ -0,0 +1,66 @@
void
fibonacci(Monitor *mon, int s) {
unsigned int i, n, nx, ny, nw, nh;
Client *c;
for(n = 0, c = nexttiled(mon->clients); c; c = nexttiled(c->next), n++);
if(n == 0)
return;
nx = mon->wx;
ny = 0;
nw = mon->ww;
nh = mon->wh;
for(i = 0, c = nexttiled(mon->clients); c; c = nexttiled(c->next)) {
if((i % 2 && nh / 2 > 2 * c->bw)
|| (!(i % 2) && nw / 2 > 2 * c->bw)) {
if(i < n - 1) {
if(i % 2)
nh /= 2;
else
nw /= 2;
if((i % 4) == 2 && !s)
nx += nw;
else if((i % 4) == 3 && !s)
ny += nh;
}
if((i % 4) == 0) {
if(s)
ny += nh;
else
ny -= nh;
}
else if((i % 4) == 1)
nx += nw;
else if((i % 4) == 2)
ny += nh;
else if((i % 4) == 3) {
if(s)
nx += nw;
else
nx -= nw;
}
if(i == 0)
{
if(n != 1)
nw = mon->ww * mon->mfact;
ny = mon->wy;
}
else if(i == 1)
nw = mon->ww - nw;
i++;
}
resize(c, nx, ny, nw - 2 * c->bw, nh - 2 * c->bw, False);
}
}
void
dwindle(Monitor *mon) {
fibonacci(mon, 1);
}
void
spiral(Monitor *mon) {
fibonacci(mon, 0);
}

+ 27
- 0
suckless/dwm/layouts.c View File

@ -0,0 +1,27 @@
void
grid(Monitor *m) {
unsigned int i, n, cx, cy, cw, ch, aw, ah, cols, rows;
Client *c;
for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next))
n++;
/* grid dimensions */
for(rows = 0; rows <= n/2; rows++)
if(rows*rows >= n)
break;
cols = (rows && (rows - 1) * rows >= n) ? rows - 1 : rows;
/* window geoms (cell height/width) */
ch = m->wh / (rows ? rows : 1);
cw = m->ww / (cols ? cols : 1);
for(i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next)) {
cx = m->wx + (i / rows) * cw;
cy = m->wy + (i % rows) * ch;
/* adjust height/width of last row/column's windows */
ah = ((i + 1) % rows == 0) ? m->wh - ch * rows : 0;
aw = (i >= rows * (cols - 1)) ? m->ww - cw * cols : 0;
resize(c, cx, cy, cw - 2 * c->bw + aw, ch - 2 * c->bw + ah, False);
i++;
}
}

+ 49
- 0
suckless/dwm/movestack.c View File

@ -0,0 +1,49 @@
void
movestack(const Arg *arg) {
Client *c = NULL, *p = NULL, *pc = NULL, *i;
if(arg->i > 0) {
/* find the client after selmon->sel */
for(c = selmon->sel->next; c && (!ISVISIBLE(c) || c->isfloating); c = c->next);
if(!c)
for(c = selmon->clients; c && (!ISVISIBLE(c) || c->isfloating); c = c->next);
}
else {
/* find the client before selmon->sel */
for(i = selmon->clients; i != selmon->sel; i = i->next)
if(ISVISIBLE(i) && !i->isfloating)
c = i;
if(!c)
for(; i; i = i->next)
if(ISVISIBLE(i) && !i->isfloating)
c = i;
}
/* find the client before selmon->sel and c */
for(i = selmon->clients; i && (!p || !pc); i = i->next) {
if(i->next == selmon->sel)
p = i;
if(i->next == c)
pc = i;
}
/* swap c and selmon->sel selmon->clients in the selmon->clients list */
if(c && c != selmon->sel) {
Client *temp = selmon->sel->next==c?selmon->sel:selmon->sel->next;
selmon->sel->next = c->next==selmon->sel?c:c->next;
c->next = temp;
if(p && p != c)
p->next = c;
if(pc && pc != selmon->sel)
pc->next = selmon->sel;
if(selmon->sel == selmon->clients)
selmon->clients = c;
else if(c == selmon->clients)
selmon->clients = selmon->sel;
arrange(selmon);
}
}

+ 65
- 0
suckless/dwm/patches/dwm-6.0-winview.diff View File

@ -0,0 +1,65 @@
diff --git a/config.def.h b/config.def.h
index 77ff358..3ba0efe 100644
--- a/config.def.h
+++ b/config.def.h
@@ -84,6 +84,7 @@ static Key keys[] = {
TAGKEYS( XK_8, 7)
TAGKEYS( XK_9, 8)
{ MODKEY|ShiftMask, XK_q, quit, {0} },
+ { MODKEY, XK_o, winview, {0} },
};
/* button definitions */
diff --git a/dwm.1 b/dwm.1
index 5268a06..1188c82 100644
--- a/dwm.1
+++ b/dwm.1
@@ -104,6 +104,9 @@ Increase master area size.
.B Mod1\-h
Decrease master area size.
.TP
+.B Mod1\-o
+Select view of the window in focus. The list of tags to be displayed is matched to the window tag list.
+.TP
.B Mod1\-Return
Zooms/cycles focused window to/from master area (tiled layouts only).
.TP
diff --git a/dwm.c b/dwm.c
index 1d78655..abf944c 100644
--- a/dwm.c
+++ b/dwm.c
@@ -247,6 +247,7 @@ static void updatewmhints(Client *c);
static void view(const Arg *arg);
static Client *wintoclient(Window w);
static Monitor *wintomon(Window w);
+static void winview(const Arg* arg);
static int xerror(Display *dpy, XErrorEvent *ee);
static int xerrordummy(Display *dpy, XErrorEvent *ee);
static int xerrorstart(Display *dpy, XErrorEvent *ee);
@@ -2080,6 +2081,26 @@ wintomon(Window w) {
return selmon;
}
+/* Selects for the view of the focused window. The list of tags */
+/* to be displayed is matched to the focused window tag list. */
+void
+winview(const Arg* arg){
+ Window win, win_r, win_p, *win_c;
+ unsigned nc;
+ int unused;
+ Client* c;
+ Arg a;
+
+ if (!XGetInputFocus(dpy, &win, &unused)) return;
+ while(XQueryTree(dpy, win, &win_r, &win_p, &win_c, &nc)
+ && win_p != win_r) win = win_p;
+
+ if (!(c = wintoclient(win))) return;
+
+ a.ui = c->tags;
+ view(&a);
+}
+
/* There's no way to check accesses to destroyed windows, thus those cases are
* ignored (especially on UnmapNotify's). Other types of errors call Xlibs
* default error handler, which may call exit. */

+ 53
- 0
suckless/dwm/patches/dwm-actualfullscreen-20191112-cb3f58a.diff View File

@ -0,0 +1,53 @@
From 3a16816a6f5d38014c2a06ce395873c545c8789a Mon Sep 17 00:00:00 2001
From: Soenke Lambert <s.lambert@mittwald.de>
Date: Tue, 12 Nov 2019 10:44:02 +0100
Subject: [PATCH] Fullscreen current window with [Alt]+[Shift]+[f]
This actually fullscreens a window, instead of just hiding the statusbar
and applying the monocle layout.
---
config.def.h | 1 +
dwm.c | 8 ++++++++
2 files changed, 9 insertions(+)
diff --git a/config.def.h b/config.def.h
index 1c0b587..8cd3204 100644
--- a/config.def.h
+++ b/config.def.h
@@ -78,6 +78,7 @@ static Key keys[] = {
{ MODKEY, XK_m, setlayout, {.v = &layouts[2]} },
{ MODKEY, XK_space, setlayout, {0} },
{ MODKEY|ShiftMask, XK_space, togglefloating, {0} },
+ { MODKEY|ShiftMask, XK_f, togglefullscr, {0} },
{ MODKEY, XK_0, view, {.ui = ~0 } },
{ MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } },
{ MODKEY, XK_comma, focusmon, {.i = -1 } },
diff --git a/dwm.c b/dwm.c
index 4465af1..c1b899a 100644
--- a/dwm.c
+++ b/dwm.c
@@ -211,6 +211,7 @@ static void tagmon(const Arg *arg);
static void tile(Monitor *);
static void togglebar(const Arg *arg);
static void togglefloating(const Arg *arg);
+static void togglefullscr(const Arg *arg);
static void toggletag(const Arg *arg);
static void toggleview(const Arg *arg);
static void unfocus(Client *c, int setfocus);
@@ -1719,6 +1720,13 @@ togglefloating(const Arg *arg)
arrange(selmon);
}
+void
+togglefullscr(const Arg *arg)
+{
+ if(selmon->sel)
+ setfullscreen(selmon->sel, !selmon->sel->isfullscreen);
+}
+
void
toggletag(const Arg *arg)
{
--
2.17.1

+ 67
- 0
suckless/dwm/patches/dwm-alttagsdecoration-2020010304-cb3f58a.diff View File

@ -0,0 +1,67 @@
diff --git a/config.def.h b/config.def.h
index 1c0b587..d4b11fc 100644
--- a/config.def.h
+++ b/config.def.h
@@ -20,6 +20,7 @@ static const char *colors[][3] = {
/* tagging */
static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
+static const char *alttags[] = { "<01>", "<02>", "<03>", "<04>", "<05>" };
static const Rule rules[] = {
/* xprop(1):
diff --git a/dwm.c b/dwm.c
index 4465af1..a394159 100644
--- a/dwm.c
+++ b/dwm.c
@@ -416,7 +416,7 @@ attachstack(Client *c)
void
buttonpress(XEvent *e)
{
- unsigned int i, x, click;
+ unsigned int i, x, click, occ;
Arg arg = {0};
Client *c;
Monitor *m;
@@ -430,9 +430,13 @@ buttonpress(XEvent *e)
focus(NULL);
}
if (ev->window == selmon->barwin) {
- i = x = 0;
+ i = x = occ = 0;
+ /* Bitmask of occupied tags */
+ for (c = m->clients; c; c = c->next)
+ occ |= c->tags;
+
do
- x += TEXTW(tags[i]);
+ x += TEXTW(occ & 1 << i ? alttags[i] : tags[i]);
while (ev->x >= x && ++i < LENGTH(tags));
if (i < LENGTH(tags)) {
click = ClkTagBar;
@@ -699,6 +703,7 @@ drawbar(Monitor *m)
int boxs = drw->fonts->h / 9;
int boxw = drw->fonts->h / 6 + 2;
unsigned int i, occ = 0, urg = 0;
+ const char *tagtext;
Client *c;
/* draw status first so it can be overdrawn by tags later */
@@ -715,13 +720,10 @@ drawbar(Monitor *m)
}
x = 0;
for (i = 0; i < LENGTH(tags); i++) {
- w = TEXTW(tags[i]);
- drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]);
- drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i);
- if (occ & 1 << i)
- drw_rect(drw, x + boxs, boxs, boxw, boxw,
- m == selmon && selmon->sel && selmon->sel->tags & 1 << i,
- urg & 1 << i);
+ tagtext = occ & 1 << i ? alttags[i] : tags[i];
+ w = TEXTW(tagtext);
+ drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]);
+ drw_text(drw, x, 0, w, bh, lrpad / 2, tagtext, urg & 1 << i);
x += w;
}
w = blw = TEXTW(m->ltsymbol);

+ 12
- 0
suckless/dwm/patches/dwm-alwayscenter-20200625-f04cac6.diff View File

@ -0,0 +1,12 @@
diff -up dwm/dwm.c dwmmod/dwm.c
--- dwm/dwm.c 2020-06-25 00:21:30.383692180 -0300
+++ dwmmod/dwm.c 2020-06-25 00:20:35.643692330 -0300
@@ -1057,6 +1057,8 @@ manage(Window w, XWindowAttributes *wa)
updatewindowtype(c);
updatesizehints(c);
updatewmhints(c);
+ c->x = c->mon->mx + (c->mon->mw - WIDTH(c)) / 2;
+ c->y = c->mon->my + (c->mon->mh - HEIGHT(c)) / 2;
XSelectInput(dpy, w, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask);
grabbuttons(c, 0);
if (!c->isfloating)

+ 124
- 0
suckless/dwm/patches/dwm-barpadding-20200720-bb2e722.diff View File

@ -0,0 +1,124 @@
From 2f6da65e84288941babde413b9c3f4a619f853a1 Mon Sep 17 00:00:00 2001
From: Pavel Oborin <pavel@oborin.xyz>
Date: Mon, 20 Jul 2020 21:42:43 +0300
Subject: [PATCH] Fixed drawbar
---
config.def.h | 2 ++
dwm.c | 26 ++++++++++++++++----------
2 files changed, 18 insertions(+), 10 deletions(-)
diff --git a/config.def.h b/config.def.h
index 1c0b587..867312f 100644
--- a/config.def.h
+++ b/config.def.h
@@ -5,6 +5,8 @@ static const unsigned int borderpx = 1; /* border pixel of windows */
static const unsigned int snap = 32; /* snap pixel */
static const int showbar = 1; /* 0 means no bar */
static const int topbar = 1; /* 0 means bottom bar */
+static const int vertpad = 10; /* vertical padding of bar */
+static const int sidepad = 10; /* horizontal padding of bar */
static const char *fonts[] = { "monospace:size=10" };
static const char dmenufont[] = "monospace:size=10";
static const char col_gray1[] = "#222222";
diff --git a/dwm.c b/dwm.c
index 9fd0286..ec9c293 100644
--- a/dwm.c
+++ b/dwm.c
@@ -242,6 +242,8 @@ static int screen;
static int sw, sh; /* X display screen geometry width, height */
static int bh, blw = 0; /* bar geometry */
static int lrpad; /* sum of left and right padding for text */
+static int vp; /* vertical padding for bar */
+static int sp; /* side padding for bar */
static int (*xerrorxlib)(Display *, XErrorEvent *);
static unsigned int numlockmask = 0;
static void (*handler[LASTEvent]) (XEvent *) = {
@@ -568,7 +570,7 @@ configurenotify(XEvent *e)
for (c = m->clients; c; c = c->next)
if (c->isfullscreen)
resizeclient(c, m->mx, m->my, m->mw, m->mh);
- XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh);
+ XMoveResizeWindow(dpy, m->barwin, m->wx + sp, m->by + vp, m->ww - 2 * sp, bh);
}
focus(NULL);
arrange(NULL);
@@ -706,7 +708,7 @@ drawbar(Monitor *m)
if (m == selmon) { /* status is only drawn on selected monitor */
drw_setscheme(drw, scheme[SchemeNorm]);
tw = TEXTW(stext) - lrpad + 2; /* 2px right padding */
- drw_text(drw, m->ww - tw, 0, tw, bh, 0, stext, 0);
+ drw_text(drw, m->ww - tw - 2 * sp, 0, tw, bh, 0, stext, 0);
}
for (c = m->clients; c; c = c->next) {
@@ -732,12 +734,12 @@ drawbar(Monitor *m)
if ((w = m->ww - tw - x) > bh) {
if (m->sel) {
drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]);
- drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0);
+ drw_text(drw, x, 0, w - 2 * sp, bh, lrpad / 2, m->sel->name, 0);
if (m->sel->isfloating)
drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0);
} else {
drw_setscheme(drw, scheme[SchemeNorm]);
- drw_rect(drw, x, 0, w, bh, 1, 1);
+ drw_rect(drw, x, 0, w - 2 * sp, bh, 1, 1);
}
}
drw_map(drw, m->barwin, 0, 0, m->ww, bh);
@@ -1548,6 +1550,9 @@ setup(void)
lrpad = drw->fonts->h;
bh = drw->fonts->h + 2;
updategeom();
+ sp = sidepad;
+ vp = (topbar == 1) ? vertpad : - vertpad;
+
/* init atoms */
utf8string = XInternAtom(dpy, "UTF8_STRING", False);
wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False);
@@ -1574,6 +1579,7 @@ setup(void)
/* init bars */
updatebars();
updatestatus();
+ updatebarpos(selmon);
/* supporting window for NetWMCheck */
wmcheckwin = XCreateSimpleWindow(dpy, root, 0, 0, 1, 1, 0, 0, 0);
XChangeProperty(dpy, wmcheckwin, netatom[NetWMCheck], XA_WINDOW, 32,
@@ -1704,7 +1710,7 @@ togglebar(const Arg *arg)
{
selmon->showbar = !selmon->showbar;
updatebarpos(selmon);
- XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh);
+ XMoveResizeWindow(dpy, selmon->barwin, selmon->wx + sp, selmon->by + vp, selmon->ww - 2 * sp, bh);
arrange(selmon);
}
@@ -1814,7 +1820,7 @@ updatebars(void)
for (m = mons; m; m = m->next) {
if (m->barwin)
continue;
- m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, DefaultDepth(dpy, screen),
+ m->barwin = XCreateWindow(dpy, root, m->wx + sp, m->by + vp, m->ww - 2 * sp, bh, 0, DefaultDepth(dpy, screen),
CopyFromParent, DefaultVisual(dpy, screen),
CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa);
XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor);
@@ -1829,11 +1835,11 @@ updatebarpos(Monitor *m)
m->wy = m->my;
m->wh = m->mh;
if (m->showbar) {
- m->wh -= bh;
- m->by = m->topbar ? m->wy : m->wy + m->wh;
- m->wy = m->topbar ? m->wy + bh : m->wy;
+ m->wh = m->wh - vertpad - bh;
+ m->by = m->topbar ? m->wy : m->wy + m->wh + vertpad;
+ m->wy = m->topbar ? m->wy + bh + vp : m->wy;
} else
- m->by = -bh;
+ m->by = -bh - vp;
}
void
--
2.27.0

+ 142
- 0
suckless/dwm/patches/dwm-centeredmaster-6.1.diff View File

@ -0,0 +1,142 @@
diff --git a/config.def.h b/config.def.h
index 7054c06..527b214 100644
--- a/config.def.h
+++ b/config.def.h
@@ -39,6 +39,8 @@ static const Layout layouts[] = {
{ "[]=", tile }, /* first entry is default */
{ "><>", NULL }, /* no layout function means floating behavior */
{ "[M]", monocle },
+ { "|M|", centeredmaster },
+ { ">M>", centeredfloatingmaster },
};
/* key definitions */
@@ -74,6 +76,8 @@ static Key keys[] = {
{ MODKEY, XK_t, setlayout, {.v = &layouts[0]} },
{ MODKEY, XK_f, setlayout, {.v = &layouts[1]} },
{ MODKEY, XK_m, setlayout, {.v = &layouts[2]} },
+ { MODKEY, XK_u, setlayout, {.v = &layouts[3]} },
+ { MODKEY, XK_o, setlayout, {.v = &layouts[4]} },
{ MODKEY, XK_space, setlayout, {0} },
{ MODKEY|ShiftMask, XK_space, togglefloating, {0} },
{ MODKEY, XK_0, view, {.ui = ~0 } },
diff --git a/dwm.c b/dwm.c
index 0362114..1e81412 100644
--- a/dwm.c
+++ b/dwm.c
@@ -233,6 +233,8 @@ static int xerror(Display *dpy, XErrorEvent *ee);
static int xerrordummy(Display *dpy, XErrorEvent *ee);
static int xerrorstart(Display *dpy, XErrorEvent *ee);
static void zoom(const Arg *arg);
+static void centeredmaster(Monitor *m);
+static void centeredfloatingmaster(Monitor *m);
/* variables */
static const char broken[] = "broken";
@@ -2139,3 +2141,106 @@ main(int argc, char *argv[])
XCloseDisplay(dpy);
return EXIT_SUCCESS;
}
+
+void
+centeredmaster(Monitor *m)
+{
+ unsigned int i, n, h, mw, mx, my, oty, ety, tw;
+ Client *c;
+
+ /* count number of clients in the selected monitor */
+ for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
+ if (n == 0)
+ return;
+
+ /* initialize areas */
+ mw = m->ww;
+ mx = 0;
+ my = 0;
+ tw = mw;
+
+ if (n > m->nmaster) {
+ /* go mfact box in the center if more than nmaster clients */
+ mw = m->nmaster ? m->ww * m->mfact : 0;
+ tw = m->ww - mw;
+
+ if (n - m->nmaster > 1) {
+ /* only one client */
+ mx = (m->ww - mw) / 2;
+ tw = (m->ww - mw) / 2;
+ }
+ }
+
+ oty = 0;
+ ety = 0;
+ for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
+ if (i < m->nmaster) {
+ /* nmaster clients are stacked vertically, in the center
+ * of the screen */
+ h = (m->wh - my) / (MIN(n, m->nmaster) - i);
+ resize(c, m->wx + mx, m->wy + my, mw - (2*c->bw),
+ h - (2*c->bw), 0);
+ my += HEIGHT(c);
+ } else {
+ /* stack clients are stacked vertically */
+ if ((i - m->nmaster) % 2 ) {
+ h = (m->wh - ety) / ( (1 + n - i) / 2);
+ resize(c, m->wx, m->wy + ety, tw - (2*c->bw),
+ h - (2*c->bw), 0);
+ ety += HEIGHT(c);
+ } else {
+ h = (m->wh - oty) / ((1 + n - i) / 2);
+ resize(c, m->wx + mx + mw, m->wy + oty,
+ tw - (2*c->bw), h - (2*c->bw), 0);
+ oty += HEIGHT(c);
+ }
+ }
+}
+
+void
+centeredfloatingmaster(Monitor *m)
+{
+ unsigned int i, n, w, mh, mw, mx, mxo, my, myo, tx;
+ Client *c;
+
+ /* count number of clients in the selected monitor */
+ for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
+ if (n == 0)
+ return;
+
+ /* initialize nmaster area */
+ if (n > m->nmaster) {
+ /* go mfact box in the center if more than nmaster clients */
+ if (m->ww > m->wh) {
+ mw = m->nmaster ? m->ww * m->mfact : 0;
+ mh = m->nmaster ? m->wh * 0.9 : 0;
+ } else {
+ mh = m->nmaster ? m->wh * m->mfact : 0;
+ mw = m->nmaster ? m->ww * 0.9 : 0;
+ }
+ mx = mxo = (m->ww - mw) / 2;
+ my = myo = (m->wh - mh) / 2;
+ } else {
+ /* go fullscreen if all clients are in the master area */
+ mh = m->wh;
+ mw = m->ww;
+ mx = mxo = 0;
+ my = myo = 0;
+ }
+
+ for(i = tx = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
+ if (i < m->nmaster) {
+ /* nmaster clients are stacked horizontally, in the center
+ * of the screen */
+ w = (mw + mxo - mx) / (MIN(n, m->nmaster) - i);
+ resize(c, m->wx + mx, m->wy + my, w - (2*c->bw),
+ mh - (2*c->bw), 0);
+ mx += WIDTH(c);
+ } else {
+ /* stack clients are stacked horizontally */
+ w = (m->ww - tx) / (n - i);
+ resize(c, m->wx + tx, m->wy, w - (2*c->bw),
+ m->wh - (2*c->bw), 0);
+ tx += WIDTH(c);
+ }
+}

+ 117
- 0
suckless/dwm/patches/dwm-cfacts-20200913-61bb8b2.diff View File

@ -0,0 +1,117 @@
From c32a879432573d71dec7fcb4bf68927d2f4cdf10 Mon Sep 17 00:00:00 2001
From: iofq <cjriddz@protonmail.com>
Date: Sat, 12 Sep 2020 22:28:09 -0500
Subject: [PATCH] Fixed 'cfacts' patch failure due to upstream commit
'f09418bbb...'
---
config.def.h | 3 +++
dwm.c | 34 +++++++++++++++++++++++++++++++---
2 files changed, 34 insertions(+), 3 deletions(-)
diff --git a/config.def.h b/config.def.h
index 1c0b587..83910c1 100644
--- a/config.def.h
+++ b/config.def.h
@@ -70,6 +70,9 @@ static Key keys[] = {
{ MODKEY, XK_d, incnmaster, {.i = -1 } },
{ MODKEY, XK_h, setmfact, {.f = -0.05} },
{ MODKEY, XK_l, setmfact, {.f = +0.05} },
+ { MODKEY|ShiftMask, XK_h, setcfact, {.f = +0.25} },
+ { MODKEY|ShiftMask, XK_l, setcfact, {.f = -0.25} },
+ { MODKEY|ShiftMask, XK_o, setcfact, {.f = 0.00} },
{ MODKEY, XK_Return, zoom, {0} },
{ MODKEY, XK_Tab, view, {0} },
{ MODKEY|ShiftMask, XK_c, killclient, {0} },
diff --git a/dwm.c b/dwm.c
index 664c527..5233229 100644
--- a/dwm.c
+++ b/dwm.c
@@ -87,6 +87,7 @@ typedef struct Client Client;
struct Client {
char name[256];
float mina, maxa;
+ float cfact;
int x, y, w, h;
int oldx, oldy, oldw, oldh;
int basew, baseh, incw, inch, maxw, maxh, minw, minh;
@@ -201,6 +202,7 @@ static void setclientstate(Client *c, long state);
static void setfocus(Client *c);
static void setfullscreen(Client *c, int fullscreen);
static void setlayout(const Arg *arg);
+static void setcfact(const Arg *arg);
static void setmfact(const Arg *arg);
static void setup(void);
static void seturgent(Client *c, int urg);
@@ -1030,6 +1032,7 @@ manage(Window w, XWindowAttributes *wa)
c->w = c->oldw = wa->width;
c->h = c->oldh = wa->height;
c->oldbw = wa->border_width;
+ c->cfact = 1.0;
updatetitle(c);
if (XGetTransientForHint(dpy, w, &trans) && (t = wintoclient(trans))) {
@@ -1512,6 +1515,23 @@ setlayout(const Arg *arg)
drawbar(selmon);
}
+void setcfact(const Arg *arg) {
+ float f;
+ Client *c;
+
+ c = selmon->sel;
+
+ if(!arg || !c || !selmon->lt[selmon->sellt]->arrange)
+ return;
+ f = arg->f + c->cfact;
+ if(arg->f == 0.0)
+ f = 1.0;
+ else if(f < 0.25 || f > 4.0)
+ return;
+ c->cfact = f;
+ arrange(selmon);
+}
+
/* arg > 1.0 will set mfact absolutely */
void
setmfact(const Arg *arg)
@@ -1675,9 +1695,15 @@ void
tile(Monitor *m)
{
unsigned int i, n, h, mw, my, ty;
+ float mfacts = 0, sfacts = 0;
Client *c;
- for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
+ for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) {
+ if (n < m->nmaster)
+ mfacts += c->cfact;
+ else
+ sfacts += c->cfact;
+ }
if (n == 0)
return;
@@ -1687,15 +1713,17 @@ tile(Monitor *m)
mw = m->ww;
for (i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
if (i < m->nmaster) {
- h = (m->wh - my) / (MIN(n, m->nmaster) - i);
+ h = (m->wh - my) * (c->cfact / mfacts);
resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), 0);
if (my + HEIGHT(c) < m->wh)
my += HEIGHT(c);
+ mfacts -= c->cfact;
} else {
- h = (m->wh - ty) / (n - i);
+ h = (m->wh - ty) * (c->cfact / sfacts);
resize(c, m->wx + mw, m->wy + ty, m->ww - mw - (2*c->bw), h - (2*c->bw), 0);
if (ty + HEIGHT(c) < m->wh)
ty += HEIGHT(c);
+ sfacts -= c->cfact;
}
}
--
2.28.0

+ 180
- 0
suckless/dwm/patches/dwm-cfacts_centeredmaster-6.2.diff View File

@ -0,0 +1,180 @@
diff -up a/config.def.h b/config.def.h
--- a/config.def.h 2019-06-05 02:24:05.503321320 +0200
+++ b/config.def.h 2019-06-05 10:46:48.099997829 +0200
@@ -41,6 +41,8 @@ static const Layout layouts[] = {
{ "[]=", tile }, /* first entry is default */
{ "><>", NULL }, /* no layout function means floating behavior */
{ "[M]", monocle },
+ { "|M|", centeredmaster },
+ { ">M>", centeredfloatingmaster },
};
/* key definitions */
@@ -79,6 +81,8 @@ static Key keys[] = {
{ MODKEY, XK_t, setlayout, {.v = &layouts[0]} },
{ MODKEY, XK_f, setlayout, {.v = &layouts[1]} },
{ MODKEY, XK_m, setlayout, {.v = &layouts[2]} },
+ { MODKEY, XK_u, setlayout, {.v = &layouts[3]} },
+ { MODKEY, XK_o, setlayout, {.v = &layouts[4]} },
{ MODKEY, XK_space, setlayout, {0} },
{ MODKEY|ShiftMask, XK_space, togglefloating, {0} },
{ MODKEY, XK_0, view, {.ui = ~0 } },
Only in a: config.def.h.orig
Only in b: dwm-bottomstack-20160719-56a31dc.diff
diff -up a/dwm.c b/dwm.c
--- a/dwm.c 2019-06-05 02:25:40.169986187 +0200
+++ b/dwm.c 2019-06-05 10:48:42.443328992 +0200
@@ -235,6 +235,8 @@ static int xerror(Display *dpy, XErrorEv
static int xerrordummy(Display *dpy, XErrorEvent *ee);
static int xerrorstart(Display *dpy, XErrorEvent *ee);
static void zoom(const Arg *arg);
+static void centeredmaster(Monitor *m);
+static void centeredfloatingmaster(Monitor *m);
/* variables */
static const char broken[] = "broken";
@@ -2175,3 +2177,144 @@ main(int argc, char *argv[])
XCloseDisplay(dpy);
return EXIT_SUCCESS;
}
+
+void
+centeredmaster(Monitor *m)
+{
+ unsigned int i, n, h, mw, mx, my, oty, ety, tw;
+ float mfacts = 0, lfacts = 0, rfacts = 0;
+ Client *c;
+
+ /* count number of clients in the selected monitor */
+ for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) {
+ if (n < m->nmaster)
+ mfacts += c->cfact;
+ else if ((n - m->nmaster) % 2)
+ lfacts += c->cfact;
+ else
+ rfacts += c->cfact;
+ }
+ if (n == 0)
+ return;
+ if(n == 1){
+ c = nexttiled(m->clients);
+ resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, 0);
+ return;
+ }
+
+ /* initialize areas */
+ mw = m->ww;
+ mx = 0;
+ my = 0;
+ tw = mw;
+
+ if (n > m->nmaster) {
+ /* go mfact box in the center if more than nmaster clients */
+ mw = m->nmaster ? m->ww * m->mfact : 0;
+ tw = m->ww - mw;
+
+ if (n - m->nmaster > 1) {
+ /* only one client */
+ mx = (m->ww - mw) / 2;
+ tw = (m->ww - mw) / 2;
+ }
+ }
+
+ oty = 0;
+ ety = 0;
+ for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
+ if (i < m->nmaster) {
+ /* nmaster clients are stacked vertically, in the center
+ * of the screen */
+ h = (m->wh - my) * (c->cfact / mfacts);
+ resize(c, m->wx + mx, m->wy + my, mw - 2*c->bw,
+ h - 2*c->bw, 0);
+ if(my + HEIGHT(c) < m->mh)
+ my += HEIGHT(c);
+ mfacts -= c->cfact;
+ } else {
+ /* stack clients are stacked vertically */
+ if ((i - m->nmaster) % 2) {
+ h = (m->wh - ety) * (c->cfact / lfacts);
+ if(m->nmaster == 0)
+ resize(c, m->wx, m->wy + ety, tw - 2*c->bw,
+ h - 2*c->bw, 0);
+ else
+ resize(c, m->wx, m->wy + ety, tw - 2*c->bw,
+ h - 2*c->bw, 0);
+ if(ety + HEIGHT(c) < m->mh)
+ ety += HEIGHT(c);
+ lfacts -= c->cfact;
+ } else {
+ h = (m->wh - oty) * (c->cfact / rfacts);
+ resize(c, m->wx + mx + mw, m->wy + oty,
+ tw - 2*c->bw, h - 2*c->bw, 0);
+ if(oty + HEIGHT(c) < m->mh)
+ oty += HEIGHT(c);
+ rfacts -= c->cfact;
+ }
+ }
+}
+
+void
+centeredfloatingmaster(Monitor *m)
+{
+ unsigned int i, n, w, mh, mw, mx, mxo, my, myo, tx;
+ float mfacts = 0, sfacts = 0;
+ Client *c;
+
+ /* count number of clients in the selected monitor */
+ for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) {
+ if (n < m->nmaster)
+ mfacts += c->cfact;
+ else
+ sfacts += c->cfact;
+ }
+ if (n == 0)
+ return;
+ if(n == 1){
+ c = nexttiled(m->clients);
+ resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, 0);
+ return;
+ }
+
+ /* initialize nmaster area */
+ if (n > m->nmaster) {
+ /* go mfact box in the center if more than nmaster clients */
+ if (m->ww > m->wh) {
+ mw = m->nmaster ? m->ww * m->mfact : 0;
+ mh = m->nmaster ? m->wh * 0.9 : 0;
+ } else {
+ mh = m->nmaster ? m->wh * m->mfact : 0;
+ mw = m->nmaster ? m->ww * 0.9 : 0;
+ }
+ mx = mxo = (m->ww - mw) / 2;
+ my = myo = (m->wh - mh) / 2;
+ } else {
+ /* go fullscreen if all clients are in the master area */
+ mh = m->wh;
+ mw = m->ww;
+ mx = mxo = 0;
+ my = myo = 0;
+ }
+
+ for(i = tx = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
+ if (i < m->nmaster) {
+ /* nmaster clients are stacked horizontally, in the center
+ * of the screen */
+ w = (mw + mxo - mx) * (c->cfact / mfacts);
+ resize(c, m->wx + mx, m->wy + my, w - 2*c->bw,
+ mh - 2*c->bw, 0);
+ if(mx + WIDTH(c) < m->mw)
+ mx += WIDTH(c);
+ mfacts -= c->cfact;
+ } else {
+ /* stack clients are stacked horizontally */
+ w = (m->ww - tx) * (c->cfact / sfacts);
+ resize(c, m->wx + tx, m->wy, w - 2*c->bw,
+ m->wh - 2*c->bw, 0);
+ if(tx + WIDTH(c) < m->mw)
+ tx += WIDTH(c);
+ sfacts -= c->cfact;
+ }
+}

+ 68
- 0
suckless/dwm/patches/dwm-colorbar-6.2.diff View File

@ -0,0 +1,68 @@
diff --git a/config.def.h b/config.def.h
index 1c0b587..a516645 100644
--- a/config.def.h
+++ b/config.def.h
@@ -16,6 +16,11 @@ static const char *colors[][3] = {
/* fg bg border */
[SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
[SchemeSel] = { col_gray4, col_cyan, col_cyan },
+ [SchemeStatus] = { col_gray3, col_gray1, "#000000" }, // Statusbar right {text,background,not used but cannot be empty}
+ [SchemeTagsSel] = { col_gray4, col_cyan, "#000000" }, // Tagbar left selected {text,background,not used but cannot be empty}
+ [SchemeTagsNorm] = { col_gray3, col_gray1, "#000000" }, // Tagbar left unselected {text,background,not used but cannot be empty}
+ [SchemeInfoSel] = { col_gray4, col_cyan, "#000000" }, // infobar middle selected {text,background,not used but cannot be empty}
+ [SchemeInfoNorm] = { col_gray3, col_gray1, "#000000" }, // infobar middle unselected {text,background,not used but cannot be empty}
};
/* tagging */
diff --git a/dwm.c b/dwm.c
index 4465af1..0d1d2f7 100644
--- a/dwm.c
+++ b/dwm.c
@@ -59,7 +59,7 @@
/* enums */
enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
-enum { SchemeNorm, SchemeSel }; /* color schemes */
+enum { SchemeNorm, SchemeSel, SchemeStatus, SchemeTagsSel, SchemeTagsNorm, SchemeInfoSel, SchemeInfoNorm }; /* color schemes */
enum { NetSupported, NetWMName, NetWMState, NetWMCheck,
NetWMFullscreen, NetActiveWindow, NetWMWindowType,
NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */
@@ -703,7 +703,7 @@ drawbar(Monitor *m)
/* draw status first so it can be overdrawn by tags later */
if (m == selmon) { /* status is only drawn on selected monitor */
- drw_setscheme(drw, scheme[SchemeNorm]);
+ drw_setscheme(drw, scheme[SchemeStatus]);
sw = TEXTW(stext) - lrpad + 2; /* 2px right padding */
drw_text(drw, m->ww - sw, 0, sw, bh, 0, stext, 0);
}
@@ -716,7 +716,7 @@ drawbar(Monitor *m)
x = 0;
for (i = 0; i < LENGTH(tags); i++) {
w = TEXTW(tags[i]);
- drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]);
+ drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeTagsSel : SchemeTagsNorm]);
drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i);
if (occ & 1 << i)
drw_rect(drw, x + boxs, boxs, boxw, boxw,
@@ -725,17 +725,17 @@ drawbar(Monitor *m)
x += w;
}
w = blw = TEXTW(m->ltsymbol);
- drw_setscheme(drw, scheme[SchemeNorm]);
+ drw_setscheme(drw, scheme[SchemeTagsNorm]);
x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0);
if ((w = m->ww - sw - x) > bh) {
if (m->sel) {
- drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]);
+ drw_setscheme(drw, scheme[m == selmon ? SchemeInfoSel : SchemeInfoNorm]);
drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0);
if (m->sel->isfloating)
drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0);
} else {
- drw_setscheme(drw, scheme[SchemeNorm]);
+ drw_setscheme(drw, scheme[SchemeInfoNorm]);
drw_rect(drw, x, 0, w, bh, 1, 1);
}
}

+ 93
- 0
suckless/dwm/patches/dwm-cyclelayouts-20180524-6.2.diff View File

@ -0,0 +1,93 @@
From a09e766a4342f580582082a92b2de65f33208eb4 Mon Sep 17 00:00:00 2001
From: Christopher Drelich <cd@cdrakka.com>
Date: Thu, 24 May 2018 00:56:56 -0400
Subject: [PATCH] Function to cycle through available layouts.
MOD-CTRL-, and MOD-CTRL-.
cycle backwards and forwards through available layouts.
Probably only useful if you have a lot of additional layouts.
The NULL, NULL layout should always be the last layout in your list,
in order to guarantee consistent behavior.
---
config.def.h | 3 +++
dwm.1 | 6 ++++++
dwm.c | 18 ++++++++++++++++++
3 files changed, 27 insertions(+)
diff --git a/config.def.h b/config.def.h
index a9ac303..153b880 100644
--- a/config.def.h
+++ b/config.def.h
@@ -41,6 +41,7 @@ static const Layout layouts[] = {
{ "[]=", tile }, /* first entry is default */
{ "><>", NULL }, /* no layout function means floating behavior */
{ "[M]", monocle },
+ { NULL, NULL },
};
/* key definitions */
@@ -76,6 +77,8 @@ static Key keys[] = {
{ MODKEY, XK_t, setlayout, {.v = &layouts[0]} },
{ MODKEY, XK_f, setlayout, {.v = &layouts[1]} },
{ MODKEY, XK_m, setlayout, {.v = &layouts[2]} },
+ { MODKEY|ControlMask, XK_comma, cyclelayout, {.i = -1 } },
+ { MODKEY|ControlMask, XK_period, cyclelayout, {.i = +1 } },
{ MODKEY, XK_space, setlayout, {0} },
{ MODKEY|ShiftMask, XK_space, togglefloating, {0} },
{ MODKEY, XK_0, view, {.ui = ~0 } },
diff --git a/dwm.1 b/dwm.1
index 13b3729..165891b 100644
--- a/dwm.1
+++ b/dwm.1
@@ -92,6 +92,12 @@ Sets monocle layout.
.B Mod1\-space
Toggles between current and previous layout.
.TP
+.B Mod1\-Control\-,
+Cycles backwards in layout list.
+.TP
+.B Mod1\-Control\-.
+Cycles forwards in layout list.
+.TP
.B Mod1\-j
Focus next window.
.TP
diff --git a/dwm.c b/dwm.c
index bb95e26..db73000 100644
--- a/dwm.c
+++ b/dwm.c
@@ -157,6 +157,7 @@ static void configure(Client *c);
static void configurenotify(XEvent *e);
static void configurerequest(XEvent *e);
static Monitor *createmon(void);
+static void cyclelayout(const Arg *arg);
static void destroynotify(XEvent *e);
static void detach(Client *c);
static void detachstack(Client *c);
@@ -645,6 +646,23 @@ createmon(void)
}
void
+cyclelayout(const Arg *arg) {
+ Layout *l;
+ for(l = (Layout *)layouts; l != selmon->lt[selmon->sellt]; l++);
+ if(arg->i > 0) {
+ if(l->symbol && (l + 1)->symbol)
+ setlayout(&((Arg) { .v = (l + 1) }));
+ else
+ setlayout(&((Arg) { .v = layouts }));
+ } else {
+ if(l != layouts && (l - 1)->symbol)
+ setlayout(&((Arg) { .v = (l - 1) }));
+ else
+ setlayout(&((Arg) { .v = &layouts[LENGTH(layouts) - 2] }));
+ }
+}
+
+void
destroynotify(XEvent *e)
{
Client *c;
--
2.7.4

+ 90
- 0
suckless/dwm/patches/dwm-deck-6.0.diff View File

@ -0,0 +1,90 @@
From cb3cac91db32403bb581aecbc2957b00bb49c898 Mon Sep 17 00:00:00 2001
From: aleks <aleks.stier@icloud.com>
Date: Mon, 6 May 2019 16:34:58 +0200
Subject: [PATCH] Add deck-layout
deck is a dwm-layout which is inspired by the TTWM window manager.
It applies the monocle-layout to the clients in the stack.
The master-client is still visible. The stacked clients are like
a deck of cards, hence the name.
The vanilla patch doesn't work properly with patches which add gaps.
This means that when the deck-layout is activated gaps are omitted.
To make it work with the tilegap-patch apply the dwm-deck-tilegap patch
on top of the dwm-deck patch.
The vanilla patch doesn't respect the master-area which is defined by
the rmaster-patch. To make it work with the rmaster-patch apply the
dwm-deck-rmaster patch on top of the dwm-deck patch.
---
config.def.h | 2 ++
dwm.c | 26 ++++++++++++++++++++++++++
2 files changed, 28 insertions(+)
diff --git a/config.def.h b/config.def.h
index 77ff358..55d8a07 100644
--- a/config.def.h
+++ b/config.def.h
@@ -32,6 +32,7 @@ static const Layout layouts[] = {
{ "[]=", tile }, /* first entry is default */
{ "><>", NULL }, /* no layout function means floating behavior */
{ "[M]", monocle },
+ { "[D]", deck },
};
/* key definitions */
@@ -66,6 +67,7 @@ static Key keys[] = {
{ MODKEY, XK_t, setlayout, {.v = &layouts[0]} },
{ MODKEY, XK_f, setlayout, {.v = &layouts[1]} },
{ MODKEY, XK_m, setlayout, {.v = &layouts[2]} },
+ { MODKEY, XK_c, setlayout, {.v = &layouts[3]} },
{ MODKEY, XK_space, setlayout, {0} },
{ MODKEY|ShiftMask, XK_space, togglefloating, {0} },
{ MODKEY, XK_0, view, {.ui = ~0 } },
diff --git a/dwm.c b/dwm.c
index 1d78655..356ab44 100644
--- a/dwm.c
+++ b/dwm.c
@@ -171,6 +171,7 @@ static void configure(Client *c);
static void configurenotify(XEvent *e);
static void configurerequest(XEvent *e);
static Monitor *createmon(void);
+static void deck(Monitor *m);
static void destroynotify(XEvent *e);
static void detach(Client *c);
static void detachstack(Client *c);
@@ -669,6 +670,31 @@ destroynotify(XEvent *e) {
unmanage(c, True);
}
+void
+deck(Monitor *m) {
+ unsigned int i, n, h, mw, my;
+ Client *c;
+
+ for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
+ if(n == 0)
+ return;
+
+ if(n > m->nmaster) {
+ mw = m->nmaster ? m->ww * m->mfact : 0;
+ snprintf(m->ltsymbol, sizeof m->ltsymbol, "[%d]", n - m->nmaster);
+ }
+ else
+ mw = m->ww;
+ for(i = my = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
+ if(i < m->nmaster) {
+ h = (m->wh - my) / (MIN(n, m->nmaster) - i);
+ resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), False);
+ my += HEIGHT(c);
+ }
+ else
+ resize(c, m->wx + mw, m->wy, m->ww - mw - (2*c->bw), m->wh - (2*c->bw), False);
+}
+
void
detach(Client *c) {
Client **tc;
--
2.21.0

+ 340
- 0
suckless/dwm/patches/dwm-dwmblocks-6.2.diff View File

@ -0,0 +1,340 @@
diff -ruN dwm-6.2-ori/config.def.h dwm-6.2/config.def.h
--- dwm-6.2-ori/config.def.h 2019-02-02 18:25:28.000000000 +0530
+++ dwm-6.2/config.def.h 2020-07-30 00:13:59.458409207 +0530
@@ -12,10 +12,34 @@
static const char col_gray3[] = "#bbbbbb";
static const char col_gray4[] = "#eeeeee";
static const char col_cyan[] = "#005577";
+static const char col1[] = "#ffffff";
+static const char col2[] = "#ffffff";
+static const char col3[] = "#ffffff";
+static const char col4[] = "#ffffff";
+static const char col5[] = "#ffffff";
+static const char col6[] = "#ffffff";
+static const char col7[] = "#ffffff";
+static const char col8[] = "#ffffff";
+static const char col9[] = "#ffffff";
+static const char col10[] = "#ffffff";
+static const char col11[] = "#ffffff";
+static const char col12[] = "#ffffff";
static const char *colors[][3] = {
/* fg bg border */
- [SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
- [SchemeSel] = { col_gray4, col_cyan, col_cyan },
+ [SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
+ [SchemeSel] = { col_gray4, col_cyan, col_cyan },
+ [SchemeCol1] = { col1, col_gray1, col_gray2 },
+ [SchemeCol2] = { col2, col_gray1, col_gray2 },
+ [SchemeCol3] = { col3, col_gray1, col_gray2 },
+ [SchemeCol4] = { col4, col_gray1, col_gray2 },
+ [SchemeCol5] = { col5, col_gray1, col_gray2 },
+ [SchemeCol6] = { col6, col_gray1, col_gray2 },
+ [SchemeCol7] = { col7, col_gray1, col_gray2 },
+ [SchemeCol8] = { col8, col_gray1, col_gray2 },
+ [SchemeCol9] = { col8, col_gray1, col_gray2 },
+ [SchemeCol10] = { col10, col_gray1, col_gray2 },
+ [SchemeCol11] = { col11, col_gray1, col_gray2 },
+ [SchemeCol12] = { col12, col_gray1, col_gray2 },
};
/* tagging */
@@ -103,7 +127,9 @@
{ ClkLtSymbol, 0, Button1, setlayout, {0} },
{ ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} },
{ ClkWinTitle, 0, Button2, zoom, {0} },
- { ClkStatusText, 0, Button2, spawn, {.v = termcmd } },
+ { ClkStatusText, 0, Button1, sigdwmblocks, {.i = 1} },
+ { ClkStatusText, 0, Button2, sigdwmblocks, {.i = 2} },
+ { ClkStatusText, 0, Button3, sigdwmblocks, {.i = 3} },
{ ClkClientWin, MODKEY, Button1, movemouse, {0} },
{ ClkClientWin, MODKEY, Button2, togglefloating, {0} },
{ ClkClientWin, MODKEY, Button3, resizemouse, {0} },
diff -ruN dwm-6.2-ori/dwm.c dwm-6.2/dwm.c
--- dwm-6.2-ori/dwm.c 2019-02-02 18:25:28.000000000 +0530
+++ dwm-6.2/dwm.c 2020-07-30 00:22:43.991855443 +0530
@@ -40,6 +40,8 @@
#include <X11/extensions/Xinerama.h>
#endif /* XINERAMA */
#include <X11/Xft/Xft.h>
+#include <fcntl.h>
+#include <sys/prctl.h>
#include "drw.h"
#include "util.h"
@@ -56,10 +58,15 @@
#define HEIGHT(X) ((X)->h + 2 * (X)->bw)
#define TAGMASK ((1 << LENGTH(tags)) - 1)
#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad)
+#define TTEXTW(X) drw_fontset_getwidth(drw, (X))
+
+#define DWMBLOCKSLOCKFILE "/tmp/dwmblocks.pid"
/* enums */
-enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
-enum { SchemeNorm, SchemeSel }; /* color schemes */
+enum { CurNormal, CurHand, CurResize, CurMove, CurLast }; /* cursor */
+enum { SchemeNorm, SchemeSel, SchemeCol1, SchemeCol2, SchemeCol3,
+ SchemeCol4, SchemeCol5, SchemeCol6, SchemeCol7, SchemeCol8,
+ SchemeCol9, SchemeCol10, SchemeCol11, SchemeCol12 }; /* color schemes */
enum { NetSupported, NetWMName, NetWMState, NetWMCheck,
NetWMFullscreen, NetActiveWindow, NetWMWindowType,
NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */
@@ -205,6 +212,7 @@
static void seturgent(Client *c, int urg);
static void showhide(Client *c);
static void sigchld(int unused);
+static void sigdwmblocks(const Arg *arg);
static void spawn(const Arg *arg);
static void tag(const Arg *arg);
static void tagmon(const Arg *arg);
@@ -216,9 +224,11 @@
static void unfocus(Client *c, int setfocus);
static void unmanage(Client *c, int destroyed);
static void unmapnotify(XEvent *e);
+static void updatebarcursor(int cursorpos);
static void updatebarpos(Monitor *m);
static void updatebars(void);
static void updateclientlist(void);
+static void updatedwmblockssig(int x, int e);
static int updategeom(void);
static void updatenumlockmask(void);
static void updatesizehints(Client *c);
@@ -236,7 +246,10 @@
/* variables */
static const char broken[] = "broken";
-static char stext[256];
+static char stextc[256];
+static char stexts[256];
+static int wstext;
+static int dwmblockssig;
static int screen;
static int sw, sh; /* X display screen geometry width, height */
static int bh, blw = 0; /* bar geometry */
@@ -439,10 +452,14 @@
arg.ui = 1 << i;
} else if (ev->x < x + blw)
click = ClkLtSymbol;
- else if (ev->x > selmon->ww - TEXTW(stext))
- click = ClkStatusText;
- else
- click = ClkWinTitle;
+ else if (ev->x < selmon->ww - wstext)
+ click = ClkWinTitle;
+// else if (ev->x < selmon->ww - lrpad / 2 && ev->x >= (x = selmon->ww - wstext + lrpad / 2)) {
+ else if (ev->x < selmon->ww - lrpad / 2 && ev->x >= selmon->ww - wstext + lrpad / 2) {
+ click = ClkStatusText;
+// updatedwmblockssig(x, ev->x);
+ } else
+ return;
} else if ((c = wintoclient(ev->window))) {
focus(c);
restack(selmon);
@@ -695,7 +712,7 @@
void
drawbar(Monitor *m)
{
- int x, w, sw = 0;
+ int x, w;
int boxs = drw->fonts->h / 9;
int boxw = drw->fonts->h / 6 + 2;
unsigned int i, occ = 0, urg = 0;
@@ -703,9 +720,30 @@
/* draw status first so it can be overdrawn by tags later */
if (m == selmon) { /* status is only drawn on selected monitor */
- drw_setscheme(drw, scheme[SchemeNorm]);
- sw = TEXTW(stext) - lrpad + 2; /* 2px right padding */
- drw_text(drw, m->ww - sw, 0, sw, bh, 0, stext, 0);
+ char *ts = stextc;
+ char *tp = stextc;
+ char ctmp;
+
+ drw_setscheme(drw, scheme[SchemeNorm]);
+ x = drw_text(drw, m->ww - wstext, 0, lrpad / 2, bh, 0, "", 0); /* to keep left padding clean */
+ for (;;) {
+ if ((unsigned char)*ts > LENGTH(colors) + 10) {
+ ts++;
+ continue;
+ }
+ ctmp = *ts;
+ *ts = '\0';
+ if (*tp != '\0')
+ x = drw_text(drw, x, 0, TTEXTW(tp), bh, 0, tp, 0);
+ if (ctmp == '\0')
+ break;
+ /* - 11 to compensate for + 10 above */
+ drw_setscheme(drw, scheme[(unsigned char)ctmp - 11]);
+ *ts = ctmp;
+ tp = ++ts;
+ }
+ drw_setscheme(drw, scheme[SchemeNorm]);
+ drw_text(drw, x, 0, m->ww - x, bh, 0, "", 0); /* to keep right padding clean */
}
for (c = m->clients; c; c = c->next) {
@@ -728,7 +766,7 @@
drw_setscheme(drw, scheme[SchemeNorm]);
x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0);
- if ((w = m->ww - sw - x) > bh) {
+ if ((w = m->ww - wstext - x) > bh) {
if (m->sel) {
drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]);
drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0);
@@ -1122,8 +1160,11 @@
Monitor *m;
XMotionEvent *ev = &e->xmotion;
- if (ev->window != root)
+ if (ev->window != root) {
+ if (ev->window == selmon->barwin)
+ updatebarcursor(ev->x);
return;
+ }
if ((m = recttomon(ev->x_root, ev->y_root, 1, 1)) != mon && mon) {
unfocus(selmon->sel, 1);
selmon = m;
@@ -1564,6 +1605,7 @@
netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", False);
/* init cursors */
cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr);
+ cursor[CurHand] = drw_cur_create(drw, XC_hand2);
cursor[CurResize] = drw_cur_create(drw, XC_sizing);
cursor[CurMove] = drw_cur_create(drw, XC_fleur);
/* init appearance */
@@ -1637,6 +1679,28 @@
}
void
+sigdwmblocks(const Arg *arg)
+{
+ int fd;
+ struct flock fl;
+ union sigval sv;
+
+ if (dwmblockssig <= 0 || dwmblockssig >= 10)
+ return;
+ sv.sival_int = (dwmblockssig << 8) | arg->i;
+ fd = open(DWMBLOCKSLOCKFILE, O_RDONLY);
+ if (fd == -1)
+ return;
+ fl.l_type = F_WRLCK;
+ fl.l_start = 0;
+ fl.l_whence = SEEK_SET;
+ fl.l_len = 0;
+ if (fcntl(fd, F_GETLK, &fl) == -1 || fl.l_type == F_UNLCK)
+ return;
+ sigqueue(fl.l_pid, SIGRTMIN, sv);
+}
+
+void
spawn(const Arg *arg)
{
if (arg->v == dmenucmd)
@@ -1805,7 +1869,7 @@
XSetWindowAttributes wa = {
.override_redirect = True,
.background_pixmap = ParentRelative,
- .event_mask = ButtonPressMask|ExposureMask
+ .event_mask = ButtonPressMask|ExposureMask|PointerMotionMask
};
XClassHint ch = {"dwm", "dwm"};
for (m = mons; m; m = m->next) {
@@ -1821,6 +1885,33 @@
}
void
+updatebarcursor(int cursorpos)
+{
+ static int currentcursor = 0;
+ int x;
+
+ if (BETWEEN(cursorpos, (x = selmon->ww - wstext + lrpad / 2), x + wstext - lrpad)) {
+ updatedwmblockssig(x, cursorpos);
+ if (currentcursor) {
+ if (dwmblockssig <= 0 || dwmblockssig >= 10) {
+ currentcursor = 0;
+ XDefineCursor(dpy, selmon->barwin, cursor[CurNormal]->cursor);
+ }
+ } else {
+ if (dwmblockssig > 0 && dwmblockssig < 10) {
+ currentcursor = 1;
+ XDefineCursor(dpy, selmon->barwin, cursor[CurHand]->cursor);
+ }
+ }
+ } else {
+ if (currentcursor) {
+ currentcursor = 0;
+ XDefineCursor(dpy, selmon->barwin, cursor[CurNormal]->cursor);
+ }
+ }
+}
+
+void
updatebarpos(Monitor *m)
{
m->wy = m->my;
@@ -1847,6 +1938,31 @@
(unsigned char *) &(c->win), 1);
}
+void
+updatedwmblockssig(int x, int e)
+{
+ char *ts = stexts;
+ char *tp = stexts;
+ char ctmp;
+
+ while (*ts != '\0') {
+ if ((unsigned char)*ts > 10) {
+ ts++;
+ continue;
+ }
+ ctmp = *ts;
+ *ts = '\0';
+ x += TTEXTW(tp);
+ *ts = ctmp;
+ if (x >= e) {
+ dwmblockssig = (unsigned char)ctmp;
+ return;
+ }
+ tp = ++ts;
+ }
+ dwmblockssig = 0;
+}
+
int
updategeom(void)
{
@@ -1987,9 +2103,27 @@
void
updatestatus(void)
{
- if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext)))
- strcpy(stext, "dwm-"VERSION);
- drawbar(selmon);
+ char rawstext[256];
+
+ if (gettextprop(root, XA_WM_NAME, rawstext, sizeof rawstext)) {
+ char stextt[256];
+ char *stc = stextc, *sts = stexts, *stt = stextt;
+
+ for (char *rt = rawstext; *rt != '\0'; rt++)
+ if ((unsigned char)*rt >= ' ')
+ *(stc++) = *(sts++) = *(stt++) = *rt;
+ else if ((unsigned char)*rt > 10)
+ *(stc++) = *rt;
+ else
+ *(sts++) = *rt;
+ *stc = *sts = *stt = '\0';
+ wstext = TEXTW(stextt);
+ } else {
+ strcpy(stextc, "dwm-"VERSION);
+ strcpy(stexts, stextc);
+ wstext = TEXTW(stextc);
+ }
+ drawbar(selmon);
}
void

+ 161
- 0
suckless/dwm/patches/dwm-ewmhtags-6.2.diff View File

@ -0,0 +1,161 @@
From e5f0eefa921e6bad1e6f75faced0c3ae519995b3 Mon Sep 17 00:00:00 2001
From: Ryan Kes <alrayyes@gmail.com>
Date: Thu, 28 Mar 2019 14:49:28 +0100
Subject: [PATCH] dwm-ewhmtags-6.2
---
dwm.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 48 insertions(+), 1 deletion(-)
diff --git a/dwm.c b/dwm.c
index 4465af1..92022a1 100644
--- a/dwm.c
+++ b/dwm.c
@@ -55,6 +55,7 @@
#define WIDTH(X) ((X)->w + 2 * (X)->bw)
#define HEIGHT(X) ((X)->h + 2 * (X)->bw)
#define TAGMASK ((1 << LENGTH(tags)) - 1)
+#define TAGSLENGTH (LENGTH(tags))
#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad)
/* enums */
@@ -62,7 +63,7 @@ enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
enum { SchemeNorm, SchemeSel }; /* color schemes */
enum { NetSupported, NetWMName, NetWMState, NetWMCheck,
NetWMFullscreen, NetActiveWindow, NetWMWindowType,
- NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */
+ NetWMWindowTypeDialog, NetClientList, NetDesktopNames, NetDesktopViewport, NetNumberOfDesktops, NetCurrentDesktop, NetLast }; /* EWMH atoms */
enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */
enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle,
ClkClientWin, ClkRootWin, ClkLast }; /* clicks */
@@ -197,11 +198,15 @@ static void scan(void);
static int sendevent(Client *c, Atom proto);
static void sendmon(Client *c, Monitor *m);
static void setclientstate(Client *c, long state);
+static void setcurrentdesktop(void);
+static void setdesktopnames(void);
static void setfocus(Client *c);
static void setfullscreen(Client *c, int fullscreen);
static void setlayout(const Arg *arg);
static void setmfact(const Arg *arg);
+static void setnumdesktops(void);
static void setup(void);
+static void setviewport(void);
static void seturgent(Client *c, int urg);
static void showhide(Client *c);
static void sigchld(int unused);
@@ -216,6 +221,7 @@ static void toggleview(const Arg *arg);
static void unfocus(Client *c, int setfocus);
static void unmanage(Client *c, int destroyed);
static void unmapnotify(XEvent *e);
+static void updatecurrentdesktop(void);
static void updatebarpos(Monitor *m);
static void updatebars(void);
static void updateclientlist(void);
@@ -1431,6 +1437,16 @@ setclientstate(Client *c, long state)
XChangeProperty(dpy, c->win, wmatom[WMState], wmatom[WMState], 32,
PropModeReplace, (unsigned char *)data, 2);
}
+void
+setcurrentdesktop(void){
+ long data[] = { 0 };
+ XChangeProperty(dpy, root, netatom[NetCurrentDesktop], XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data, 1);
+}
+void setdesktopnames(void){
+ XTextProperty text;
+ Xutf8TextListToTextProperty(dpy, tags, TAGSLENGTH, XUTF8StringStyle, &text);
+ XSetTextProperty(dpy, root, &text, netatom[NetDesktopNames]);
+}
int
sendevent(Client *c, Atom proto)
@@ -1457,6 +1473,12 @@ sendevent(Client *c, Atom proto)
return exists;
}
+void
+setnumdesktops(void){
+ long data[] = { TAGSLENGTH };
+ XChangeProperty(dpy, root, netatom[NetNumberOfDesktops], XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data, 1);
+}
+
void
setfocus(Client *c)
{
@@ -1562,6 +1584,10 @@ setup(void)
netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False);
netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False);
netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", False);
+ netatom[NetDesktopViewport] = XInternAtom(dpy, "_NET_DESKTOP_VIEWPORT", False);
+ netatom[NetNumberOfDesktops] = XInternAtom(dpy, "_NET_NUMBER_OF_DESKTOPS", False);
+ netatom[NetCurrentDesktop] = XInternAtom(dpy, "_NET_CURRENT_DESKTOP", False);
+ netatom[NetDesktopNames] = XInternAtom(dpy, "_NET_DESKTOP_NAMES", False);
/* init cursors */
cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr);
cursor[CurResize] = drw_cur_create(drw, XC_sizing);
@@ -1584,6 +1610,10 @@ setup(void)
/* EWMH support per view */
XChangeProperty(dpy, root, netatom[NetSupported], XA_ATOM, 32,
PropModeReplace, (unsigned char *) netatom, NetLast);
+ setnumdesktops();
+ setcurrentdesktop();
+ setdesktopnames();
+ setviewport();
XDeleteProperty(dpy, root, netatom[NetClientList]);
/* select events */
wa.cursor = cursor[CurNormal]->cursor;
@@ -1595,6 +1625,11 @@ setup(void)
grabkeys();
focus(NULL);
}
+void
+setviewport(void){
+ long data[] = { 0, 0 };
+ XChangeProperty(dpy, root, netatom[NetDesktopViewport], XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data, 2);
+}
void
@@ -1732,6 +1767,7 @@ toggletag(const Arg *arg)
focus(NULL);
arrange(selmon);
}
+ updatecurrentdesktop();
}
void
@@ -1744,6 +1780,7 @@ toggleview(const Arg *arg)
focus(NULL);
arrange(selmon);
}
+ updatecurrentdesktop();
}
void
@@ -1846,6 +1883,15 @@ updateclientlist()
XA_WINDOW, 32, PropModeAppend,
(unsigned char *) &(c->win), 1);
}
+void updatecurrentdesktop(void){
+ long rawdata[] = { selmon->tagset[selmon->seltags] };
+ int i=0;
+ while(*rawdata >> i+1){
+ i++;
+ }
+ long data[] = { i };
+ XChangeProperty(dpy, root, netatom[NetCurrentDesktop], XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data, 1);
+}
int
updategeom(void)
@@ -2042,6 +2088,7 @@ view(const Arg *arg)
selmon->tagset[selmon->seltags] = arg->ui & TAGMASK;
focus(NULL);
arrange(selmon);
+ updatecurrentdesktop();
}
Client *
--
2.21.0

+ 85
- 0
suckless/dwm/patches/dwm-fibonacci-5.8.2.diff View File

@ -0,0 +1,85 @@
diff --git a/config.def.h b/config.def.h
index cca37df..91b91aa 100644
--- a/config.def.h
+++ b/config.def.h
@@ -29,1 +29,2 @@
+#include "fibonacci.c"
static const Layout layouts[] = {
@@ -34,3 +35,5 @@
+ { "[@]", spiral },
+ { "[\\]", dwindle },
};
/* key definitions */
diff --git a/fibonacci.c b/fibonacci.c
new file mode 100644
index 0000000..fce0a57
--- /dev/null
+++ b/fibonacci.c
@@ -0,0 +1,66 @@
+void
+fibonacci(Monitor *mon, int s) {
+ unsigned int i, n, nx, ny, nw, nh;
+ Client *c;
+
+ for(n = 0, c = nexttiled(mon->clients); c; c = nexttiled(c->next), n++);
+ if(n == 0)
+ return;
+
+ nx = mon->wx;
+ ny = 0;
+ nw = mon->ww;
+ nh = mon->wh;
+
+ for(i = 0, c = nexttiled(mon->clients); c; c = nexttiled(c->next)) {
+ if((i % 2 && nh / 2 > 2 * c->bw)
+ || (!(i % 2) && nw / 2 > 2 * c->bw)) {
+ if(i < n - 1) {
+ if(i % 2)
+ nh /= 2;
+ else
+ nw /= 2;
+ if((i % 4) == 2 && !s)
+ nx += nw;
+ else if((i % 4) == 3 && !s)
+ ny += nh;
+ }
+ if((i % 4) == 0) {
+ if(s)
+ ny += nh;
+ else
+ ny -= nh;
+ }
+ else if((i % 4) == 1)
+ nx += nw;
+ else if((i % 4) == 2)
+ ny += nh;
+ else if((i % 4) == 3) {
+ if(s)
+ nx += nw;
+ else
+ nx -= nw;
+ }
+ if(i == 0)
+ {
+ if(n != 1)
+ nw = mon->ww * mon->mfact;
+ ny = mon->wy;
+ }
+ else if(i == 1)
+ nw = mon->ww - nw;
+ i++;
+ }
+ resize(c, nx, ny, nw - 2 * c->bw, nh - 2 * c->bw, False);
+ }
+}
+
+void
+dwindle(Monitor *mon) {
+ fibonacci(mon, 1);
+}
+
+void
+spiral(Monitor *mon) {
+ fibonacci(mon, 0);
+}

+ 27
- 0
suckless/dwm/patches/dwm-fixborders-6.2.diff View File

@ -0,0 +1,27 @@
From 1529909466206016f2101457bbf37c67195714c8 Mon Sep 17 00:00:00 2001
From: Jakub Leszczak <szatan@gecc.xyz>
Date: Fri, 22 Nov 2019 10:46:53 +0800
Subject: [PATCH] Fix transparent borders
When terminal has transparency then its borders also become transparent.
Fix it by removing transparency from any pixels drawn.
---
drw.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drw.c b/drw.c
index 8fd1ca4..490a592 100644
--- a/drw.c
+++ b/drw.c
@@ -202,6 +202,8 @@ drw_clr_create(Drw *drw, Clr *dest, const char *clrname)
DefaultColormap(drw->dpy, drw->screen),
clrname, dest))
die("error, cannot allocate color '%s'", clrname);
+
+ dest->pixel |= 0xff << 24;
}
/* Wrapper to create color schemes. The caller has to call free(3) on the
--
2.26.2

+ 73
- 0
suckless/dwm/patches/dwm-gridmode-20170909-ceac8c9.diff View File

@ -0,0 +1,73 @@
From b04bb473cf9818277d33a591f7fe2dfae96afaaf Mon Sep 17 00:00:00 2001
From: Joshua Haase <hahj87@gmail.com>
Date: Mon, 15 Aug 2016 17:06:18 -0500
Subject: [PATCH] Apply modified gridmode patch.
---
config.def.h | 3 +++
layouts.c | 27 +++++++++++++++++++++++++++
2 files changed, 30 insertions(+)
create mode 100644 layouts.c
diff --git a/config.def.h b/config.def.h
index a9ac303..30b7c4a 100644
--- a/config.def.h
+++ b/config.def.h
@@ -36,11 +36,13 @@ static const float mfact = 0.55; /* factor of master area size [0.05..0.95]
static const int nmaster = 1; /* number of clients in master area */
static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */
+#include "layouts.c"
static const Layout layouts[] = {
/* symbol arrange function */
{ "[]=", tile }, /* first entry is default */
{ "><>", NULL }, /* no layout function means floating behavior */
{ "[M]", monocle },
+ { "HHH", grid },
};
/* key definitions */
@@ -76,6 +78,7 @@ static Key keys[] = {
{ MODKEY, XK_t, setlayout, {.v = &layouts[0]} },
{ MODKEY, XK_f, setlayout, {.v = &layouts[1]} },
{ MODKEY, XK_m, setlayout, {.v = &layouts[2]} },
+ { MODKEY, XK_g, setlayout, {.v = &layouts[3]} },
{ MODKEY, XK_space, setlayout, {0} },
{ MODKEY|ShiftMask, XK_space, togglefloating, {0} },
{ MODKEY, XK_0, view, {.ui = ~0 } },
diff --git a/layouts.c b/layouts.c
new file mode 100644
index 0000000..d26acf3
--- /dev/null
+++ b/layouts.c
@@ -0,0 +1,27 @@
+void
+grid(Monitor *m) {
+ unsigned int i, n, cx, cy, cw, ch, aw, ah, cols, rows;
+ Client *c;
+
+ for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next))
+ n++;
+
+ /* grid dimensions */
+ for(rows = 0; rows <= n/2; rows++)
+ if(rows*rows >= n)
+ break;
+ cols = (rows && (rows - 1) * rows >= n) ? rows - 1 : rows;
+
+ /* window geoms (cell height/width) */
+ ch = m->wh / (rows ? rows : 1);
+ cw = m->ww / (cols ? cols : 1);
+ for(i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next)) {
+ cx = m->wx + (i / rows) * cw;
+ cy = m->wy + (i % rows) * ch;
+ /* adjust height/width of last row/column's windows */
+ ah = ((i + 1) % rows == 0) ? m->wh - ch * rows : 0;
+ aw = (i >= rows * (cols - 1)) ? m->ww - cw * cols : 0;
+ resize(c, cx, cy, cw - 2 * c->bw + aw, ch - 2 * c->bw + ah, False);
+ i++;
+ }
+}
--
2.14.1

+ 108
- 0
suckless/dwm/patches/dwm-inplacerotate-6.2.diff View File

@ -0,0 +1,108 @@
From 75012a6ab9cc1b6c319af7f4ae7d682b16a66ce3 Mon Sep 17 00:00:00 2001
From: Miles Alan <m@milesalan.com>
Date: Sun, 26 Apr 2020 16:05:43 -0500
Subject: [PATCH] Add inplacerotate fn to rotate all, master, or stacks clients
inplace
CW (+2) or CCW (-2) Rotates all windows.
CW (+1) or CCW (-1) Rotates master xor stack windows (depending on focus).
Focus position stays 'in-place' so the area of the screen you are focused
on remains unchanged.
---
config.def.h | 4 ++++
dwm.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 63 insertions(+)
diff --git a/config.def.h b/config.def.h
index 1c0b587..9bcb792 100644
--- a/config.def.h
+++ b/config.def.h
@@ -66,6 +66,10 @@ static Key keys[] = {
{ MODKEY, XK_b, togglebar, {0} },
{ MODKEY, XK_j, focusstack, {.i = +1 } },
{ MODKEY, XK_k, focusstack, {.i = -1 } },
+ { MODKEY|ShiftMask, XK_j, inplacerotate, {.i = +1} },
+ { MODKEY|ShiftMask, XK_k, inplacerotate, {.i = -1} },
+ { MODKEY|ShiftMask, XK_h, inplacerotate, {.i = +2} },
+ { MODKEY|ShiftMask, XK_l, inplacerotate, {.i = -2} },
{ MODKEY, XK_i, incnmaster, {.i = +1 } },
{ MODKEY, XK_d, incnmaster, {.i = -1 } },
{ MODKEY, XK_h, setmfact, {.f = -0.05} },
diff --git a/dwm.c b/dwm.c
index 4465af1..3930680 100644
--- a/dwm.c
+++ b/dwm.c
@@ -175,6 +175,7 @@ static int gettextprop(Window w, Atom atom, char *text, unsigned int size);
static void grabbuttons(Client *c, int focused);
static void grabkeys(void);
static void incnmaster(const Arg *arg);
+static void inplacerotate(const Arg *arg);
static void keypress(XEvent *e);
static void killclient(const Arg *arg);
static void manage(Window w, XWindowAttributes *wa);
@@ -2147,3 +2148,61 @@ main(int argc, char *argv[])
XCloseDisplay(dpy);
return EXIT_SUCCESS;
}
+
+void
+insertclient(Client *item, Client *insertItem, int after) {
+ Client *c;
+ if (item == NULL || insertItem == NULL || item == insertItem) return;
+ detach(insertItem);
+ if (!after && selmon->clients == item) {
+ attach(insertItem);
+ return;
+ }
+ if (after) {
+ c = item;
+ } else {
+ for (c = selmon->clients; c; c = c->next) { if (c->next == item) break; }
+ }
+ insertItem->next = c->next;
+ c->next = insertItem;
+}
+
+void
+inplacerotate(const Arg *arg)
+{
+ if(!selmon->sel || (selmon->sel->isfloating && !arg->f)) return;
+
+ unsigned int selidx = 0, i = 0;
+ Client *c = NULL, *stail = NULL, *mhead = NULL, *mtail = NULL, *shead = NULL;
+
+ // Determine positionings for insertclient
+ for (c = selmon->clients; c; c = c->next) {
+ if (ISVISIBLE(c) && !(c->isfloating)) {
+ if (selmon->sel == c) { selidx = i; }
+ if (i == selmon->nmaster - 1) { mtail = c; }
+ if (i == selmon->nmaster) { shead = c; }
+ if (mhead == NULL) { mhead = c; }
+ stail = c;
+ i++;
+ }
+ }
+
+ // All clients rotate
+ if (arg->i == 2) insertclient(selmon->clients, stail, 0);
+ if (arg->i == -2) insertclient(stail, selmon->clients, 1);
+ // Stack xor master rotate
+ if (arg->i == -1 && selidx >= selmon->nmaster) insertclient(stail, shead, 1);
+ if (arg->i == 1 && selidx >= selmon->nmaster) insertclient(shead, stail, 0);
+ if (arg->i == -1 && selidx < selmon->nmaster) insertclient(mtail, mhead, 1);
+ if (arg->i == 1 && selidx < selmon->nmaster) insertclient(mhead, mtail, 0);
+
+ // Restore focus position
+ i = 0;
+ for (c = selmon->clients; c; c = c->next) {
+ if (!ISVISIBLE(c) || (c->isfloating)) continue;
+ if (i == selidx) { focus(c); break; }
+ i++;
+ }
+ arrange(selmon);
+ focus(c);
+}
--
2.23.1

+ 69
- 0
suckless/dwm/patches/dwm-leftlayout-20180524-c8e9479.diff View File

@ -0,0 +1,69 @@
From 73f9b8a4563ff89953459feae5bdbda8bdff94e7 Mon Sep 17 00:00:00 2001
From: Christopher Drelich <cd@cdrakka.com>
Date: Thu, 24 May 2018 20:40:58 -0400
Subject: [PATCH] Moved layout symbol to left-hand side.
---
dwm.c | 31 +++++++++++++++++--------------
1 file changed, 17 insertions(+), 14 deletions(-)
diff --git a/dwm.c b/dwm.c
index bb95e26..9a57082 100644
--- a/dwm.c
+++ b/dwm.c
@@ -431,18 +431,21 @@ buttonpress(XEvent *e)
}
if (ev->window == selmon->barwin) {
i = x = 0;
- do
- x += TEXTW(tags[i]);
- while (ev->x >= x && ++i < LENGTH(tags));
- if (i < LENGTH(tags)) {
- click = ClkTagBar;
- arg.ui = 1 << i;
- } else if (ev->x < x + blw)
+ x += blw;
+ if (ev->x < x) {
click = ClkLtSymbol;
- else if (ev->x > selmon->ww - TEXTW(stext))
- click = ClkStatusText;
- else
- click = ClkWinTitle;
+ } else {
+ do
+ x += TEXTW(tags[i]);
+ while (ev->x >= x && ++i < LENGTH(tags));
+ if (i < LENGTH(tags)) {
+ click = ClkTagBar;
+ arg.ui = 1 << i;
+ } else if (ev->x > selmon->ww - TEXTW(stext))
+ click = ClkStatusText;
+ else
+ click = ClkWinTitle;
+ }
} else if ((c = wintoclient(ev->window))) {
focus(c);
restack(selmon);
@@ -714,6 +717,9 @@ drawbar(Monitor *m)
urg |= c->tags;
}
x = 0;
+ w = blw = TEXTW(m->ltsymbol);
+ drw_setscheme(drw, scheme[SchemeNorm]);
+ x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0);
for (i = 0; i < LENGTH(tags); i++) {
w = TEXTW(tags[i]);
drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]);
@@ -724,9 +730,6 @@ drawbar(Monitor *m)
urg & 1 << i);
x += w;
}
- w = blw = TEXTW(m->ltsymbol);
- drw_setscheme(drw, scheme[SchemeNorm]);
- x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0);
if ((w = m->ww - sw - x) > bh) {
if (m->sel) {
--
2.7.4

+ 73
- 0
suckless/dwm/patches/dwm-movestack-6.1.diff View File

@ -0,0 +1,73 @@
diff -r 050d521d66d8 config.def.h
--- a/config.def.h Tue Aug 24 13:13:20 2010 +0100
+++ b/config.def.h Sun Sep 05 18:43:07 2010 +0200
@@ -57,6 +57,7 @@
static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", normbgcolor, "-nf", normfgcolor, "-sb", selbgcolor, "-sf", selfgcolor, NULL };
static const char *termcmd[] = { "st", NULL };
+#include "movestack.c"
static Key keys[] = {
/* modifier key function argument */
{ MODKEY, XK_p, spawn, {.v = dmenucmd } },
@@ -68,6 +69,8 @@
{ MODKEY, XK_d, incnmaster, {.i = -1 } },
{ MODKEY, XK_h, setmfact, {.f = -0.05} },
{ MODKEY, XK_l, setmfact, {.f = +0.05} },
+ { MODKEY|ShiftMask, XK_j, movestack, {.i = +1 } },
+ { MODKEY|ShiftMask, XK_k, movestack, {.i = -1 } },
{ MODKEY, XK_Return, zoom, {0} },
{ MODKEY, XK_Tab, view, {0} },
{ MODKEY|ShiftMask, XK_c, killclient, {0} },
diff -r 050d521d66d8 movestack.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/movestack.c Sun Sep 05 18:43:07 2010 +0200
@@ -0,0 +1,49 @@
+void
+movestack(const Arg *arg) {
+ Client *c = NULL, *p = NULL, *pc = NULL, *i;
+
+ if(arg->i > 0) {
+ /* find the client after selmon->sel */
+ for(c = selmon->sel->next; c && (!ISVISIBLE(c) || c->isfloating); c = c->next);
+ if(!c)
+ for(c = selmon->clients; c && (!ISVISIBLE(c) || c->isfloating); c = c->next);
+
+ }
+ else {
+ /* find the client before selmon->sel */
+ for(i = selmon->clients; i != selmon->sel; i = i->next)
+ if(ISVISIBLE(i) && !i->isfloating)
+ c = i;
+ if(!c)
+ for(; i; i = i->next)
+ if(ISVISIBLE(i) && !i->isfloating)
+ c = i;
+ }
+ /* find the client before selmon->sel and c */
+ for(i = selmon->clients; i && (!p || !pc); i = i->next) {
+ if(i->next == selmon->sel)
+ p = i;
+ if(i->next == c)
+ pc = i;
+ }
+
+ /* swap c and selmon->sel selmon->clients in the selmon->clients list */
+ if(c && c != selmon->sel) {
+ Client *temp = selmon->sel->next==c?selmon->sel:selmon->sel->next;
+ selmon->sel->next = c->next==selmon->sel?c:c->next;
+ c->next = temp;
+
+ if(p && p != c)
+ p->next = c;
+ if(pc && pc != selmon->sel)
+ pc->next = selmon->sel;
+
+ if(selmon->sel == selmon->clients)
+ selmon->clients = c;
+ else if(c == selmon->clients)
+ selmon->clients = selmon->sel;
+
+ arrange(selmon);
+ }
+}
+

+ 65
- 0
suckless/dwm/patches/dwm-netclientliststacking-6.2.diff View File

@ -0,0 +1,65 @@
From 67840904a9510d6a6fc991b7f04046e74d196a26 Mon Sep 17 00:00:00 2001
From: bakkeby <bakkeby@gmail.com>
Date: Sun, 25 Oct 2020 16:40:05 +0100
Subject: [PATCH] Adds the _NET_CLIENT_LIST_STACKING property which may be
needed by some applications, e.g. zoom for window sharing.
---
dwm.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/dwm.c b/dwm.c
index 4465af1..0be261f 100644
--- a/dwm.c
+++ b/dwm.c
@@ -62,7 +62,7 @@ enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
enum { SchemeNorm, SchemeSel }; /* color schemes */
enum { NetSupported, NetWMName, NetWMState, NetWMCheck,
NetWMFullscreen, NetActiveWindow, NetWMWindowType,
- NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */
+ NetWMWindowTypeDialog, NetClientList, NetClientListStacking, NetLast }; /* EWMH atoms */
enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */
enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle,
ClkClientWin, ClkRootWin, ClkLast }; /* clicks */
@@ -1066,6 +1066,8 @@ manage(Window w, XWindowAttributes *wa)
attachstack(c);
XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend,
(unsigned char *) &(c->win), 1);
+ XChangeProperty(dpy, root, netatom[NetClientListStacking], XA_WINDOW, 32, PropModePrepend,
+ (unsigned char *) &(c->win), 1);
XMoveResizeWindow(dpy, c->win, c->x + 2 * sw, c->y, c->w, c->h); /* some windows require this */
setclientstate(c, NormalState);
if (c->mon == selmon)
@@ -1562,6 +1564,7 @@ setup(void)
netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False);
netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False);
netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", False);
+ netatom[NetClientListStacking] = XInternAtom(dpy, "_NET_CLIENT_LIST_STACKING", False);
/* init cursors */
cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr);
cursor[CurResize] = drw_cur_create(drw, XC_sizing);
@@ -1585,6 +1588,7 @@ setup(void)
XChangeProperty(dpy, root, netatom[NetSupported], XA_ATOM, 32,
PropModeReplace, (unsigned char *) netatom, NetLast);
XDeleteProperty(dpy, root, netatom[NetClientList]);
+ XDeleteProperty(dpy, root, netatom[NetClientListStacking]);
/* select events */
wa.cursor = cursor[CurNormal]->cursor;
wa.event_mask = SubstructureRedirectMask|SubstructureNotifyMask
@@ -1845,6 +1849,13 @@ updateclientlist()
XChangeProperty(dpy, root, netatom[NetClientList],
XA_WINDOW, 32, PropModeAppend,
(unsigned char *) &(c->win), 1);
+
+ XDeleteProperty(dpy, root, netatom[NetClientListStacking]);
+ for (m = mons; m; m = m->next)
+ for (c = m->stack; c; c = c->snext)
+ XChangeProperty(dpy, root, netatom[NetClientListStacking],
+ XA_WINDOW, 32, PropModeAppend,
+ (unsigned char *) &(c->win), 1);
}
int
--
2.19.1

+ 177
- 0
suckless/dwm/patches/dwm-pertag-20170513-ceac8c9.diff View File

@ -0,0 +1,177 @@
diff --git a/dwm.c b/dwm.c
index a5ce993..45f1e27 100644
--- a/dwm.c
+++ b/dwm.c
@@ -112,6 +112,7 @@ typedef struct {
void (*arrange)(Monitor *);
} Layout;
+typedef struct Pertag Pertag;
struct Monitor {
char ltsymbol[16];
float mfact;
@@ -131,6 +132,7 @@ struct Monitor {
Monitor *next;
Window barwin;
const Layout *lt[2];
+ Pertag *pertag;
};
typedef struct {
@@ -272,6 +274,15 @@ static Window root, wmcheckwin;
/* configuration, allows nested code to access above variables */
#include "config.h"
+struct Pertag {
+ unsigned int curtag, prevtag; /* current and previous tag */
+ int nmasters[LENGTH(tags) + 1]; /* number of windows in master area */
+ float mfacts[LENGTH(tags) + 1]; /* mfacts per tag */
+ unsigned int sellts[LENGTH(tags) + 1]; /* selected layouts */
+ const Layout *ltidxs[LENGTH(tags) + 1][2]; /* matrix of tags and layouts indexes */
+ int showbars[LENGTH(tags) + 1]; /* display bar for the current tag */
+};
+
/* compile-time check if all tags fit into an unsigned int bit array. */
struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; };
@@ -632,6 +643,7 @@ Monitor *
createmon(void)
{
Monitor *m;
+ unsigned int i;
m = ecalloc(1, sizeof(Monitor));
m->tagset[0] = m->tagset[1] = 1;
@@ -642,6 +654,20 @@ createmon(void)
m->lt[0] = &layouts[0];
m->lt[1] = &layouts[1 % LENGTH(layouts)];
strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
+ m->pertag = ecalloc(1, sizeof(Pertag));
+ m->pertag->curtag = m->pertag->prevtag = 1;
+
+ for (i = 0; i <= LENGTH(tags); i++) {
+ m->pertag->nmasters[i] = m->nmaster;
+ m->pertag->mfacts[i] = m->mfact;
+
+ m->pertag->ltidxs[i][0] = m->lt[0];
+ m->pertag->ltidxs[i][1] = m->lt[1];
+ m->pertag->sellts[i] = m->sellt;
+
+ m->pertag->showbars[i] = m->showbar;
+ }
+
return m;
}
@@ -968,7 +994,7 @@ grabkeys(void)
void
incnmaster(const Arg *arg)
{
- selmon->nmaster = MAX(selmon->nmaster + arg->i, 0);
+ selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag] = MAX(selmon->nmaster + arg->i, 0);
arrange(selmon);
}
@@ -1503,9 +1529,9 @@ void
setlayout(const Arg *arg)
{
if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt])
- selmon->sellt ^= 1;
+ selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag] ^= 1;
if (arg && arg->v)
- selmon->lt[selmon->sellt] = (Layout *)arg->v;
+ selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt] = (Layout *)arg->v;
strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol);
if (selmon->sel)
arrange(selmon);
@@ -1524,7 +1550,7 @@ setmfact(const Arg *arg)
f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0;
if (f < 0.1 || f > 0.9)
return;
- selmon->mfact = f;
+ selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag] = f;
arrange(selmon);
}
@@ -1701,7 +1727,7 @@ tile(Monitor *m)
void
togglebar(const Arg *arg)
{
- selmon->showbar = !selmon->showbar;
+ selmon->showbar = selmon->pertag->showbars[selmon->pertag->curtag] = !selmon->showbar;
updatebarpos(selmon);
XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh);
arrange(selmon);
@@ -1740,9 +1766,33 @@ void
toggleview(const Arg *arg)
{
unsigned int newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK);
+ int i;
if (newtagset) {
selmon->tagset[selmon->seltags] = newtagset;
+
+ if (newtagset == ~0) {
+ selmon->pertag->prevtag = selmon->pertag->curtag;
+ selmon->pertag->curtag = 0;
+ }
+
+ /* test if the user did not select the same tag */
+ if (!(newtagset & 1 << (selmon->pertag->curtag - 1))) {
+ selmon->pertag->prevtag = selmon->pertag->curtag;
+ for (i = 0; !(newtagset & 1 << i); i++) ;
+ selmon->pertag->curtag = i + 1;
+ }
+
+ /* apply settings for this view */
+ selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag];
+ selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag];
+ selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag];
+ selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt];
+ selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1];
+
+ if (selmon->showbar != selmon->pertag->showbars[selmon->pertag->curtag])
+ togglebar(NULL);
+
focus(NULL);
arrange(selmon);
}
@@ -2036,11 +2086,37 @@ updatewmhints(Client *c)
void
view(const Arg *arg)
{
+ int i;
+ unsigned int tmptag;
+
if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags])
return;
selmon->seltags ^= 1; /* toggle sel tagset */
- if (arg->ui & TAGMASK)
+ if (arg->ui & TAGMASK) {
selmon->tagset[selmon->seltags] = arg->ui & TAGMASK;
+ selmon->pertag->prevtag = selmon->pertag->curtag;
+
+ if (arg->ui == ~0)
+ selmon->pertag->curtag = 0;
+ else {
+ for (i = 0; !(arg->ui & 1 << i); i++) ;
+ selmon->pertag->curtag = i + 1;
+ }
+ } else {
+ tmptag = selmon->pertag->prevtag;
+ selmon->pertag->prevtag = selmon->pertag->curtag;
+ selmon->pertag->curtag = tmptag;
+ }
+
+ selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag];
+ selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag];
+ selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag];
+ selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt];
+ selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1];
+
+ if (selmon->showbar != selmon->pertag->showbars[selmon->pertag->curtag])
+ togglebar(NULL);
+
focus(NULL);
arrange(selmon);
}

+ 113
- 0
suckless/dwm/patches/dwm-rmaster-6.1.diff View File

@ -0,0 +1,113 @@
From 3aca05f642469799086acbc243e173cfda527683 Mon Sep 17 00:00:00 2001
From: aleks <aleks.stier@icloud.com>
Date: Thu, 23 May 2019 22:39:13 +0200
Subject: [PATCH] Enable swapping master- and stack-area
Enables swapping the master- and stack area such that the master-client
appears on the right and the stack-clients appear on the left.
A variable and a toggle-function are introduced to achieve this
behaviour which are set in the config.h:
* The rmaster-variable can be set to 1 to make the right area the
default master-area
* The togglemaster-function can be used to swap the master- and
stack-areas dynamically.
---
config.def.h | 2 ++
dwm.c | 23 ++++++++++++++++++++---
2 files changed, 22 insertions(+), 3 deletions(-)
diff --git a/config.def.h b/config.def.h
index 7054c06..5a69035 100644
--- a/config.def.h
+++ b/config.def.h
@@ -13,6 +13,7 @@ static const char selbgcolor[] = "#005577";
static const char selfgcolor[] = "#eeeeee";
static const unsigned int borderpx = 1; /* border pixel of windows */
static const unsigned int snap = 32; /* snap pixel */
+static const int rmaster = 1; /* 1 means master-area is initially on the right */
static const int showbar = 1; /* 0 means no bar */
static const int topbar = 1; /* 0 means bottom bar */
@@ -76,6 +77,7 @@ static Key keys[] = {
{ MODKEY, XK_m, setlayout, {.v = &layouts[2]} },
{ MODKEY, XK_space, setlayout, {0} },
{ MODKEY|ShiftMask, XK_space, togglefloating, {0} },
+ { MODKEY, XK_r, togglermaster, {0} },
{ MODKEY, XK_0, view, {.ui = ~0 } },
{ MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } },
{ MODKEY, XK_comma, focusmon, {.i = -1 } },
diff --git a/dwm.c b/dwm.c
index 0362114..e11bd8b 100644
--- a/dwm.c
+++ b/dwm.c
@@ -122,6 +122,7 @@ struct Monitor {
unsigned int seltags;
unsigned int sellt;
unsigned int tagset[2];
+ int rmaster;
int showbar;
int topbar;
Client *clients;
@@ -211,6 +212,7 @@ static void tagmon(const Arg *arg);
static void tile(Monitor *);
static void togglebar(const Arg *arg);
static void togglefloating(const Arg *arg);
+static void togglermaster(const Arg *arg);
static void toggletag(const Arg *arg);
static void toggleview(const Arg *arg);
static void unfocus(Client *c, int setfocus);
@@ -645,6 +647,7 @@ createmon(void)
m->tagset[0] = m->tagset[1] = 1;
m->mfact = mfact;
m->nmaster = nmaster;
+ m->rmaster = rmaster;
m->showbar = showbar;
m->topbar = topbar;
m->lt[0] = &layouts[0];
@@ -1674,17 +1677,21 @@ tile(Monitor *m)
return;
if (n > m->nmaster)
- mw = m->nmaster ? m->ww * m->mfact : 0;
+ mw = m->nmaster
+ ? m->ww * (m->rmaster ? 1.0 - m->mfact : m->mfact)
+ : 0;
else
mw = m->ww;
for (i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
if (i < m->nmaster) {
h = (m->wh - my) / (MIN(n, m->nmaster) - i);
- resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), 0);
+ resize(c, m->rmaster ? m->wx + m->ww - mw : m->wx,
+ m->wy + my, mw - (2*c->bw), h - (2*c->bw), 0);
my += HEIGHT(c);
} else {
h = (m->wh - ty) / (n - i);
- resize(c, m->wx + mw, m->wy + ty, m->ww - mw - (2*c->bw), h - (2*c->bw), 0);
+ resize(c, m->rmaster ? m->wx : m->wx + mw, m->wy + ty,
+ m->ww - mw - (2*c->bw), h - (2*c->bw), 0);
ty += HEIGHT(c);
}
}
@@ -1712,6 +1719,16 @@ togglefloating(const Arg *arg)
arrange(selmon);
}
+void
+togglermaster(const Arg *arg)
+{
+ selmon->rmaster = !selmon->rmaster;
+ /* now mfact represents the left factor */
+ selmon->mfact = 1.0 - selmon->mfact;
+ if (selmon->lt[selmon->sellt]->arrange)
+ arrange(selmon);
+}
+
void
toggletag(const Arg *arg)
{
--
2.21.0

+ 62
- 0
suckless/dwm/patches/dwm-statuspadding-20150524-c8e9479.diff View File

@ -0,0 +1,62 @@
From 75d5edbe16ee2fc060ff8b05eea17791d6334a59 Mon Sep 17 00:00:00 2001
From: Christopher Drelich <cd@cdrakka.com>
Date: Thu, 24 May 2018 23:24:12 -0400
Subject: [PATCH] Replaces magic numbers in statusbar with configurable
variables.
horizpadbar for horizontal statusbar padding
vertpadbar for vertical statusbar padding
StatusText now has both left and right padding,
as well as the vertical padding that all of the statusbar shares.
Other than the addition of left padding to StatusText, appearance
of the statusbar is identical to pre-patch when using the defaults
in config.def.h
---
config.def.h | 2 ++
dwm.c | 8 ++++----
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/config.def.h b/config.def.h
index a9ac303..5819399 100644
--- a/config.def.h
+++ b/config.def.h
@@ -5,6 +5,8 @@ static const unsigned int borderpx = 1; /* border pixel of windows */
static const unsigned int snap = 32; /* snap pixel */
static const int showbar = 1; /* 0 means no bar */
static const int topbar = 1; /* 0 means bottom bar */
+static const int horizpadbar = 2; /* horizontal padding for statusbar */
+static const int vertpadbar = 0; /* vertical padding for statusbar */
static const char *fonts[] = { "monospace:size=10" };
static const char dmenufont[] = "monospace:size=10";
static const char col_gray1[] = "#222222";
diff --git a/dwm.c b/dwm.c
index bb95e26..7b9ed42 100644
--- a/dwm.c
+++ b/dwm.c
@@ -704,8 +704,8 @@ drawbar(Monitor *m)
/* draw status first so it can be overdrawn by tags later */
if (m == selmon) { /* status is only drawn on selected monitor */
drw_setscheme(drw, scheme[SchemeNorm]);
- sw = TEXTW(stext) - lrpad + 2; /* 2px right padding */
- drw_text(drw, m->ww - sw, 0, sw, bh, 0, stext, 0);
+ sw = TEXTW(stext);
+ drw_text(drw, m->ww - sw, 0, sw, bh, lrpad / 2, stext, 0);
}
for (c = m->clients; c; c = c->next) {
@@ -1544,8 +1544,8 @@ setup(void)
drw = drw_create(dpy, screen, root, sw, sh);
if (!drw_fontset_create(drw, fonts, LENGTH(fonts)))
die("no fonts could be loaded.");
- lrpad = drw->fonts->h;
- bh = drw->fonts->h + 2;
+ lrpad = drw->fonts->h + horizpadbar;
+ bh = drw->fonts->h + vertpadbar;
updategeom();
/* init atoms */
utf8string = XInternAtom(dpy, "UTF8_STRING", False);
--
2.7.4

+ 47
- 0
suckless/dwm/patches/dwm-switchcol-6.1.diff View File

@ -0,0 +1,47 @@
diff -urp dwm-6.1/dwm.c dwm-6.1-patched/dwm.c
--- dwm-6.1/dwm.c 2015-11-09 06:39:37.000000000 +0800
+++ dwm-6.1-patched/dwm.c 2016-03-24 23:56:35.435047948 +0800
@@ -206,6 +206,7 @@ static void setup(void);
static void showhide(Client *c);
static void sigchld(int unused);
static void spawn(const Arg *arg);
+static void switchcol(const Arg *arg);
static void tag(const Arg *arg);
static void tagmon(const Arg *arg);
static void tile(Monitor *);
@@ -1645,6 +1646,35 @@ spawn(const Arg *arg)
}
}
+void
+switchcol(const Arg *arg)
+{
+ Client *c, *t;
+ int col = 0;
+ int i;
+
+ if (!selmon->sel)
+ return;
+ for (i = 0, c = nexttiled(selmon->clients); c ;
+ c = nexttiled(c->next), i++) {
+ if (c == selmon->sel)
+ col = (i + 1) > selmon->nmaster;
+ }
+ if (i <= selmon->nmaster)
+ return;
+ for (c = selmon->stack; c; c = c->snext) {
+ if (!ISVISIBLE(c))
+ continue;
+ for (i = 0, t = nexttiled(selmon->clients); t && t != c;
+ t = nexttiled(t->next), i++);
+ if (t && (i + 1 > selmon->nmaster) != col) {
+ focus(c);
+ restack(selmon);
+ break;
+ }
+ }
+}
+
void
tag(const Arg *arg)
{

+ 727
- 0
suckless/dwm/patches/dwm-systray-20200914-61bb8b2.diff View File

@ -0,0 +1,727 @@
diff --git a/config.def.h b/config.def.h
index 1c0b587..2d824d1 100644
--- a/config.def.h
+++ b/config.def.h
@@ -3,6 +3,10 @@
/* appearance */
static const unsigned int borderpx = 1; /* border pixel of windows */
static const unsigned int snap = 32; /* snap pixel */
+static const unsigned int systraypinning = 0; /* 0: sloppy systray follows selected monitor, >0: pin systray to monitor X */
+static const unsigned int systrayspacing = 2; /* systray spacing */
+static const int systraypinningfailfirst = 1; /* 1: if pinning fails, display systray on the first monitor, False: display systray on the last monitor*/
+static const int showsystray = 1; /* 0 means no systray */
static const int showbar = 1; /* 0 means no bar */
static const int topbar = 1; /* 0 means bottom bar */
static const char *fonts[] = { "monospace:size=10" };
diff --git a/dwm.c b/dwm.c
index 664c527..abce13d 100644
--- a/dwm.c
+++ b/dwm.c
@@ -57,12 +57,30 @@
#define TAGMASK ((1 << LENGTH(tags)) - 1)
#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad)
+#define SYSTEM_TRAY_REQUEST_DOCK 0
+
+/* XEMBED messages */
+#define XEMBED_EMBEDDED_NOTIFY 0
+#define XEMBED_WINDOW_ACTIVATE 1
+#define XEMBED_FOCUS_IN 4
+#define XEMBED_MODALITY_ON 10
+
+#define XEMBED_MAPPED (1 << 0)
+#define XEMBED_WINDOW_ACTIVATE 1
+#define XEMBED_WINDOW_DEACTIVATE 2
+
+#define VERSION_MAJOR 0
+#define VERSION_MINOR 0
+#define XEMBED_EMBEDDED_VERSION (VERSION_MAJOR << 16) | VERSION_MINOR
+
/* enums */
enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
enum { SchemeNorm, SchemeSel }; /* color schemes */
enum { NetSupported, NetWMName, NetWMState, NetWMCheck,
+ NetSystemTray, NetSystemTrayOP, NetSystemTrayOrientation, NetSystemTrayOrientationHorz,
NetWMFullscreen, NetActiveWindow, NetWMWindowType,
NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */
+enum { Manager, Xembed, XembedInfo, XLast }; /* Xembed atoms */
enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */
enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle,
ClkClientWin, ClkRootWin, ClkLast }; /* clicks */
@@ -141,6 +159,12 @@ typedef struct {
int monitor;
} Rule;
+typedef struct Systray Systray;
+struct Systray {
+ Window win;
+ Client *icons;
+};
+
/* function declarations */
static void applyrules(Client *c);
static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact);
@@ -172,6 +196,7 @@ static void focusstack(const Arg *arg);
static Atom getatomprop(Client *c, Atom prop);
static int getrootptr(int *x, int *y);
static long getstate(Window w);
+static unsigned int getsystraywidth();
static int gettextprop(Window w, Atom atom, char *text, unsigned int size);
static void grabbuttons(Client *c, int focused);
static void grabkeys(void);
@@ -189,13 +214,16 @@ static void pop(Client *);
static void propertynotify(XEvent *e);
static void quit(const Arg *arg);
static Monitor *recttomon(int x, int y, int w, int h);
+static void removesystrayicon(Client *i);
static void resize(Client *c, int x, int y, int w, int h, int interact);
+static void resizebarwin(Monitor *m);
static void resizeclient(Client *c, int x, int y, int w, int h);
static void resizemouse(const Arg *arg);
+static void resizerequest(XEvent *e);
static void restack(Monitor *m);
static void run(void);
static void scan(void);
-static int sendevent(Client *c, Atom proto);
+static int sendevent(Window w, Atom proto, int m, long d0, long d1, long d2, long d3, long d4);
static void sendmon(Client *c, Monitor *m);
static void setclientstate(Client *c, long state);
static void setfocus(Client *c);
@@ -207,6 +235,7 @@ static void seturgent(Client *c, int urg);
static void showhide(Client *c);
static void sigchld(int unused);
static void spawn(const Arg *arg);
+static Monitor *systraytomon(Monitor *m);
static void tag(const Arg *arg);
static void tagmon(const Arg *arg);
static void tile(Monitor *);
@@ -224,18 +253,23 @@ static int updategeom(void);
static void updatenumlockmask(void);
static void updatesizehints(Client *c);
static void updatestatus(void);
+static void updatesystray(void);
+static void updatesystrayicongeom(Client *i, int w, int h);
+static void updatesystrayiconstate(Client *i, XPropertyEvent *ev);
static void updatetitle(Client *c);
static void updatewindowtype(Client *c);
static void updatewmhints(Client *c);
static void view(const Arg *arg);
static Client *wintoclient(Window w);
static Monitor *wintomon(Window w);
+static Client *wintosystrayicon(Window w);
static int xerror(Display *dpy, XErrorEvent *ee);
static int xerrordummy(Display *dpy, XErrorEvent *ee);
static int xerrorstart(Display *dpy, XErrorEvent *ee);
static void zoom(const Arg *arg);
/* variables */
+static Systray *systray = NULL;
static const char broken[] = "broken";
static char stext[256];
static int screen;
@@ -258,9 +292,10 @@ static void (*handler[LASTEvent]) (XEvent *) = {
[MapRequest] = maprequest,
[MotionNotify] = motionnotify,
[PropertyNotify] = propertynotify,
+ [ResizeRequest] = resizerequest,
[UnmapNotify] = unmapnotify
};
-static Atom wmatom[WMLast], netatom[NetLast];
+static Atom wmatom[WMLast], netatom[NetLast], xatom[XLast];
static int running = 1;
static Cur *cursor[CurLast];
static Clr **scheme;
@@ -440,7 +475,7 @@ buttonpress(XEvent *e)
arg.ui = 1 << i;
} else if (ev->x < x + blw)
click = ClkLtSymbol;
- else if (ev->x > selmon->ww - (int)TEXTW(stext))
+ else if (ev->x > selmon->ww - (int)TEXTW(stext) - getsystraywidth())
click = ClkStatusText;
else
click = ClkWinTitle;
@@ -483,6 +518,11 @@ cleanup(void)
XUngrabKey(dpy, AnyKey, AnyModifier, root);
while (mons)
cleanupmon(mons);
+ if (showsystray) {
+ XUnmapWindow(dpy, systray->win);
+ XDestroyWindow(dpy, systray->win);
+ free(systray);
+ }
for (i = 0; i < CurLast; i++)
drw_cur_free(drw, cursor[i]);
for (i = 0; i < LENGTH(colors); i++)
@@ -513,9 +553,57 @@ cleanupmon(Monitor *mon)
void
clientmessage(XEvent *e)
{
+ XWindowAttributes wa;
+ XSetWindowAttributes swa;
XClientMessageEvent *cme = &e->xclient;
Client *c = wintoclient(cme->window);
+ if (showsystray && cme->window == systray->win && cme->message_type == netatom[NetSystemTrayOP]) {
+ /* add systray icons */
+ if (cme->data.l[1] == SYSTEM_TRAY_REQUEST_DOCK) {
+ if (!(c = (Client *)calloc(1, sizeof(Client))))
+ die("fatal: could not malloc() %u bytes\n", sizeof(Client));
+ if (!(c->win = cme->data.l[2])) {
+ free(c);
+ return;
+ }
+ c->mon = selmon;
+ c->next = systray->icons;
+ systray->icons = c;
+ if (!XGetWindowAttributes(dpy, c->win, &wa)) {
+ /* use sane defaults */
+ wa.width = bh;
+ wa.height = bh;
+ wa.border_width = 0;
+ }
+ c->x = c->oldx = c->y = c->oldy = 0;
+ c->w = c->oldw = wa.width;
+ c->h = c->oldh = wa.height;
+ c->oldbw = wa.border_width;
+ c->bw = 0;
+ c->isfloating = True;
+ /* reuse tags field as mapped status */
+ c->tags = 1;
+ updatesizehints(c);
+ updatesystrayicongeom(c, wa.width, wa.height);
+ XAddToSaveSet(dpy, c->win);
+ XSelectInput(dpy, c->win, StructureNotifyMask | PropertyChangeMask | ResizeRedirectMask);
+ XReparentWindow(dpy, c->win, systray->win, 0, 0);
+ /* use parents background color */
+ swa.background_pixel = scheme[SchemeNorm][ColBg].pixel;
+ XChangeWindowAttributes(dpy, c->win, CWBackPixel, &swa);
+ sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_EMBEDDED_NOTIFY, 0 , systray->win, XEMBED_EMBEDDED_VERSION);
+ /* FIXME not sure if I have to send these events, too */
+ sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_FOCUS_IN, 0 , systray->win, XEMBED_EMBEDDED_VERSION);
+ sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_WINDOW_ACTIVATE, 0 , systray->win, XEMBED_EMBEDDED_VERSION);
+ sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_MODALITY_ON, 0 , systray->win, XEMBED_EMBEDDED_VERSION);
+ XSync(dpy, False);
+ resizebarwin(selmon);
+ updatesystray();
+ setclientstate(c, NormalState);
+ }
+ return;
+ }
if (!c)
return;
if (cme->message_type == netatom[NetWMState]) {
@@ -568,7 +656,7 @@ configurenotify(XEvent *e)
for (c = m->clients; c; c = c->next)
if (c->isfullscreen)
resizeclient(c, m->mx, m->my, m->mw, m->mh);
- XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh);
+ resizebarwin(m);
}
focus(NULL);
arrange(NULL);
@@ -653,6 +741,11 @@ destroynotify(XEvent *e)
if ((c = wintoclient(ev->window)))
unmanage(c, 1);
+ else if ((c = wintosystrayicon(ev->window))) {
+ removesystrayicon(c);
+ resizebarwin(selmon);
+ updatesystray();
+ }
}
void
@@ -696,19 +789,23 @@ dirtomon(int dir)
void
drawbar(Monitor *m)
{
- int x, w, tw = 0;
+ int x, w, tw = 0, stw = 0;
int boxs = drw->fonts->h / 9;
int boxw = drw->fonts->h / 6 + 2;
unsigned int i, occ = 0, urg = 0;
Client *c;
+ if(showsystray && m == systraytomon(m))
+ stw = getsystraywidth();
+
/* draw status first so it can be overdrawn by tags later */
if (m == selmon) { /* status is only drawn on selected monitor */
drw_setscheme(drw, scheme[SchemeNorm]);
- tw = TEXTW(stext) - lrpad + 2; /* 2px right padding */
- drw_text(drw, m->ww - tw, 0, tw, bh, 0, stext, 0);
+ tw = TEXTW(stext) - lrpad / 2 + 2; /* 2px right padding */
+ drw_text(drw, m->ww - tw - stw, 0, tw, bh, lrpad / 2 - 2, stext, 0);
}
+ resizebarwin(m);
for (c = m->clients; c; c = c->next) {
occ |= c->tags;
if (c->isurgent)
@@ -729,7 +826,7 @@ drawbar(Monitor *m)
drw_setscheme(drw, scheme[SchemeNorm]);
x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0);
- if ((w = m->ww - tw - x) > bh) {
+ if ((w = m->ww - tw - stw - x) > bh) {
if (m->sel) {
drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]);
drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0);
@@ -740,7 +837,7 @@ drawbar(Monitor *m)
drw_rect(drw, x, 0, w, bh, 1, 1);
}
}
- drw_map(drw, m->barwin, 0, 0, m->ww, bh);
+ drw_map(drw, m->barwin, 0, 0, m->ww - stw, bh);
}
void
@@ -777,8 +874,11 @@ expose(XEvent *e)
Monitor *m;
XExposeEvent *ev = &e->xexpose;
- if (ev->count == 0 && (m = wintomon(ev->window)))
+ if (ev->count == 0 && (m = wintomon(ev->window))) {
drawbar(m);
+ if (m == selmon)
+ updatesystray();
+ }
}
void
@@ -863,10 +963,17 @@ getatomprop(Client *c, Atom prop)
unsigned long dl;
unsigned char *p = NULL;
Atom da, atom = None;
+ /* FIXME getatomprop should return the number of items and a pointer to
+ * the stored data instead of this workaround */
+ Atom req = XA_ATOM;
+ if (prop == xatom[XembedInfo])
+ req = xatom[XembedInfo];
- if (XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, XA_ATOM,
+ if (XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, req,
&da, &di, &dl, &dl, &p) == Success && p) {
atom = *(Atom *)p;
+ if (da == xatom[XembedInfo] && dl == 2)
+ atom = ((Atom *)p)[1];
XFree(p);
}
return atom;
@@ -900,6 +1007,16 @@ getstate(Window w)
return result;
}
+unsigned int
+getsystraywidth()
+{
+ unsigned int w = 0;
+ Client *i;
+ if(showsystray)
+ for(i = systray->icons; i; w += i->w + systrayspacing, i = i->next) ;
+ return w ? w + systrayspacing : 1;
+}
+
int
gettextprop(Window w, Atom atom, char *text, unsigned int size)
{
@@ -1004,7 +1121,7 @@ killclient(const Arg *arg)
{
if (!selmon->sel)
return;
- if (!sendevent(selmon->sel, wmatom[WMDelete])) {
+ if (!sendevent(selmon->sel->win, wmatom[WMDelete], NoEventMask, wmatom[WMDelete], CurrentTime, 0 , 0, 0)) {
XGrabServer(dpy);
XSetErrorHandler(xerrordummy);
XSetCloseDownMode(dpy, DestroyAll);
@@ -1092,6 +1209,12 @@ maprequest(XEvent *e)
{
static XWindowAttributes wa;
XMapRequestEvent *ev = &e->xmaprequest;
+ Client *i;
+ if ((i = wintosystrayicon(ev->window))) {
+ sendevent(i->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_WINDOW_ACTIVATE, 0, systray->win, XEMBED_EMBEDDED_VERSION);
+ resizebarwin(selmon);
+ updatesystray();
+ }
if (!XGetWindowAttributes(dpy, ev->window, &wa))
return;
@@ -1216,6 +1339,16 @@ propertynotify(XEvent *e)
Window trans;
XPropertyEvent *ev = &e->xproperty;
+ if ((c = wintosystrayicon(ev->window))) {
+ if (ev->atom == XA_WM_NORMAL_HINTS) {
+ updatesizehints(c);
+ updatesystrayicongeom(c, c->w, c->h);
+ }
+ else
+ updatesystrayiconstate(c, ev);
+ resizebarwin(selmon);
+ updatesystray();
+ }
if ((ev->window == root) && (ev->atom == XA_WM_NAME))
updatestatus();
else if (ev->state == PropertyDelete)
@@ -1266,6 +1399,20 @@ recttomon(int x, int y, int w, int h)
return r;
}
+void
+removesystrayicon(Client *i)
+{
+ Client **ii;
+
+ if (!showsystray || !i)
+ return;
+ for (ii = &systray->icons; *ii && *ii != i; ii = &(*ii)->next);
+ if (ii)
+ *ii = i->next;
+ free(i);
+}
+
+
void
resize(Client *c, int x, int y, int w, int h, int interact)
{
@@ -1273,6 +1420,14 @@ resize(Client *c, int x, int y, int w, int h, int interact)
resizeclient(c, x, y, w, h);
}
+void
+resizebarwin(Monitor *m) {
+ unsigned int w = m->ww;
+ if (showsystray && m == systraytomon(m))
+ w -= getsystraywidth();
+ XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, w, bh);
+}
+
void
resizeclient(Client *c, int x, int y, int w, int h)
{
@@ -1345,6 +1500,19 @@ resizemouse(const Arg *arg)
}
}
+void
+resizerequest(XEvent *e)
+{
+ XResizeRequestEvent *ev = &e->xresizerequest;
+ Client *i;
+
+ if ((i = wintosystrayicon(ev->window))) {
+ updatesystrayicongeom(i, ev->width, ev->height);
+ resizebarwin(selmon);
+ updatesystray();
+ }
+}
+
void
restack(Monitor *m)
{
@@ -1434,26 +1602,36 @@ setclientstate(Client *c, long state)
}
int
-sendevent(Client *c, Atom proto)
+sendevent(Window w, Atom proto, int mask, long d0, long d1, long d2, long d3, long d4)
{
int n;
- Atom *protocols;
+ Atom *protocols, mt;
int exists = 0;
XEvent ev;
- if (XGetWMProtocols(dpy, c->win, &protocols, &n)) {
- while (!exists && n--)
- exists = protocols[n] == proto;
- XFree(protocols);
+ if (proto == wmatom[WMTakeFocus] || proto == wmatom[WMDelete]) {
+ mt = wmatom[WMProtocols];
+ if (XGetWMProtocols(dpy, w, &protocols, &n)) {
+ while (!exists && n--)
+ exists = protocols[n] == proto;
+ XFree(protocols);
+ }
+ }
+ else {
+ exists = True;
+ mt = proto;
}
if (exists) {
ev.type = ClientMessage;
- ev.xclient.window = c->win;
- ev.xclient.message_type = wmatom[WMProtocols];
+ ev.xclient.window = w;
+ ev.xclient.message_type = mt;
ev.xclient.format = 32;
- ev.xclient.data.l[0] = proto;
- ev.xclient.data.l[1] = CurrentTime;
- XSendEvent(dpy, c->win, False, NoEventMask, &ev);
+ ev.xclient.data.l[0] = d0;
+ ev.xclient.data.l[1] = d1;
+ ev.xclient.data.l[2] = d2;
+ ev.xclient.data.l[3] = d3;
+ ev.xclient.data.l[4] = d4;
+ XSendEvent(dpy, w, False, mask, &ev);
}
return exists;
}
@@ -1467,7 +1645,7 @@ setfocus(Client *c)
XA_WINDOW, 32, PropModeReplace,
(unsigned char *) &(c->win), 1);
}
- sendevent(c, wmatom[WMTakeFocus]);
+ sendevent(c->win, wmatom[WMTakeFocus], NoEventMask, wmatom[WMTakeFocus], CurrentTime, 0, 0, 0);
}
void
@@ -1556,6 +1734,10 @@ setup(void)
wmatom[WMTakeFocus] = XInternAtom(dpy, "WM_TAKE_FOCUS", False);
netatom[NetActiveWindow] = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False);
netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False);
+ netatom[NetSystemTray] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_S0", False);
+ netatom[NetSystemTrayOP] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_OPCODE", False);
+ netatom[NetSystemTrayOrientation] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_ORIENTATION", False);
+ netatom[NetSystemTrayOrientationHorz] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_ORIENTATION_HORZ", False);
netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False);
netatom[NetWMState] = XInternAtom(dpy, "_NET_WM_STATE", False);
netatom[NetWMCheck] = XInternAtom(dpy, "_NET_SUPPORTING_WM_CHECK", False);
@@ -1563,6 +1745,9 @@ setup(void)
netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False);
netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False);
netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", False);
+ xatom[Manager] = XInternAtom(dpy, "MANAGER", False);
+ xatom[Xembed] = XInternAtom(dpy, "_XEMBED", False);
+ xatom[XembedInfo] = XInternAtom(dpy, "_XEMBED_INFO", False);
/* init cursors */
cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr);
cursor[CurResize] = drw_cur_create(drw, XC_sizing);
@@ -1571,6 +1756,8 @@ setup(void)
scheme = ecalloc(LENGTH(colors), sizeof(Clr *));
for (i = 0; i < LENGTH(colors); i++)
scheme[i] = drw_scm_create(drw, colors[i], 3);
+ /* init system tray */
+ updatesystray();
/* init bars */
updatebars();
updatestatus();
@@ -1704,7 +1891,18 @@ togglebar(const Arg *arg)
{
selmon->showbar = !selmon->showbar;
updatebarpos(selmon);
- XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh);
+ resizebarwin(selmon);
+ if (showsystray) {
+ XWindowChanges wc;
+ if (!selmon->showbar)
+ wc.y = -bh;
+ else if (selmon->showbar) {
+ wc.y = 0;
+ if (!selmon->topbar)
+ wc.y = selmon->mh - bh;
+ }
+ XConfigureWindow(dpy, systray->win, CWY, &wc);
+ }
arrange(selmon);
}
@@ -1799,11 +1997,18 @@ unmapnotify(XEvent *e)
else
unmanage(c, 0);
}
+ else if ((c = wintosystrayicon(ev->window))) {
+ /* KLUDGE! sometimes icons occasionally unmap their windows, but do
+ * _not_ destroy them. We map those windows back */
+ XMapRaised(dpy, c->win);
+ updatesystray();
+ }
}
void
updatebars(void)
{
+ unsigned int w;
Monitor *m;
XSetWindowAttributes wa = {
.override_redirect = True,
@@ -1814,10 +2019,15 @@ updatebars(void)
for (m = mons; m; m = m->next) {
if (m->barwin)
continue;
- m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, DefaultDepth(dpy, screen),
+ w = m->ww;
+ if (showsystray && m == systraytomon(m))
+ w -= getsystraywidth();
+ m->barwin = XCreateWindow(dpy, root, m->wx, m->by, w, bh, 0, DefaultDepth(dpy, screen),
CopyFromParent, DefaultVisual(dpy, screen),
CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa);
XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor);
+ if (showsystray && m == systraytomon(m))
+ XMapRaised(dpy, systray->win);
XMapRaised(dpy, m->barwin);
XSetClassHint(dpy, m->barwin, &ch);
}
@@ -1993,6 +2203,121 @@ updatestatus(void)
if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext)))
strcpy(stext, "dwm-"VERSION);
drawbar(selmon);
+ updatesystray();
+}
+
+void
+updatesystrayicongeom(Client *i, int w, int h)
+{
+ if (i) {
+ i->h = bh;
+ if (w == h)
+ i->w = bh;
+ else if (h == bh)
+ i->w = w;
+ else
+ i->w = (int) ((float)bh * ((float)w / (float)h));
+ applysizehints(i, &(i->x), &(i->y), &(i->w), &(i->h), False);
+ /* force icons into the systray dimensions if they don't want to */
+ if (i->h > bh) {
+ if (i->w == i->h)
+ i->w = bh;
+ else
+ i->w = (int) ((float)bh * ((float)i->w / (float)i->h));
+ i->h = bh;
+ }
+ }
+}
+
+void
+updatesystrayiconstate(Client *i, XPropertyEvent *ev)
+{
+ long flags;
+ int code = 0;
+
+ if (!showsystray || !i || ev->atom != xatom[XembedInfo] ||
+ !(flags = getatomprop(i, xatom[XembedInfo])))
+ return;
+
+ if (flags & XEMBED_MAPPED && !i->tags) {
+ i->tags = 1;
+ code = XEMBED_WINDOW_ACTIVATE;
+ XMapRaised(dpy, i->win);
+ setclientstate(i, NormalState);
+ }
+ else if (!(flags & XEMBED_MAPPED) && i->tags) {
+ i->tags = 0;
+ code = XEMBED_WINDOW_DEACTIVATE;
+ XUnmapWindow(dpy, i->win);
+ setclientstate(i, WithdrawnState);
+ }
+ else
+ return;
+ sendevent(i->win, xatom[Xembed], StructureNotifyMask, CurrentTime, code, 0,
+ systray->win, XEMBED_EMBEDDED_VERSION);
+}
+
+void
+updatesystray(void)
+{
+ XSetWindowAttributes wa;
+ XWindowChanges wc;
+ Client *i;
+ Monitor *m = systraytomon(NULL);
+ unsigned int x = m->mx + m->mw;
+ unsigned int w = 1;
+
+ if (!showsystray)
+ return;
+ if (!systray) {
+ /* init systray */
+ if (!(systray = (Systray *)calloc(1, sizeof(Systray))))
+ die("fatal: could not malloc() %u bytes\n", sizeof(Systray));
+ systray->win = XCreateSimpleWindow(dpy, root, x, m->by, w, bh, 0, 0, scheme[SchemeSel][ColBg].pixel);
+ wa.event_mask = ButtonPressMask | ExposureMask;
+ wa.override_redirect = True;
+ wa.background_pixel = scheme[SchemeNorm][ColBg].pixel;
+ XSelectInput(dpy, systray->win, SubstructureNotifyMask);
+ XChangeProperty(dpy, systray->win, netatom[NetSystemTrayOrientation], XA_CARDINAL, 32,
+ PropModeReplace, (unsigned char *)&netatom[NetSystemTrayOrientationHorz], 1);
+ XChangeWindowAttributes(dpy, systray->win, CWEventMask|CWOverrideRedirect|CWBackPixel, &wa);
+ XMapRaised(dpy, systray->win);
+ XSetSelectionOwner(dpy, netatom[NetSystemTray], systray->win, CurrentTime);
+ if (XGetSelectionOwner(dpy, netatom[NetSystemTray]) == systray->win) {
+ sendevent(root, xatom[Manager], StructureNotifyMask, CurrentTime, netatom[NetSystemTray], systray->win, 0, 0);
+ XSync(dpy, False);
+ }
+ else {
+ fprintf(stderr, "dwm: unable to obtain system tray.\n");
+ free(systray);
+ systray = NULL;
+ return;
+ }
+ }
+ for (w = 0, i = systray->icons; i; i = i->next) {
+ /* make sure the background color stays the same */
+ wa.background_pixel = scheme[SchemeNorm][ColBg].pixel;
+ XChangeWindowAttributes(dpy, i->win, CWBackPixel, &wa);
+ XMapRaised(dpy, i->win);
+ w += systrayspacing;
+ i->x = w;
+ XMoveResizeWindow(dpy, i->win, i->x, 0, i->w, i->h);
+ w += i->w;
+ if (i->mon != m)
+ i->mon = m;
+ }
+ w = w ? w + systrayspacing : 1;
+ x -= w;
+ XMoveResizeWindow(dpy, systray->win, x, m->by, w, bh);
+ wc.x = x; wc.y = m->by; wc.width = w; wc.height = bh;
+ wc.stack_mode = Above; wc.sibling = m->barwin;
+ XConfigureWindow(dpy, systray->win, CWX|CWY|CWWidth|CWHeight|CWSibling|CWStackMode, &wc);
+ XMapWindow(dpy, systray->win);
+ XMapSubwindows(dpy, systray->win);
+ /* redraw background */
+ XSetForeground(dpy, drw->gc, scheme[SchemeNorm][ColBg].pixel);
+ XFillRectangle(dpy, systray->win, drw->gc, 0, 0, w, bh);
+ XSync(dpy, False);
}
void
@@ -2060,6 +2385,16 @@ wintoclient(Window w)
return NULL;
}
+Client *
+wintosystrayicon(Window w) {
+ Client *i = NULL;
+
+ if (!showsystray || !w)
+ return i;
+ for (i = systray->icons; i && i->win != w; i = i->next) ;
+ return i;
+}
+
Monitor *
wintomon(Window w)
{
@@ -2113,6 +2448,22 @@ xerrorstart(Display *dpy, XErrorEvent *ee)
return -1;
}
+Monitor *
+systraytomon(Monitor *m) {
+ Monitor *t;
+ int i, n;
+ if(!systraypinning) {
+ if(!m)
+ return selmon;
+ return m == selmon ? m : NULL;
+ }
+ for(n = 1, t = mons; t && t->next; n++, t = t->next) ;
+ for(i = 1, t = mons; t && t->next && i < systraypinning; i++, t = t->next) ;
+ if(systraypinningfailfirst && n < systraypinning)
+ return mons;
+ return t;
+}
+
void
zoom(const Arg *arg)
{

+ 81
- 0
suckless/dwm/patches/dwm-uselessgap-6.2.diff View File

@ -0,0 +1,81 @@
From 58a5ece9406ca6c90dc362617c065e4aac19417f Mon Sep 17 00:00:00 2001
From: Cyril Cressent <cyril@cressent.org>
Date: Wed, 3 Jul 2019 21:33:45 -0700
Subject: [PATCH] Port the uselessgap patch to 6.2
---
config.def.h | 1 +
dwm.c | 36 ++++++++++++++++++++++++++++++------
2 files changed, 31 insertions(+), 6 deletions(-)
diff --git a/config.def.h b/config.def.h
index 1c0b587..b11471d 100644
--- a/config.def.h
+++ b/config.def.h
@@ -2,6 +2,7 @@
/* appearance */
static const unsigned int borderpx = 1; /* border pixel of windows */
+static const unsigned int gappx = 6; /* gaps between windows */
static const unsigned int snap = 32; /* snap pixel */
static const int showbar = 1; /* 0 means no bar */
static const int topbar = 1; /* 0 means bottom bar */
diff --git a/dwm.c b/dwm.c
index 4465af1..4545e05 100644
--- a/dwm.c
+++ b/dwm.c
@@ -52,8 +52,8 @@
#define ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags]))
#define LENGTH(X) (sizeof X / sizeof X[0])
#define MOUSEMASK (BUTTONMASK|PointerMotionMask)
-#define WIDTH(X) ((X)->w + 2 * (X)->bw)
-#define HEIGHT(X) ((X)->h + 2 * (X)->bw)
+#define WIDTH(X) ((X)->w + 2 * (X)->bw + gappx)
+#define HEIGHT(X) ((X)->h + 2 * (X)->bw + gappx)
#define TAGMASK ((1 << LENGTH(tags)) - 1)
#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad)
@@ -1276,13 +1276,37 @@ void
resizeclient(Client *c, int x, int y, int w, int h)
{
XWindowChanges wc;
+ unsigned int n;
+ unsigned int gapoffset;
+ unsigned int gapincr;
+ Client *nbc;
- c->oldx = c->x; c->x = wc.x = x;
- 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;
wc.border_width = c->bw;
+
+ /* Get number of clients for the selected monitor */
+ for (n = 0, nbc = nexttiled(selmon->clients); nbc; nbc = nexttiled(nbc->next), n++);
+
+ /* Do nothing if layout is floating */
+ if (c->isfloating || selmon->lt[selmon->sellt]->arrange == NULL) {
+ gapincr = gapoffset = 0;
+ } else {
+ /* Remove border and gap if layout is monocle or only one client */
+ if (selmon->lt[selmon->sellt]->arrange == monocle || n == 1) {
+ gapoffset = 0;
+ gapincr = -2 * borderpx;
+ wc.border_width = 0;
+ } else {
+ gapoffset = gappx;
+ gapincr = 2 * gappx;
+ }
+ }
+
+ c->oldx = c->x; c->x = wc.x = x + gapoffset;
+ c->oldy = c->y; c->y = wc.y = y + gapoffset;
+ c->oldw = c->w; c->w = wc.width = w - gapincr;
+ c->oldh = c->h; c->h = wc.height = h - gapincr;
+
XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc);
configure(c);
XSync(dpy, False);
2.22.0

+ 19
- 0
suckless/dwm/shiftview.c View File

@ -0,0 +1,19 @@
/** Function to shift the current view to the left/right
*
* @param: "arg->i" stores the number of tags to shift right (positive value)
* or left (negative value)
*/
void
shiftview(const Arg *arg) {
Arg shifted;
if(arg->i > 0) // left circular shift
shifted.ui = (selmon->tagset[selmon->seltags] << arg->i)
| (selmon->tagset[selmon->seltags] >> (LENGTH(tags) - arg->i));
else // right circular shift
shifted.ui = selmon->tagset[selmon->seltags] >> (- arg->i)
| selmon->tagset[selmon->seltags] << (LENGTH(tags) + arg->i);
view(&shifted);
}

+ 42
- 0
suckless/dwm/transient.c View File

@ -0,0 +1,42 @@
/* cc transient.c -o transient -lX11 */
#include <stdlib.h>
#include <unistd.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
int main(void) {
Display *d;
Window r, f, t = None;
XSizeHints h;
XEvent e;
d = XOpenDisplay(NULL);
if (!d)
exit(1);
r = DefaultRootWindow(d);
f = XCreateSimpleWindow(d, r, 100, 100, 400, 400, 0, 0, 0);
h.min_width = h.max_width = h.min_height = h.max_height = 400;
h.flags = PMinSize | PMaxSize;
XSetWMNormalHints(d, f, &h);
XStoreName(d, f, "floating");
XMapWindow(d, f);
XSelectInput(d, f, ExposureMask);
while (1) {
XNextEvent(d, &e);
if (t == None) {
sleep(5);
t = XCreateSimpleWindow(d, r, 50, 50, 100, 100, 0, 0, 0);
XSetTransientForHint(d, t, f);
XStoreName(d, t, "transient");
XMapWindow(d, t);
XSelectInput(d, t, ExposureMask);
}
}
XCloseDisplay(d);
exit(0);
}

+ 35
- 0
suckless/dwm/util.c View File

@ -0,0 +1,35 @@
/* See LICENSE file for copyright and license details. */
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "util.h"
void *
ecalloc(size_t nmemb, size_t size)
{
void *p;
if (!(p = calloc(nmemb, size)))
die("calloc:");
return p;
}
void
die(const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
if (fmt[0] && fmt[strlen(fmt)-1] == ':') {
fputc(' ', stderr);
perror(NULL);
} else {
fputc('\n', stderr);
}
exit(1);
}

+ 8
- 0
suckless/dwm/util.h View File

@ -0,0 +1,8 @@
/* See LICENSE file for copyright and license details. */
#define MAX(A, B) ((A) > (B) ? (A) : (B))
#define MIN(A, B) ((A) < (B) ? (A) : (B))
#define BETWEEN(X, A, B) ((A) <= (X) && (X) <= (B))
void die(const char *fmt, ...);
void *ecalloc(size_t nmemb, size_t size);

+ 3
- 0
suckless/dwmblocks/.gitignore View File

@ -0,0 +1,3 @@
dwmblocks
sigdwmblocks
xgetrootname

+ 32
- 0
suckless/dwmblocks/GNUmakefile View File

@ -0,0 +1,32 @@
#PREFIX := /usr/local
PREFIX := ${HOME}/.local
CC := gcc
CFLAGS := -O3 -Wall -Wextra
CFLAGSEXTRA := -Wno-missing-field-initializers -Wno-unused-parameter
X11CFLAGS := $(shell pkg-config --cflags x11)
X11LIBS := $(shell pkg-config --libs x11)
all: dwmblocks sigdwmblocks
dwmblocks: dwmblocks.c blocks.h
${CC} -o $@ ${CFLAGS} ${CFLAGSEXTRA} ${X11CFLAGS} $< ${X11LIBS}
sigdwmblocks: sigdwmblocks.c
${CC} -o $@ ${CFLAGS} $<
xgetrootname: xgetrootname.c
${CC} -o $@ ${CFLAGS} ${X11CFLAGS} $< ${X11LIBS}
clean:
rm -f dwmblocks sigdwmblocks
install: all
install -m 0755 dwmblocks ${DESTDIR}${PREFIX}/dwmblocks
install -m 0755 sigdwmblocks ${DESTDIR}${PREFIX}/sigdwmblocks
uninstall:
rm -f ${DESTDIR}${PREFIX}/bin/dwmblocks ${DESTDIR}${PREFIX}/sigdwmblocks
.PHONY: all clean install uninstall

+ 7
- 0
suckless/dwmblocks/LICENSE View File

@ -0,0 +1,7 @@
ISC License (ISC)
Copyright 2020 Ashish Kumar Yadav
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save