Snippets » History » Version 42
« Previous -
Version 42/46
(diff) -
Next » -
Current version
Anonymous, 01/31/2013 03:16 PM
Snippets\015\012\015\012This page shows small snippets that might be useful. Without further instructions they just need to be copied into the config of subtle.\015\012\015\012{{>toc}}\015\012\015\012h2. Alt-Tab\015\012\015\012This cycles through windows of view\015\012\015\012{{hide}}\015\012grab "A-Tab" do\015\012 clients = Subtlext::Client.visible\015\012\015\012 clients.last.instance_eval do\015\012 focus\015\012 raise\015\012 end\015\012end\015\012\015\012grab "A-S-Tab" do \015\012clients = Subtlext::Client.visible\015\012\015\012 clients.first.instance_eval do \015\012 lower \015\012 end\015\012 clients.first.instance_eval do\015\012 focus\015\012 end \015\012end\015\012
\015\012\015\012h2. Extend view\015\012\015\012{{hide}}\015\012require "subtle/subtlext"\015\012\015\012STORE ||= {}\015\012\015\012module Subtlext\015\012 class View\015\012 def method_missing(meth, *args)\015\012 STORE[self.name] = { } unless(STORE.has_key?(self.name))\015\012\015\012 if meth.to_s.end_with?("=")\015\012 meth = meth.to_s.chop.to_sym\015\012\015\012 STORE[self.name][meth] = args[0]\015\012 else\015\012 STORE[self.name][meth]\015\012 end\015\012 end\015\012 end\015\012end\015\012
\015\012\015\012Finally make some use of this like following hook:\015\012\015\012{{hide}}\015\012on :view_jump do |v|\015\012 v.visits += 1 rescue v.visits = 1\015\012 puts "View %s, %d visits" % [ v.name, v.visits ]\015\012end\015\012
\015\012\015\012h2. Focus gravities\015\012\015\012Focus window a specific gravities on view.\015\012\015\012{{hide}}\015\012{\015\012 "KP_7" => :top_left, "KP_8" => :top, "KP_9" => :top_right,\015\012 "KP_4" => :left, "KP_5" => :center, "KP_6" => :right,\015\012 "KP_1" => :bottom_left, "KP_2" => :bottom, "KP_3" => :bottom_right\015\012}.each do |k, v|\015\012 grab "A-C-" + k, lambda {\015\012 c = Subtlext::View.current.clients.select { |c|\015\012 c.gravity.name.to_sym == v\015\012 }\015\012 \015\012 c.first.focus unless(c.empty?)\015\012 }\015\012end\015\012
\015\012\015\012h2. Move windows\015\012\015\012This 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.\015\012\015\012{{hide}}\015\012on :start do\015\012 # Create missing tags\015\012 views = Subtlext::View.all.map { |v| v.name }\015\012 tags = Subtlext::Tag.all.map { |t| t.name }\015\012\015\012 views.each do |v|\015\012 unless tags.include?(v)\015\012 t = Subtlext::Tag.new(v)\015\012 t.save\015\012 end\015\012 end\015\012end\015\012\015\012# Add nine C-< number> grabs\015\012(1..9).each do |i|\015\012 grab "C-%d" % [ i ] do |c|\015\012 views = Subtlext::View.all\015\012 names = views.map { |v| v.name }\015\012\015\012 # Sanity check\015\012 if i <= views.size\015\012 # Tag client\015\012 tags = c.tags.reject { |t| names.include?(t.name) or "default" == t.name }\015\012 tags << names[i - 1]\015\012\015\012 c.tags = tags\015\012\015\012 # Tag view\015\012 views[i - 1].tag(names[i - 1])\015\012 end\015\012 end\015\012end\015\012
\015\012\015\012h2. Current view\015\012\015\012This 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.\015\012\015\012{{hide}}\015\012on :start do\015\012 # Create missing tags\015\012 views = Subtlext::View.all.map { |v| v.name }\015\012 tags = Subtlext::Tag.all.map { |t| t.name }\015\012\015\012 views.each do |v|\015\012 unless tags.include?(v)\015\012 t = Subtlext::Tag.new(v)\015\012 t.save\015\012 end\015\012 end\015\012end\015\012\015\012# Assign tags to clients\015\012on :client_create do |c|\015\012 view = Subtlext::View.current\015\012 tags = c.tags.map { |t| t.name }\015\012\015\012 # Add tag to view\015\012 view.tag(view.name) unless(view.tags.include?(view.name))\015\012\015\012 # Exclusive for clients with default tag only\015\012 if tags.include?("default") and 1 == tags.size\015\012 c.tags = [ view.name ]\015\012 end\015\012end\015\012
\015\012\015\012h2. Scratchpad\015\012\015\012The 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.\015\012\015\012{{hide}}grab "A-b" do\015\012 if (c = Subtlext::Client.first("scratch"))\015\012 c.toggle_stick\015\012 c.focus\015\012 elsif (c = Subtlext::Client.spawn("urxvt -name scratch"))\015\012 c.tags = [] \015\012 c.flags = [ :stick ]\015\012 end\015\012end\015\012
\015\012\015\012h2. Scratchsrack\015\012\015\012Put clients into stack and cycle (show/hide) through them.\015\012\015\012{{hide}}\015\012scratch_stack = []\015\012scratch_current = 0\015\012\015\012# Add window to stack\015\012grab modkey + "-KP_Add" do |c|\015\012 unless scratch_stack.include?(c.win)\015\012 scratch_stack << c.win\015\012 c.tags = []\015\012 c.toggle_stick if c.is_stick?\015\012 end\015\012end\015\012\015\012# Remove window from stack\015\012grab modkey + "-KP_Subtract" do |c|\015\012 if scratch_stack.include?(c.win)\015\012 c.retag\015\012 scratch_stack.delete(c.win)\015\012 end\015\012end\015\012\015\012# Cycle through stack windows\015\012grab modkey + "-comma" do\015\012 # Get id of next window\015\012 if 0 < scratch_current\015\012 cur_idx = scratch_stack.index(scratch_current)\015\012\015\012 # Hide current window\015\012 cur_client = Subtlext::Client[scratch_current]\015\012 cur_client.toggle_stick\015\012\015\012 # Check whether cur is last window of stack\015\012 if cur_idx == scratch_stack.size - 1\015\012 scratch_current = 0\015\012\015\012 return\015\012 end\015\012\015\012 idx = cur_idx + 1\015\012 else\015\012 idx = 0\015\012 end\015\012\015\012 # Show next window\015\012 cur = Subtlext::Client[scratch_stack[idx]]\015\012\015\012 scratch_current = cur.win\015\012 cur.toggle_stick\015\012end\015\012
\015\012\015\012h2. Check config\015\012\015\012In 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.\015\012\015\012{{hide}}# Make xmessage stick and urgent\015\012tag "xmessage" do\015\012 match "xmessage"\015\012 float true\015\012 stick true\015\012 urgent true\015\012end\015\012\015\012# The actual grab\015\012grab "A-C-r", <<SCRIPT\015\012subtle -k &>/dev/null\015\012reload=$?\015\012\015\012if [ $reload -eq 1 ] ; then\015\012 xmessage 'Syntax error, reload anyway?' -center -buttons NO:1,YES:0\015\012 reload=$?\015\012fi\015\012\015\012[ $reload -eq 0 ] && subtler -r\015\012SCRIPT\015\012
\015\012\015\012h2. Switch view\015\012\015\012Allow 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)\015\012\015\012{{hide}}\015\012require "subtle/subtlext"\015\012grab "W-Right" do\015\012 vArr = Subtlext::View[:all];\015\012 cindx = vArr.index(Subtlext::View.current);\015\012\015\012 for i in 1..vArr.size do\015\012 cV = vArr[(i + cindx) % vArr.size];\015\012 if (!cV.clients.empty? && Subtlext::View.visible.index(cV) == nil) then\015\012 cV.jump;\015\012 break;\015\012 end\015\012 end\015\012end\015\012\015\012grab "W-Left" do\015\012 vArr = Subtlext::View[:all].reverse;\015\012 cindx = vArr.index(Subtlext::View.current);\015\012\015\012 for i in 1..vArr.size do\015\012 cV = vArr[(i + cindx) % vArr.size];\015\012 if (!cV.clients.empty? && Subtlext::View.visible.index(cV) == nil) then\015\012 cV.jump;\015\012 break;\015\012 end\015\012 end\015\012end\015\012\015\012
¶
\015\012grab "A-Tab" do\015\012 clients = Subtlext::Client.visible\015\012\015\012 clients.last.instance_eval do\015\012 focus\015\012 raise\015\012 end\015\012end\015\012\015\012grab "A-S-Tab" do \015\012clients = Subtlext::Client.visible\015\012\015\012 clients.first.instance_eval do \015\012 lower \015\012 end\015\012 clients.first.instance_eval do\015\012 focus\015\012 end \015\012end\015\012
\015\012require "subtle/subtlext"\015\012\015\012STORE ||= {}\015\012\015\012module Subtlext\015\012 class View\015\012 def method_missing(meth, *args)\015\012 STORE[self.name] = { } unless(STORE.has_key?(self.name))\015\012\015\012 if meth.to_s.end_with?("=")\015\012 meth = meth.to_s.chop.to_sym\015\012\015\012 STORE[self.name][meth] = args[0]\015\012 else\015\012 STORE[self.name][meth]\015\012 end\015\012 end\015\012 end\015\012end\015\012
\015\012on :view_jump do |v|\015\012 v.visits += 1 rescue v.visits = 1\015\012 puts "View %s, %d visits" % [ v.name, v.visits ]\015\012end\015\012
\015\012{\015\012 "KP_7" => :top_left, "KP_8" => :top, "KP_9" => :top_right,\015\012 "KP_4" => :left, "KP_5" => :center, "KP_6" => :right,\015\012 "KP_1" => :bottom_left, "KP_2" => :bottom, "KP_3" => :bottom_right\015\012}.each do |k, v|\015\012 grab "A-C-" + k, lambda {\015\012 c = Subtlext::View.current.clients.select { |c|\015\012 c.gravity.name.to_sym == v\015\012 }\015\012 \015\012 c.first.focus unless(c.empty?)\015\012 }\015\012end\015\012
\015\012on :start do\015\012 # Create missing tags\015\012 views = Subtlext::View.all.map { |v| v.name }\015\012 tags = Subtlext::Tag.all.map { |t| t.name }\015\012\015\012 views.each do |v|\015\012 unless tags.include?(v)\015\012 t = Subtlext::Tag.new(v)\015\012 t.save\015\012 end\015\012 end\015\012end\015\012\015\012# Add nine C-< number> grabs\015\012(1..9).each do |i|\015\012 grab "C-%d" % [ i ] do |c|\015\012 views = Subtlext::View.all\015\012 names = views.map { |v| v.name }\015\012\015\012 # Sanity check\015\012 if i <= views.size\015\012 # Tag client\015\012 tags = c.tags.reject { |t| names.include?(t.name) or "default" == t.name }\015\012 tags << names[i - 1]\015\012\015\012 c.tags = tags\015\012\015\012 # Tag view\015\012 views[i - 1].tag(names[i - 1])\015\012 end\015\012 end\015\012end\015\012
\015\012on :start do\015\012 # Create missing tags\015\012 views = Subtlext::View.all.map { |v| v.name }\015\012 tags = Subtlext::Tag.all.map { |t| t.name }\015\012\015\012 views.each do |v|\015\012 unless tags.include?(v)\015\012 t = Subtlext::Tag.new(v)\015\012 t.save\015\012 end\015\012 end\015\012end\015\012\015\012# Assign tags to clients\015\012on :client_create do |c|\015\012 view = Subtlext::View.current\015\012 tags = c.tags.map { |t| t.name }\015\012\015\012 # Add tag to view\015\012 view.tag(view.name) unless(view.tags.include?(view.name))\015\012\015\012 # Exclusive for clients with default tag only\015\012 if tags.include?("default") and 1 == tags.size\015\012 c.tags = [ view.name ]\015\012 end\015\012end\015\012
grab "A-b" do\015\012 if (c = Subtlext::Client.first("scratch"))\015\012 c.toggle_stick\015\012 c.focus\015\012 elsif (c = Subtlext::Client.spawn("urxvt -name scratch"))\015\012 c.tags = [] \015\012 c.flags = [ :stick ]\015\012 end\015\012end\015\012
\015\012scratch_stack = []\015\012scratch_current = 0\015\012\015\012# Add window to stack\015\012grab modkey + "-KP_Add" do |c|\015\012 unless scratch_stack.include?(c.win)\015\012 scratch_stack << c.win\015\012 c.tags = []\015\012 c.toggle_stick if c.is_stick?\015\012 end\015\012end\015\012\015\012# Remove window from stack\015\012grab modkey + "-KP_Subtract" do |c|\015\012 if scratch_stack.include?(c.win)\015\012 c.retag\015\012 scratch_stack.delete(c.win)\015\012 end\015\012end\015\012\015\012# Cycle through stack windows\015\012grab modkey + "-comma" do\015\012 # Get id of next window\015\012 if 0 < scratch_current\015\012 cur_idx = scratch_stack.index(scratch_current)\015\012\015\012 # Hide current window\015\012 cur_client = Subtlext::Client[scratch_current]\015\012 cur_client.toggle_stick\015\012\015\012 # Check whether cur is last window of stack\015\012 if cur_idx == scratch_stack.size - 1\015\012 scratch_current = 0\015\012\015\012 return\015\012 end\015\012\015\012 idx = cur_idx + 1\015\012 else\015\012 idx = 0\015\012 end\015\012\015\012 # Show next window\015\012 cur = Subtlext::Client[scratch_stack[idx]]\015\012\015\012 scratch_current = cur.win\015\012 cur.toggle_stick\015\012end\015\012
# Make xmessage stick and urgent\015\012tag "xmessage" do\015\012 match "xmessage"\015\012 float true\015\012 stick true\015\012 urgent true\015\012end\015\012\015\012# The actual grab\015\012grab "A-C-r", <<SCRIPT\015\012subtle -k &>/dev/null\015\012reload=$?\015\012\015\012if [ $reload -eq 1 ] ; then\015\012 xmessage 'Syntax error, reload anyway?' -center -buttons NO:1,YES:0\015\012 reload=$?\015\012fi\015\012\015\012[ $reload -eq 0 ] && subtler -r\015\012SCRIPT\015\012
\015\012require "subtle/subtlext"\015\012grab "W-Right" do\015\012 vArr = Subtlext::View[:all];\015\012 cindx = vArr.index(Subtlext::View.current);\015\012\015\012 for i in 1..vArr.size do\015\012 cV = vArr[(i + cindx) % vArr.size];\015\012 if (!cV.clients.empty? && Subtlext::View.visible.index(cV) == nil) then\015\012 cV.jump;\015\012 break;\015\012 end\015\012 end\015\012end\015\012\015\012grab "W-Left" do\015\012 vArr = Subtlext::View[:all].reverse;\015\012 cindx = vArr.index(Subtlext::View.current);\015\012\015\012 for i in 1..vArr.size do\015\012 cV = vArr[(i + cindx) % vArr.size];\015\012 if (!cV.clients.empty? && Subtlext::View.visible.index(cV) == nil) then\015\012 cV.jump;\015\012 break;\015\012 end\015\012 end\015\012end\015\012\015\012