mirror of https://github.com/0intro/wmii
Sync ruby wmiirc.
This commit is contained in:
parent
6afe9e6262
commit
b26fc42fed
|
@ -19,28 +19,3 @@ 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.
|
||||
|
||||
|
||||
Portions of this software originate from wmii <http://wmii.suckless.org>:
|
||||
|
||||
(the MIT license)
|
||||
|
||||
© 2006-2007 Kris Maglione <fbsdaemon@gmail.com>
|
||||
© 2003-2006 Anselm R. Garbe <garbeam at suckless dot org>
|
||||
|
||||
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.
|
||||
|
|
|
@ -54,13 +54,26 @@ Installation:
|
|||
mv ~/.wmii-hg ~/.wmii-hg.backup
|
||||
git clone git://github.com/sunaku/wmiirc.git ~/.wmii-hg
|
||||
|
||||
# choose
|
||||
cd ~/.wmii-hg
|
||||
git checkout --track -b CHOICE origin/CHOICE # choices are:
|
||||
|
||||
+--------+------------------------------------------------+
|
||||
| CHOICE | DESCRIPTION |
|
||||
+--------+------------------------------------------------+
|
||||
| dvorak | sunaku's personal configuration; DSK friendly! |
|
||||
| qwerty | QWERTY port of sunaku's personal configuration |
|
||||
| strict | port of the default wmiirc shipped with wmii |
|
||||
| master | barebones template for starting from scratch |
|
||||
+--------+------------------------------------------------+
|
||||
|
||||
# run
|
||||
~/.wmii-hg/wmiirc
|
||||
|
||||
Documentation:
|
||||
|
||||
# see list of all key bindings
|
||||
grep 'Mod.*#' ~/.wmii-hg/config.yaml
|
||||
egrep '^ +\$\{\w+\}' ~/.wmii-hg/config.yaml
|
||||
|
||||
# read the configuration file
|
||||
less ~/.wmii-hg/config.yaml
|
||||
|
@ -71,7 +84,11 @@ Configuration:
|
|||
|
||||
Run ~/.wmii-hg/wmiirc to apply your changes.
|
||||
|
||||
Contribution:
|
||||
|
||||
Fork this project on GitHub and send pull requests.
|
||||
|
||||
Questions:
|
||||
|
||||
Send me an e-mail; see LICENSE for my address.
|
||||
Send me an e-mail (see LICENSE for my address).
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ ACTIONS = Handler.new
|
|||
KEYS = Handler.new
|
||||
|
||||
##
|
||||
# When a block is given, registers a handler
|
||||
# If a block is given, registers a handler
|
||||
# for the given event and returns the handler.
|
||||
#
|
||||
# Otherwise, executes all handlers for the given event.
|
||||
|
@ -106,7 +106,10 @@ end
|
|||
# Instruction on what the user should enter or choose.
|
||||
#
|
||||
def key_menu choices, prompt = nil
|
||||
words = %w[dmenu -b -fn].push(CONFIG['display']['font'])
|
||||
words = ['dmenu', '-fn', CONFIG['display']['font']]
|
||||
|
||||
# show menu at the same location as the status bar
|
||||
words << '-b' if CONFIG['display']['bar'] == 'bottom'
|
||||
|
||||
words.concat %w[-nf -nb -sf -sb].zip(
|
||||
[
|
||||
|
@ -145,11 +148,11 @@ end
|
|||
# The choice that should be initially selected.
|
||||
#
|
||||
# If this choice is not included in the list
|
||||
# of cohices, then this item will be made
|
||||
# of choices, then this item will be made
|
||||
# into a makeshift title-bar for the menu.
|
||||
#
|
||||
def click_menu choices, initial = nil
|
||||
words = %w[wmii9menu]
|
||||
words = ['wmii9menu']
|
||||
|
||||
if initial
|
||||
words << '-i'
|
||||
|
@ -169,6 +172,36 @@ def click_menu choices, initial = nil
|
|||
choice unless choice.empty?
|
||||
end
|
||||
|
||||
##
|
||||
# Shows a key_menu() containing the given
|
||||
# clients and returns the chosen client.
|
||||
#
|
||||
# If nothing was chosen, then nil is returned.
|
||||
#
|
||||
# ==== Parameters
|
||||
#
|
||||
# [prompt]
|
||||
# Instruction on what the user should enter or choose.
|
||||
#
|
||||
# [clients]
|
||||
# List of clients to present as choices to the user.
|
||||
#
|
||||
# If this parameter is not specified,
|
||||
# its default value will be a list of
|
||||
# all currently available clients.
|
||||
#
|
||||
def client_menu prompt = nil, clients = Rumai.clients
|
||||
choices = []
|
||||
|
||||
clients.each_with_index do |c, i|
|
||||
choices << "%d. [%s] %s" % [i, c[:tags].read, c[:label].read.downcase]
|
||||
end
|
||||
|
||||
if target = key_menu(choices, prompt)
|
||||
clients[target.scan(/\d+/).first.to_i]
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Returns the basenames of executable files present in the given directories.
|
||||
#
|
||||
|
@ -269,7 +302,7 @@ def load_config config_file
|
|||
# applied. but a "bad command" error is raised nevertheless!
|
||||
#
|
||||
warn e.inspect
|
||||
warn e.backtrace
|
||||
warn e.backtrace.join("\n")
|
||||
end
|
||||
|
||||
launch 'xsetroot', '-solid', CONFIG['display']['background']
|
||||
|
@ -343,7 +376,7 @@ def load_config config_file
|
|||
|
||||
@status_button_by_name.each_value {|b| b.refresh }
|
||||
|
||||
end.call
|
||||
end
|
||||
|
||||
##
|
||||
# Returns the status button associated with the given name.
|
||||
|
@ -400,14 +433,106 @@ def load_config config_file
|
|||
end
|
||||
|
||||
# control
|
||||
action 'reload' do
|
||||
# reload this wmii configuration
|
||||
reload_config
|
||||
end
|
||||
|
||||
action 'rehash' do
|
||||
# scan for available programs and actions
|
||||
@programs = find_programs(ENV['PATH'].squeeze(':').split(':'))
|
||||
end
|
||||
|
||||
# kill all currently open clients
|
||||
action 'clear' do
|
||||
# firefox's restore session feature does not
|
||||
# work unless the whole process is killed.
|
||||
system 'killall firefox firefox-bin thunderbird thunderbird-bin'
|
||||
|
||||
# gnome-panel refuses to die by any other means
|
||||
system 'killall -s TERM gnome-panel'
|
||||
|
||||
Thread.pass until clients.each do |c|
|
||||
begin
|
||||
c.focus # XXX: client must be on current view in order to be killed
|
||||
c.kill
|
||||
rescue
|
||||
# ignore
|
||||
end
|
||||
end.empty?
|
||||
end
|
||||
|
||||
# kill the window manager only; do not touch the clients!
|
||||
action 'kill' do
|
||||
fs.ctl.write 'quit'
|
||||
end
|
||||
|
||||
# kill both clients and window manager
|
||||
action 'quit' do
|
||||
action 'clear'
|
||||
action 'kill'
|
||||
end
|
||||
|
||||
event 'Unresponsive' do |client_id|
|
||||
client = Client.new(client_id)
|
||||
|
||||
IO.popen('xmessage -nearmouse -file - -buttons Kill,Wait -print', 'w+') do |f|
|
||||
f.puts 'The following client is not responding.', ''
|
||||
f.puts client.inspect
|
||||
f.puts client.label.read
|
||||
|
||||
f.puts '', 'What would you like to do?'
|
||||
f.close_write
|
||||
|
||||
if f.read.chomp == 'Kill'
|
||||
client.slay
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
event 'Notice' do |*argv|
|
||||
unless defined? @notice_mutex
|
||||
require 'thread'
|
||||
@notice_mutex = Mutex.new
|
||||
end
|
||||
|
||||
Thread.new do
|
||||
# prevent notices from overwriting each other
|
||||
@notice_mutex.synchronize do
|
||||
button = fs.rbar['!notice']
|
||||
button.create unless button.exist?
|
||||
|
||||
# display the notice
|
||||
message = argv.join(' ')
|
||||
|
||||
LOG.info message # also log it in case the user is AFK
|
||||
button.write "#{CONFIG['display']['color']['notice']} #{message}"
|
||||
|
||||
# clear the notice
|
||||
sleep [1, CONFIG['display']['notice'].to_i].max
|
||||
button.remove
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
%w[key action event].each do |param|
|
||||
CONFIG['control'][param].each do |name, code|
|
||||
eval "#{param}(#{name.inspect}) {|*argv| #{code} }",
|
||||
TOPLEVEL_BINDING, "#{config_file}:control:#{param}:#{name}"
|
||||
if settings = CONFIG['control'][param]
|
||||
settings.each do |name, code|
|
||||
if param == 'key'
|
||||
# expand ${...} expressions in shortcut key sequences
|
||||
name = name.gsub(/\$\{(.+?)\}/) { CONFIG['control'][$1] }
|
||||
end
|
||||
|
||||
eval "#{param}(#{name.inspect}) {|*argv| #{code} }",
|
||||
TOPLEVEL_BINDING, "#{config_file}:control:#{param}:#{name}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# script
|
||||
action 'status'
|
||||
action 'rehash'
|
||||
|
||||
eval CONFIG['script']['after'].to_s, TOPLEVEL_BINDING,
|
||||
"#{config_file}:script:after"
|
||||
|
||||
|
@ -418,5 +543,5 @@ end
|
|||
#
|
||||
def reload_config
|
||||
LOG.info 'reload'
|
||||
launch $0
|
||||
exec $0
|
||||
end
|
||||
|
|
|
@ -11,6 +11,16 @@
|
|||
#++
|
||||
|
||||
|
||||
##
|
||||
# Program preferences.
|
||||
#
|
||||
program:
|
||||
terminal: urxvt
|
||||
browser: firefox
|
||||
editor: mousepad
|
||||
filer: thunar
|
||||
|
||||
|
||||
##
|
||||
# Appearance settings.
|
||||
#
|
||||
|
@ -26,7 +36,7 @@ display:
|
|||
##
|
||||
# The font to use in all text drawn by wmii.
|
||||
#
|
||||
font: -*-fixed-medium-r-*-*-18-*-*-*-*-*-*-*
|
||||
font: -*-fixed-medium-r-*-*-13-*-*-*-*-*-*-*
|
||||
|
||||
##
|
||||
# Thickness of client border (measured in pixels).
|
||||
|
@ -48,11 +58,11 @@ display:
|
|||
# http://wmii.suckless.org/scripts_n_snips/themes
|
||||
#
|
||||
color:
|
||||
normal: "#c0c0c0 #0a0a0a #202020"
|
||||
focus: "#ffffff #285577 #4c7899"
|
||||
error: "#8a1f11 #FBE3E4 #FBC2C4" # from http://www.blueprintcss.org
|
||||
notice: "#514721 #FFF6BF #FFD324" # from http://www.blueprintcss.org
|
||||
success: "#264409 #E6EFC2 #C6D880" # from http://www.blueprintcss.org
|
||||
normal: "#000000 #c1c48b #81654f"
|
||||
focus: "#000000 #81654f #000000"
|
||||
error: "#000000 #81654f #000000"
|
||||
notice: "#000000 #a1956d #413328"
|
||||
success: "#000000 #c1c48b #81654f"
|
||||
|
||||
##
|
||||
# Color of desktop background.
|
||||
|
@ -69,7 +79,7 @@ display:
|
|||
mode: default
|
||||
rule: |
|
||||
/gimp/ -> 17+83+41
|
||||
/.*/ -> 50+50
|
||||
/.*/ -> 62+38 # Golden Ratio
|
||||
|
||||
##
|
||||
# Mapping of clients to views they must appear on.
|
||||
|
@ -80,10 +90,7 @@ display:
|
|||
# Processing stops after the first matching mapping is applied.
|
||||
#
|
||||
client:
|
||||
- /\b(xconsole|alsamixer|XMMS|Sonata)\b/ : 1
|
||||
- /^pidgin:|:WeeChat\b/ : chat
|
||||
- /\b(Liferea|GMail|Thunderbird)\b/ : mail
|
||||
- /:(Firefox|Shiretoko):.*\bRestore\b.*\bSession\b/ : web
|
||||
- /MPlayer|VLC/ : ~
|
||||
|
||||
##
|
||||
# Self-refreshing buttons on the status bar.
|
||||
|
@ -103,42 +110,6 @@ display:
|
|||
# bar reflects the vertical order in which they are defined below.
|
||||
#
|
||||
status:
|
||||
- music:
|
||||
refresh: 15
|
||||
content: |
|
||||
unless defined? @music
|
||||
require 'rubygems'
|
||||
gem 'librmpd', '~> 0.1'
|
||||
require 'librmpd'
|
||||
|
||||
@music = MPD.new
|
||||
end
|
||||
|
||||
unless @music.connected?
|
||||
@music.connect
|
||||
end
|
||||
|
||||
music_state = (@music.stopped? || @music.paused?) ? '(-)' : '(>)'
|
||||
|
||||
if song = @music.current_song
|
||||
artist = song.artist
|
||||
title = song.title || (f = song.file and File.basename(f))
|
||||
song_name = [artist, title].compact.join(': ')
|
||||
end
|
||||
|
||||
[music_state, song_name].compact
|
||||
|
||||
- volume:
|
||||
refresh: 60
|
||||
content: |
|
||||
['volume', `amixer get Master`.scan(/\d+%/).first]
|
||||
|
||||
- disk_space:
|
||||
refresh: 600 # 10 minutes
|
||||
content: |
|
||||
free, used, path = `df -h ~`.split.last(3)
|
||||
[path, used, 'used', free, 'free']
|
||||
|
||||
- system_load:
|
||||
refresh: 10
|
||||
content: |
|
||||
|
@ -168,374 +139,154 @@ control:
|
|||
#
|
||||
grab: Mod1
|
||||
|
||||
##
|
||||
# Prefix for all shortcuts.
|
||||
#
|
||||
mod: Mod1
|
||||
|
||||
##
|
||||
# Direction keys.
|
||||
#
|
||||
up: k
|
||||
down: j
|
||||
left: h
|
||||
right: l
|
||||
|
||||
##
|
||||
# Key bindings.
|
||||
#
|
||||
# <key sequence>: <Ruby code to execute>
|
||||
#
|
||||
# A key sequence may contain ${...} expressions which
|
||||
# are replaced with the value corresponding to '...'
|
||||
# in the 'control' section of this configuration file.
|
||||
#
|
||||
# For example, if the 'control' section of
|
||||
# this configuration file appeared like this:
|
||||
#
|
||||
# control:
|
||||
# foo: Mod4
|
||||
# bar: y
|
||||
#
|
||||
# and the following key sequence was used:
|
||||
#
|
||||
# ${foo}-${bar},${bar}
|
||||
#
|
||||
# then after ${...} expression replacement,
|
||||
# that key sequence would appear like this:
|
||||
#
|
||||
# Mod4-y,y
|
||||
#
|
||||
key:
|
||||
#---------------------------------------------------------------------------
|
||||
# focus
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
Mod1-Control-t: | # focus above client
|
||||
${mod}-${up}: | # focus above client
|
||||
curr_view.select(:up) rescue nil
|
||||
|
||||
Mod1-Control-n: | # focus below client
|
||||
${mod}-${down}: | # focus below client
|
||||
curr_view.select(:down) rescue nil
|
||||
|
||||
Mod1-Control-h: | # focus left client
|
||||
${mod}-${left}: | # focus left client
|
||||
curr_view.select(:left) rescue nil
|
||||
|
||||
Mod1-Control-s: | # focus right client
|
||||
${mod}-${right}: | # focus right client
|
||||
curr_view.select(:right) rescue nil
|
||||
|
||||
Mod1-Control-space: | # focus floating area (toggle)
|
||||
${mod}-space: | # focus floating area (toggle)
|
||||
curr_view.select(:toggle)
|
||||
|
||||
Mod1-Control-comma: | # focus previous view
|
||||
prev_view.focus
|
||||
|
||||
Mod1-Control-period: | # focus next view
|
||||
next_view.focus
|
||||
|
||||
# focus the view whose index or name equals the pressed number
|
||||
Mod1-Control-1: focus_view( tags[0] || 1 )
|
||||
Mod1-Control-2: focus_view( tags[1] || 2 )
|
||||
Mod1-Control-3: focus_view( tags[2] || 3 )
|
||||
Mod1-Control-4: focus_view( tags[3] || 4 )
|
||||
Mod1-Control-5: focus_view( tags[4] || 5 )
|
||||
Mod1-Control-6: focus_view( tags[5] || 6 )
|
||||
Mod1-Control-7: focus_view( tags[6] || 7 )
|
||||
Mod1-Control-8: focus_view( tags[7] || 8 )
|
||||
Mod1-Control-9: focus_view( tags[8] || 9 )
|
||||
Mod1-Control-0: focus_view( tags[9] || 10 )
|
||||
|
||||
# focus the view whose name begins with the pressed alphabet
|
||||
Mod1-Control-v,a: t = tags.grep(/^a/i).first and focus_view(t)
|
||||
Mod1-Control-v,b: t = tags.grep(/^b/i).first and focus_view(t)
|
||||
Mod1-Control-v,c: t = tags.grep(/^c/i).first and focus_view(t)
|
||||
Mod1-Control-v,d: t = tags.grep(/^d/i).first and focus_view(t)
|
||||
Mod1-Control-v,e: t = tags.grep(/^e/i).first and focus_view(t)
|
||||
Mod1-Control-v,f: t = tags.grep(/^f/i).first and focus_view(t)
|
||||
Mod1-Control-v,g: t = tags.grep(/^g/i).first and focus_view(t)
|
||||
Mod1-Control-v,h: t = tags.grep(/^h/i).first and focus_view(t)
|
||||
Mod1-Control-v,i: t = tags.grep(/^i/i).first and focus_view(t)
|
||||
Mod1-Control-v,j: t = tags.grep(/^j/i).first and focus_view(t)
|
||||
Mod1-Control-v,k: t = tags.grep(/^k/i).first and focus_view(t)
|
||||
Mod1-Control-v,l: t = tags.grep(/^l/i).first and focus_view(t)
|
||||
Mod1-Control-v,m: t = tags.grep(/^m/i).first and focus_view(t)
|
||||
Mod1-Control-v,n: t = tags.grep(/^n/i).first and focus_view(t)
|
||||
Mod1-Control-v,o: t = tags.grep(/^o/i).first and focus_view(t)
|
||||
Mod1-Control-v,p: t = tags.grep(/^p/i).first and focus_view(t)
|
||||
Mod1-Control-v,q: t = tags.grep(/^q/i).first and focus_view(t)
|
||||
Mod1-Control-v,r: t = tags.grep(/^r/i).first and focus_view(t)
|
||||
Mod1-Control-v,s: t = tags.grep(/^s/i).first and focus_view(t)
|
||||
Mod1-Control-v,t: t = tags.grep(/^t/i).first and focus_view(t)
|
||||
Mod1-Control-v,u: t = tags.grep(/^u/i).first and focus_view(t)
|
||||
Mod1-Control-v,v: t = tags.grep(/^v/i).first and focus_view(t)
|
||||
Mod1-Control-v,w: t = tags.grep(/^w/i).first and focus_view(t)
|
||||
Mod1-Control-v,x: t = tags.grep(/^x/i).first and focus_view(t)
|
||||
Mod1-Control-v,y: t = tags.grep(/^y/i).first and focus_view(t)
|
||||
Mod1-Control-v,z: t = tags.grep(/^z/i).first and focus_view(t)
|
||||
${mod}-1: focus_view tags[0] || 1
|
||||
${mod}-2: focus_view tags[1] || 2
|
||||
${mod}-3: focus_view tags[2] || 3
|
||||
${mod}-4: focus_view tags[3] || 4
|
||||
${mod}-5: focus_view tags[4] || 5
|
||||
${mod}-6: focus_view tags[5] || 6
|
||||
${mod}-7: focus_view tags[6] || 7
|
||||
${mod}-8: focus_view tags[7] || 8
|
||||
${mod}-9: focus_view tags[8] || 9
|
||||
${mod}-0: focus_view tags[9] || 10
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# move
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
Mod1-Control-m,t: | # move grouping toward the top
|
||||
${mod}-Shift-${up}: | # move grouping toward the top
|
||||
grouping.each {|c| c.send(:up) rescue nil }
|
||||
|
||||
Mod1-Control-m,n: | # move grouping toward the bottom
|
||||
${mod}-Shift-${down}: | # move grouping toward the bottom
|
||||
grouping.each {|c| c.send(:down) rescue nil }
|
||||
|
||||
Mod1-Control-m,h: | # move grouping toward the left
|
||||
${mod}-Shift-${left}: | # move grouping toward the left
|
||||
grouping.each {|c| c.send(:left) rescue nil }
|
||||
|
||||
Mod1-Control-m,s: | # move grouping toward the right
|
||||
${mod}-Shift-${right}: | # move grouping toward the right
|
||||
grouping.each {|c| c.send(:right) rescue nil }
|
||||
|
||||
Mod1-Control-m,space: | # move grouping to floating area (toggle)
|
||||
${mod}-Shift-space: | # move grouping to floating area (toggle)
|
||||
grouping.each {|c| c.send(:toggle) rescue nil }
|
||||
|
||||
Mod1-Control-m,v: | # move grouping to chosen view
|
||||
#
|
||||
# Changes the tag (according to a menu choice) of
|
||||
# each grouped client and returns the chosen tag.
|
||||
#
|
||||
# The +tag -tag idea is from Jonas Pfenniger:
|
||||
#
|
||||
# http://zimbatm.oree.ch/articles/2006/06/15/wmii-3-and-ruby
|
||||
#
|
||||
choices = tags.map {|t| [t, "+#{t}", "-#{t}"] }.flatten
|
||||
|
||||
if target = key_menu(choices, 'tag as:')
|
||||
grouping.each do |c|
|
||||
case target
|
||||
when /^\+/ then c.tag $'
|
||||
when /^\-/ then c.untag $'
|
||||
else c.tags = target
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Mod1-Control-m,Delete: | # kill all clients in grouping
|
||||
grouping.each {|c| c.kill }
|
||||
|
||||
# move grouping to the view whose index or name equals the pressed number
|
||||
Mod1-Control-m,1: grouping.each {|c| c.tags = tags[0] || 1 }
|
||||
Mod1-Control-m,2: grouping.each {|c| c.tags = tags[1] || 2 }
|
||||
Mod1-Control-m,3: grouping.each {|c| c.tags = tags[2] || 3 }
|
||||
Mod1-Control-m,4: grouping.each {|c| c.tags = tags[3] || 4 }
|
||||
Mod1-Control-m,5: grouping.each {|c| c.tags = tags[4] || 5 }
|
||||
Mod1-Control-m,6: grouping.each {|c| c.tags = tags[5] || 6 }
|
||||
Mod1-Control-m,7: grouping.each {|c| c.tags = tags[6] || 7 }
|
||||
Mod1-Control-m,8: grouping.each {|c| c.tags = tags[7] || 8 }
|
||||
Mod1-Control-m,9: grouping.each {|c| c.tags = tags[8] || 9 }
|
||||
Mod1-Control-m,0: grouping.each {|c| c.tags = tags[9] || 10 }
|
||||
${mod}-Shift-1: grouping.each {|c| c.tags = tags[0] || 1 }
|
||||
${mod}-Shift-2: grouping.each {|c| c.tags = tags[1] || 2 }
|
||||
${mod}-Shift-3: grouping.each {|c| c.tags = tags[2] || 3 }
|
||||
${mod}-Shift-4: grouping.each {|c| c.tags = tags[3] || 4 }
|
||||
${mod}-Shift-5: grouping.each {|c| c.tags = tags[4] || 5 }
|
||||
${mod}-Shift-6: grouping.each {|c| c.tags = tags[5] || 6 }
|
||||
${mod}-Shift-7: grouping.each {|c| c.tags = tags[6] || 7 }
|
||||
${mod}-Shift-8: grouping.each {|c| c.tags = tags[7] || 8 }
|
||||
${mod}-Shift-9: grouping.each {|c| c.tags = tags[8] || 9 }
|
||||
${mod}-Shift-0: grouping.each {|c| c.tags = tags[9] || 10 }
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# swap
|
||||
# client
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
Mod1-Control-w,t: | # swap with above client
|
||||
curr_client.swap(:up) rescue nil
|
||||
${mod}-f: | # zoom client to fullscreen (toggle)
|
||||
curr_client.fullscreen!
|
||||
|
||||
Mod1-Control-w,n: | # swap with below client
|
||||
curr_client.swap(:down) rescue nil
|
||||
|
||||
Mod1-Control-w,h: | # swap with left client
|
||||
curr_client.swap(:left) rescue nil
|
||||
|
||||
Mod1-Control-w,s: | # swap with right client
|
||||
curr_client.swap(:right) rescue nil
|
||||
|
||||
# swap current client with the column whose index equals the pressed number
|
||||
Mod1-Control-w,1: curr_client.swap 1
|
||||
Mod1-Control-w,2: curr_client.swap 2
|
||||
Mod1-Control-w,3: curr_client.swap 3
|
||||
Mod1-Control-w,4: curr_client.swap 4
|
||||
Mod1-Control-w,5: curr_client.swap 5
|
||||
Mod1-Control-w,6: curr_client.swap 6
|
||||
Mod1-Control-w,7: curr_client.swap 7
|
||||
Mod1-Control-w,8: curr_client.swap 8
|
||||
Mod1-Control-w,9: curr_client.swap 9
|
||||
Mod1-Control-w,0: curr_client.swap 10
|
||||
${mod}-Shift-c: | # kill the current client
|
||||
curr_client.kill
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# column
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
Mod1-Control-z,w: | # apply equal-spacing layout to current column
|
||||
curr_area.layout = :default
|
||||
${mod}-d: | # apply equal-spacing layout to current column
|
||||
curr_area.layout = 'default-max'
|
||||
|
||||
Mod1-Control-z,Shift-w: | # apply equal-spacing layout to all columns
|
||||
curr_view.columns.each do |a|
|
||||
a.layout = :default
|
||||
end
|
||||
|
||||
Mod1-Control-z,v: | # apply stacked layout to current column
|
||||
${mod}-v: | # apply stacked layout to current column
|
||||
curr_area.layout = 'stack-max'
|
||||
|
||||
Mod1-Control-z,Shift-v: | # apply stacked layout to all columns
|
||||
curr_view.columns.each do |a|
|
||||
a.layout = 'stack-max'
|
||||
end
|
||||
|
||||
Mod1-Control-z,m: | # apply maximized layout to current column
|
||||
${mod}-m: | # apply maximized layout to current column
|
||||
curr_area.layout = 'stack+max'
|
||||
|
||||
Mod1-Control-z,Shift-m: | # apply maximized layout to all columns
|
||||
curr_view.columns.each do |a|
|
||||
a.layout = 'stack+max'
|
||||
end
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# group
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
Mod1-Control-g,g: | # toggle current client from grouping
|
||||
curr_client.group!
|
||||
|
||||
Mod1-Control-g,c: | # add clients in current area to grouping
|
||||
curr_area.group
|
||||
|
||||
Mod1-Control-g,Shift-c: | # remove clients in current area from grouping
|
||||
curr_area.ungroup
|
||||
|
||||
Mod1-Control-g,f: | # add clients in floating area to grouping
|
||||
Area.floating.group
|
||||
|
||||
Mod1-Control-g,Shift-f: | # remove clients in floating area from grouping
|
||||
Area.floating.ungroup
|
||||
|
||||
Mod1-Control-g,m: | # add clients in managed areas to grouping
|
||||
curr_view.managed_areas.each {|a| a.group }
|
||||
|
||||
Mod1-Control-g,Shift-m: | # remove clients in managed areas from grouping
|
||||
curr_view.managed_areas.each {|a| a.ungroup }
|
||||
|
||||
Mod1-Control-g,v: | # add clients in current view to grouping
|
||||
curr_view.group
|
||||
|
||||
Mod1-Control-g,Shift-v: | # remove clients in current view from grouping
|
||||
curr_view.ungroup
|
||||
|
||||
Mod1-Control-g,i: | # invert the grouping in the current view
|
||||
curr_view.group!
|
||||
|
||||
Mod1-Control-g,Shift-i: | # invert the grouping in all views
|
||||
Rumai.group!
|
||||
|
||||
Mod1-Control-g,n: | # remove all clients everywhere from grouping
|
||||
Rumai.ungroup
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# detach
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
Mod1-Control-d: | # detach grouping from current view
|
||||
grouping.each do |c|
|
||||
c.with_tags do
|
||||
delete curr_tag
|
||||
push DETACHED_TAG
|
||||
end
|
||||
end
|
||||
|
||||
Mod1-Control-Shift-d: | # attach most recently detached client
|
||||
v = View.new DETACHED_TAG
|
||||
|
||||
if v.exist? and c = v.clients.last
|
||||
c.with_tags do
|
||||
delete DETACHED_TAG
|
||||
push curr_tag
|
||||
end
|
||||
end
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# zoom
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
Mod1-Control-f: | # zoom client to fullscreen (toggle)
|
||||
curr_client.fullscreen!
|
||||
|
||||
Mod1-Control-b: | # copy grouping to temporary view
|
||||
clients = grouping
|
||||
|
||||
unless clients.empty?
|
||||
# determine new view
|
||||
if curr_tag =~ ZOOMED_SUFFIX
|
||||
src, num = $`, $1.to_i
|
||||
dst = "#{src}~#{num+1}"
|
||||
else
|
||||
dst = "#{curr_tag}~1"
|
||||
end
|
||||
|
||||
# add clients to new view
|
||||
clients.each {|c| c.tag dst }
|
||||
|
||||
# focus new view
|
||||
v = View.new dst
|
||||
v.focus
|
||||
v.arrange_in_grid
|
||||
|
||||
# propagate focus into new view
|
||||
clients.first.focus v
|
||||
end
|
||||
|
||||
Mod1-Control-Shift-b: | # return grouping to original view
|
||||
clients = grouping
|
||||
|
||||
unless clients.empty?
|
||||
src = curr_tag
|
||||
|
||||
if src =~ ZOOMED_SUFFIX
|
||||
# determine new view
|
||||
dst = $`
|
||||
|
||||
# remove clients from old view
|
||||
clients.each do |c|
|
||||
c.with_tags do
|
||||
delete src
|
||||
|
||||
if empty?
|
||||
push dst
|
||||
else
|
||||
dst = last
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# focus new view
|
||||
v = View.new dst
|
||||
v.focus
|
||||
|
||||
# propagate focus into original view
|
||||
clients.first.focus v
|
||||
end
|
||||
end
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# arrange
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
Mod1-Control-z,t: | # arrange clients in current view like LarsWM does
|
||||
curr_view.arrange_as_larswm
|
||||
|
||||
Mod1-Control-z,g: | # arrange clients in current view like a grid
|
||||
curr_view.arrange_in_grid
|
||||
|
||||
Mod1-Control-z,d: | # arrange clients in current view like a diamond
|
||||
curr_view.arrange_in_diamond
|
||||
|
||||
# apply grid layout with the pressed number of clients per column
|
||||
Mod1-Control-z,1: curr_view.arrange_in_grid 1
|
||||
Mod1-Control-z,2: curr_view.arrange_in_grid 2
|
||||
Mod1-Control-z,3: curr_view.arrange_in_grid 3
|
||||
Mod1-Control-z,4: curr_view.arrange_in_grid 4
|
||||
Mod1-Control-z,5: curr_view.arrange_in_grid 5
|
||||
Mod1-Control-z,6: curr_view.arrange_in_grid 6
|
||||
Mod1-Control-z,7: curr_view.arrange_in_grid 7
|
||||
Mod1-Control-z,8: curr_view.arrange_in_grid 8
|
||||
Mod1-Control-z,9: curr_view.arrange_in_grid 9
|
||||
Mod1-Control-z,0: curr_view.arrange_in_grid 9999 # make one giant column
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# menu
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
Mod1-Control-i: | # run internal action chosen from a menu
|
||||
${mod}-a: | # run internal action chosen from a menu
|
||||
if choice = key_menu(actions, 'run action:')
|
||||
action choice
|
||||
end
|
||||
|
||||
Mod1-Control-e: | # run external program chosen from a menu
|
||||
${mod}-p: | # run external program chosen from a menu
|
||||
if choice = key_menu(@programs, 'run program:')
|
||||
launch choice
|
||||
end
|
||||
|
||||
Mod1-Control-u: | # focus view chosen from a menu
|
||||
${mod}-t: | # focus view chosen from a menu
|
||||
if choice = key_menu(tags, 'show view:')
|
||||
focus_view choice
|
||||
end
|
||||
|
||||
Mod1-Control-a: | # focus client chosen from a menu
|
||||
choices = []
|
||||
|
||||
clients.each_with_index do |c, i|
|
||||
choices << "%d. [%s] %s" % [i, c[:tags].read, c[:label].read.downcase]
|
||||
end
|
||||
|
||||
if target = key_menu(choices, 'show client:')
|
||||
i = target.scan(/\d+/).first.to_i
|
||||
clients[i].focus
|
||||
end
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# launcher
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
Mod1-Control-x: | # launch a terminal
|
||||
${mod}-Return: | # launch a terminal
|
||||
#
|
||||
# Launch a new terminal and set its
|
||||
# working directory to be the same
|
||||
|
@ -562,77 +313,9 @@ control:
|
|||
|
||||
require 'fileutils'
|
||||
FileUtils.cd work do
|
||||
launch 'urxvt'
|
||||
launch CONFIG['program']['terminal']
|
||||
end
|
||||
|
||||
Mod1-Control-k: | # launch a web browser
|
||||
launch 'firefox'
|
||||
|
||||
Mod1-Control-j: | # launch a file manager
|
||||
launch 'thunar'
|
||||
|
||||
Mod1-Control-q: | # launch a note taker
|
||||
launch 'mousepad'
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# music
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
Mod1-Control-Prior: | # previous song
|
||||
@music.previous rescue nil
|
||||
status 'music'
|
||||
|
||||
Mod1-Control-Next: | # next song
|
||||
@music.next rescue nil
|
||||
status 'music'
|
||||
|
||||
Mod1-Control-Return: | # pause song (toggle)
|
||||
begin
|
||||
if @music.stopped?
|
||||
@music.play
|
||||
else
|
||||
@music.pause = !@music.paused?
|
||||
end
|
||||
rescue
|
||||
# ignore
|
||||
end
|
||||
|
||||
status 'music'
|
||||
|
||||
Mod1-Control-Home: | # load a playlist
|
||||
if list = key_menu(@music.playlists, 'load playlist:')
|
||||
@music.clear
|
||||
@music.load list
|
||||
@music.play
|
||||
end
|
||||
|
||||
Mod1-Control-End: | # add current song to a playlist
|
||||
if list = key_menu(@music.playlists, 'add current song to playlist:')
|
||||
file = File.join(File.expand_path('~/.mpd/playlists'), list + '.m3u')
|
||||
|
||||
songs = File.readlines(file) rescue []
|
||||
songs << @music.current_song.file
|
||||
songs.uniq!
|
||||
|
||||
File.open(file, 'w') {|f| f.puts songs }
|
||||
end
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# volume
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
Mod1-Control-Shift-Prior: | # increase volume
|
||||
system 'amixer set Master 3dB+'
|
||||
status 'volume'
|
||||
|
||||
Mod1-Control-Shift-Next: | # decrease volume
|
||||
system 'amixer set Master 3dB-'
|
||||
status 'volume'
|
||||
|
||||
Mod1-Control-Shift-Return: | # mute volume (toggle)
|
||||
system 'amixer set Master toggle'
|
||||
status 'volume'
|
||||
|
||||
##
|
||||
# Event handlers.
|
||||
#
|
||||
|
@ -691,47 +374,6 @@ control:
|
|||
RightBarClick: |
|
||||
status_click *argv.reverse
|
||||
|
||||
Unresponsive: |
|
||||
client_id = argv[0]
|
||||
client = Client.new(client_id)
|
||||
|
||||
IO.popen('xmessage -nearmouse -file - -buttons Kill,Wait -print', 'w+') do |f|
|
||||
f.puts 'The following client is not responding.', ''
|
||||
f.puts client.inspect
|
||||
f.puts client.label.read
|
||||
|
||||
f.puts '', 'What would you like to do?'
|
||||
f.close_write
|
||||
|
||||
if f.read.chomp == 'Kill'
|
||||
client.slay
|
||||
end
|
||||
end
|
||||
|
||||
Notice: |
|
||||
unless defined? @notice_mutex
|
||||
require 'thread'
|
||||
@notice_mutex = Mutex.new
|
||||
end
|
||||
|
||||
Thread.new do
|
||||
# prevent notices from overwriting each other
|
||||
@notice_mutex.synchronize do
|
||||
button = fs.rbar['!notice']
|
||||
button.create unless button.exist?
|
||||
|
||||
# display the notice
|
||||
message = argv.join(' ')
|
||||
|
||||
LOG.info message # also log it in case the user is AFK
|
||||
button.write "#{CONFIG['display']['color']['notice']} #{message}"
|
||||
|
||||
# clear the notice
|
||||
sleep [1, CONFIG['display']['notice'].to_i].max
|
||||
button.remove
|
||||
end
|
||||
end
|
||||
|
||||
ClientMouseDown: |
|
||||
client_id, mouse_button = argv
|
||||
|
||||
|
@ -753,35 +395,6 @@ control:
|
|||
# <action name>: <Ruby code to execute>
|
||||
#
|
||||
action:
|
||||
reload: | # reload this wmii configuration
|
||||
reload_config
|
||||
|
||||
rehash: | # scan for available programs and actions
|
||||
@programs = find_programs(ENV['PATH'].squeeze(':').split(':'))
|
||||
|
||||
clear: | # kill all clients
|
||||
# firefox's restore session feature does not
|
||||
# work unless the whole process is killed.
|
||||
system 'killall firefox firefox-bin thunderbird thunderbird-bin'
|
||||
|
||||
# gnome-panel refuses to die by any other means
|
||||
system 'killall -s TERM gnome-panel'
|
||||
|
||||
Thread.pass until clients.each do |c|
|
||||
begin
|
||||
c.focus # XXX: client must be on current view in order to be killed
|
||||
c.kill
|
||||
rescue
|
||||
# ignore
|
||||
end
|
||||
end.empty?
|
||||
|
||||
kill: | # kill the window manager only; do not touch the clients!
|
||||
fs.ctl.write 'quit'
|
||||
|
||||
quit: | # kill both clients and window manager
|
||||
action 'clear'
|
||||
action 'kill'
|
||||
|
||||
|
||||
##
|
||||
|
@ -792,13 +405,5 @@ control:
|
|||
# after: <Ruby code to execute after processing this file>
|
||||
#
|
||||
script:
|
||||
before: |
|
||||
DETACHED_TAG = '|'
|
||||
ZOOMED_SUFFIX = /~(\d+)$/
|
||||
|
||||
after: |
|
||||
action 'rehash'
|
||||
|
||||
# desktop wallpaper
|
||||
system 'sh ~/.fehbg'
|
||||
|
||||
before:
|
||||
after:
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#!/usr/bin/env ruby
|
||||
#
|
||||
# Bootloader for wmii configuration.
|
||||
#
|
||||
#--
|
||||
# Copyright protects this work.
|
||||
# See LICENSE file for details.
|
||||
|
@ -25,11 +27,14 @@ begin
|
|||
LOG.info 'birth'
|
||||
|
||||
# load configuration library
|
||||
config_home = File.dirname(__FILE__)
|
||||
config_libs = File.join(config_home, 'config.rb')
|
||||
config_file = File.join(config_home, 'config.yaml')
|
||||
def find_config file
|
||||
base_dirs = ENV['WMII_CONFPATH'].to_s.split(/:+/)
|
||||
ruby_dirs = base_dirs.map {|dir| File.join(dir, 'ruby') }
|
||||
|
||||
require config_libs
|
||||
Dir["{#{base_dirs.zip(ruby_dirs).join(',')}}/#{file}"].first
|
||||
end
|
||||
|
||||
require find_config('config.rb')
|
||||
|
||||
# terminate any existing wmiirc
|
||||
fs.event.write 'Start wmiirc'
|
||||
|
@ -39,7 +44,7 @@ begin
|
|||
end
|
||||
|
||||
# apply user configuration
|
||||
load_config config_file
|
||||
load_config find_config('config.yaml')
|
||||
|
||||
# setup tag bar (buttons that correspond to views)
|
||||
fs.lbar.clear
|
||||
|
|
Loading…
Reference in New Issue