Snippets¶
This page shows small snippets that might be useful. Without further instructions they just need to be copied into the config of subtle.
- Table of contents
- Snippets
Alt-Tab¶
This cycles through windows of view
grab "A-Tab" do
clients = Subtlext::Client.visible
clients.last.instance_eval do
focus
raise
end
end
grab "A-S-Tab" do
clients = Subtlext::Client.visible
clients.first.instance_eval do
lower
end
clients.first.instance_eval do
focus
end
end
Extend view¶
require "subtle/subtlext"
STORE ||= {}
module Subtlext
class View
def method_missing(meth, *args)
STORE[self.name] = { } unless(STORE.has_key?(self.name))
if meth.to_s.end_with?("=")
meth = meth.to_s.chop.to_sym
STORE[self.name][meth] = args[0]
else
STORE[self.name][meth]
end
end
end
end
Finally make some use of this like following hook:
on :view_jump do |v|
v.visits += 1 rescue v.visits = 1
puts "View %s, %d visits" % [ v.name, v.visits ]
end
Focus gravities¶
Focus window a specific gravities on view.
{
"KP_7" => :top_left, "KP_8" => :top, "KP_9" => :top_right,
"KP_4" => :left, "KP_5" => :center, "KP_6" => :right,
"KP_1" => :bottom_left, "KP_2" => :bottom, "KP_3" => :bottom_right
}.each do |k, v|
grab "A-C-" + k, lambda {
c = Subtlext::View.current.clients.select { |c|
c.gravity.name.to_sym == v
}
c.first.focus unless(c.empty?)
}
end
Move windows¶
This snippet adds nine grabs to move windows on the fly to nine defined views. It uses tagging for this, creates tags based on the view names and applies them when needed.
on :start do
# Create missing tags
views = Subtlext::View.all.map { |v| v.name }
tags = Subtlext::Tag.all.map { |t| t.name }
views.each do |v|
unless tags.include?(v)
t = Subtlext::Tag.new(v)
t.save
end
end
end
# Add nine C-< number> grabs
(1..9).each do |i|
grab "C-%d" % [ i ] do |c|
views = Subtlext::View.all
names = views.map { |v| v.name }
# Sanity check
if i <= views.size
# Tag client
tags = c.tags.reject { |t| names.include?(t.name) or "default" == t.name }
tags << names[i - 1]
c.tags = tags
# Tag view
views[i - 1].tag(names[i - 1])
end
end
end
Current view¶
This snippet works similar to the previous, it adds tags based on the view names. When there is an untagged window (a window with the default tag only) it adds the name of the current view as tag, which effectively moves the window to the current view.
on :start do
# Create missing tags
views = Subtlext::View.all.map { |v| v.name }
tags = Subtlext::Tag.all.map { |t| t.name }
views.each do |v|
unless tags.include?(v)
t = Subtlext::Tag.new(v)
t.save
end
end
end
# Assign tags to clients
on :client_create do |c|
view = Subtlext::View.current
tags = c.tags.map { |t| t.name }
# Add tag to view
view.tag(view.name) unless(view.tags.include?(view.name))
# Exclusive for clients with default tag only
if tags.include?("default") and 1 == tags.size
c.tags = [ view.name ]
end
end
Scratchpad¶
The scratchpad snippet is just a small hack of the tagging. Normally subtle doesn't allow to create a window without tags, so that it's never visible. This grab just creates a urxvt, strips all tags and sets sticky. On the next press it just toggles sticky and blends the window in and out, like a scratchpad.
grab "A-b" do
if (c = Subtlext::Client.first("scratch"))
c.toggle_stick
c.focus
elsif (c = Subtlext::Client.spawn("urxvt -name scratch"))
c.tags = []
c.flags = [ :stick ]
end
end
Scratchstack¶
Like the Scratchpad, this snippet can show and hide a client, but instead just one specific client, it can cycle through multiple running ones. There are basically three grabs:
- Win-Keypad+ Adds a client to the stack and initially hides it
- Win-Keypad- Removes a client fromt he stack and retags it
- Win-comma Cycles through the clients on the stack
scratch_stack = []
scratch_current = 0
# Add window to stack
grab modkey + "-KP_Add" do |c|
unless scratch_stack.include?(c.win)
scratch_stack << c.win
c.tags = []
c.toggle_stick if c.is_stick?
end
end
# Remove window from stack
grab modkey + "-KP_Subtract" do |c|
if scratch_stack.include?(c.win)
c.retag
scratch_stack.delete(c.win)
end
end
# Cycle through stack windows
grab modkey + "-comma" do
# Get id of next window
if 0 < scratch_current
cur_idx = scratch_stack.index(scratch_current)
# Hide current window
cur_client = Subtlext::Client[scratch_current]
cur_client.toggle_stick
# Check whether cur is last window of stack
if cur_idx == scratch_stack.size - 1
scratch_current = 0
return
end
idx = cur_idx + 1
else
idx = 0
end
# Show next window
cur = Subtlext::Client[scratch_stack[idx]]
scratch_current = cur.win
cur.toggle_stick
end
Check config¶
In case you keep forgetting to run subtle -k
after changing the config this might be handy for you. It checks the config, displays a message via xmessage or just reloads the config.
# Make xmessage stick and urgent
tag "xmessage" do
match "xmessage"
float true
stick true
urgent true
end
# The actual grab
grab "A-C-r", <<SCRIPT
subtle -k &>/dev/null
reload=$?
if [ $reload -eq 1 ] ; then
xmessage 'Syntax error, reload anyway?' -center -buttons NO:1,YES:0
reload=$?
fi
[ $reload -eq 0 ] && subtler -r
SCRIPT
Switch view¶
Allow you to go to the next non-empty view. very useful when you don't want :ViewNext to go into hidden views (Mostly with dynamic views)
def goto_next_view(vArr)
cindx = vArr.index(Subtlext::View.current);
#Find the next view beyond all existing
for i in 1..vArr.size do
cV = vArr[(i + cindx) % vArr.size];
# Verify that the potential next view isn't displayed on another screens
if (Subtlext::View.visible.index(cV) == nil) then
containsClients = false;
# Check if the view has clients and if those clients are not only sticky one.
cV.clients.each {|c|
containsClients = !(cV.tags & c.tags).empty?;
if(containsClients)
break;
end
}
if (containsClients) then
cV.jump;
break;
end;
end
end
end
grab "W-Right" do
goto_next_view(Subtlext::View[:all]);
end
grab "W-Left" do
goto_next_view(Subtlext::View[:all].reverse);
end