Ion3: Unterschied zwischen den Versionen
(Update: InfoBox) |
(→Debian: Update Version.) |
||
(14 dazwischenliegende Versionen von 3 Benutzern werden nicht angezeigt) | |||
Zeile 4: | Zeile 4: | ||
|Beschreibung= Ion3 Screenshot | |Beschreibung= Ion3 Screenshot | ||
|Hersteller= Tuomo Valkonen | |Hersteller= Tuomo Valkonen | ||
− | |AktuelleVersion= ion-3- | + | |AktuelleVersion= ion-3-20090110 |
− | |AktuelleVersionFreigabeDatum= | + | |AktuelleVersionFreigabeDatum= 10. Januar 2009 |
|Betriebssystem= Linux, BSD, Unix | |Betriebssystem= Linux, BSD, Unix | ||
|Kategorie= [[Windowmanager]] | |Kategorie= [[Windowmanager]] | ||
Zeile 14: | Zeile 14: | ||
{{Box Test|| | {{Box Test|| | ||
+ | * [[Debian]] 3.1 | ||
* [[Debian]] 4.0 | * [[Debian]] 4.0 | ||
+ | * [[Debian]] 5.0 | ||
}} | }} | ||
Zeile 44: | Zeile 46: | ||
= Alternativen = | = Alternativen = | ||
− | Als Alternative zu Ion gibt es | + | Als Alternative zu Ion gibt es folgende andere Fenstermanager: |
* LarsWM | * LarsWM | ||
Zeile 58: | Zeile 60: | ||
= Funktionstasten = | = Funktionstasten = | ||
− | In der Regel sind die Funktionstasten bei Ion | + | In der Regel sind die Funktionstasten bei Ion folgendermaßen bestückt: |
* F1 - Die Manpages anzeigen | * F1 - Die Manpages anzeigen | ||
Zeile 81: | Zeile 83: | ||
Wie immer gestaltet sich die Installation unter Debian recht einfach mit Hilfe von APT.<br> | Wie immer gestaltet sich die Installation unter Debian recht einfach mit Hilfe von APT.<br> | ||
* Die Ion3 Version liegt derzeit bei GNU/Debian im ''SID Non-Free'' Bereich. | * Die Ion3 Version liegt derzeit bei GNU/Debian im ''SID Non-Free'' Bereich. | ||
+ | |||
+ | * Ausgenommen Debian Sarge: | ||
+ | ** ion3 (20090110-1) | ||
<pre> | <pre> | ||
Zeile 86: | Zeile 91: | ||
apt-get install ion3 | apt-get install ion3 | ||
</pre> | </pre> | ||
+ | |||
+ | <br> | ||
+ | |||
+ | = Konfigurationsdateien = | ||
+ | |||
+ | ämtliche Konfigurationsdateien welche Systemweit für alle Benutzer gelten sind in der Regel unter /etc/X11/ion3 zu finden. Wer seinen Ion nicht Systemweit für alle gleich sondern für jeden Benutzer anderst konfigurieren möchte kann hierzu die entsprechenden Konfigurationsdateien im /home/ ~ /.ion3 Verzeichniss anlegen. | ||
+ | |||
+ | Die wohl wichtigsten Konfigurationsdateien sind: | ||
+ | |||
+ | * cfg_ioncore.lua | ||
+ | * cfg_statusbar.lua | ||
+ | * cfg_menu.lua | ||
+ | |||
+ | In der ersten Konfigurationsdateien koennen Tastenkombinationen entsprechend konfigurirt werden wie auch die F-Tasten Belegung. In der Zweiten werden Einstellungen zur Statusbar vorgenommen. Diverse Lua-Scripts fuer die Statusbar koennen hier eingebunden werden. In der letzten kann das Menue konfiguriert werden. | ||
+ | |||
+ | = F-Tasten = | ||
+ | |||
+ | Die Funktion der F-Tasten ist eigentlich gar nicht mal so schlecht, doch leider bei manchen Anwendungen welche selbst die F-Tasten benötigen extrem störend. zum Beispiel wird beim Arbeiten im MC das Betätigen der F-Tasten die Funktion vom Ion und nicht vom MC selbst ausführen. Drücke ich z.B. F-5 so wird die Option von Ion für das Editieren geöffnet anstelle die Option im MC für das Kopieren einer Datei. Wie können wir das Problem am einfachsten lösen. Ganz einfach, wir entfernen die Funktionen aus der entsprechenden Konfigurationsdatet so, das die F--Tasten von F1--10 keine Funktion mehr in Ion beim drücken haben. | ||
+ | |||
+ | = Tastenkombinationen = | ||
+ | |||
+ | Das aufrufen des Menüs lassen wir weiterhin auf der F12 Taste liegen. In dem von mir hier gezeigten Beispiel ist es als Terminal ''RoxTerm'' und ''Rxvt'' auf die Tastenkombination ALT+T und ALT+R gelegt. Mit der Kombination ALT+E wird Esetroot gestartet um ein Wallpaper bei transparentem Terminal anzeigen zu lassen (Der Pfad zum Wallpaper muss entsprechend angepasst werden). Bai ALT+W wird eine neue Arbeitsflaeche erstellt durch welche mit ALT+1 bis ALT+9 durchgewechselt werden kann. | ||
+ | |||
+ | == cfg_ioncore.lua == | ||
+ | |||
+ | <pre> | ||
+ | -- | ||
+ | -- Ion core configuration file | ||
+ | -- | ||
+ | |||
+ | |||
+ | -- | ||
+ | -- Bindings. This includes global bindings and bindings common to | ||
+ | -- screens and all types of frames only. See modules' configuration | ||
+ | -- files for other bindings. | ||
+ | -- | ||
+ | |||
+ | |||
+ | -- WScreen context bindings | ||
+ | -- | ||
+ | -- The bindings in this context are available all the time. | ||
+ | -- | ||
+ | -- The variable META should contain a string of the form 'Mod1+' | ||
+ | -- where Mod1 maybe replaced with the modifier you want to use for most | ||
+ | -- of the bindings. Similarly ALTMETA may be redefined to add a | ||
+ | -- modifier to some of the F-key bindings. | ||
+ | |||
+ | defbindings("WScreen", { | ||
+ | bdoc("Switch to n:th object (workspace, full screen client window) ".. | ||
+ | "within current screen."), | ||
+ | kpress(META.."1", "WScreen.switch_nth(_, 0)"), | ||
+ | kpress(META.."2", "WScreen.switch_nth(_, 1)"), | ||
+ | kpress(META.."3", "WScreen.switch_nth(_, 2)"), | ||
+ | kpress(META.."4", "WScreen.switch_nth(_, 3)"), | ||
+ | kpress(META.."5", "WScreen.switch_nth(_, 4)"), | ||
+ | kpress(META.."6", "WScreen.switch_nth(_, 5)"), | ||
+ | kpress(META.."7", "WScreen.switch_nth(_, 6)"), | ||
+ | kpress(META.."8", "WScreen.switch_nth(_, 7)"), | ||
+ | kpress(META.."9", "WScreen.switch_nth(_, 8)"), | ||
+ | kpress(META.."0", "WScreen.switch_nth(_, 9)"), | ||
+ | |||
+ | bdoc("Switch to next/previous object within current screen."), | ||
+ | kpress(META.."comma", "WScreen.switch_prev(_)"), | ||
+ | kpress(META.."period", "WScreen.switch_next(_)"), | ||
+ | |||
+ | submap(META.."K", { | ||
+ | bdoc("Go to first region demanding attention or previously active one."), | ||
+ | kpress("K", "mod_menu.grabmenu(_, _sub, 'focuslist')"), | ||
+ | -- Alternative without (cyclable) menu | ||
+ | --kpress("K", "ioncore.goto_activity() or ioncore.goto_previous()"), | ||
+ | |||
+ | --bdoc("Go to previous active object."), | ||
+ | --kpress("K", "ioncore.goto_previous()"), | ||
+ | |||
+ | --bdoc("Go to first object on activity/urgency list."), | ||
+ | --kpress("I", "ioncore.goto_activity()"), | ||
+ | |||
+ | bdoc("Clear all tags."), | ||
+ | kpress("T", "ioncore.tagged_clear()"), | ||
+ | }), | ||
+ | |||
+ | bdoc("Go to n:th screen on multihead setup."), | ||
+ | kpress(META.."Shift+1", "ioncore.goto_nth_screen(0)"), | ||
+ | kpress(META.."Shift+2", "ioncore.goto_nth_screen(1)"), | ||
+ | |||
+ | bdoc("Go to next/previous screen on multihead setup."), | ||
+ | kpress(META.."Shift+comma", "ioncore.goto_prev_screen()"), | ||
+ | kpress(META.."Shift+period", "ioncore.goto_next_screen()"), | ||
+ | |||
+ | bdoc("Create a new workspace of chosen default type."), | ||
+ | kpress(META.."W", "ioncore.create_ws(_)"), | ||
+ | |||
+ | |||
+ | |||
+ | bdoc("Display the main menu."), | ||
+ | kpress(ALTMETA.."F12", "mod_query.query_menu(_, _sub, 'mainmenu', 'Main menu:')"), | ||
+ | --kpress(ALTMETA.."F12", "mod_menu.menu(_, _sub, 'mainmenu', {big=true})"), | ||
+ | mpress("Button3", "mod_menu.pmenu(_, _sub, 'mainmenu')"), | ||
+ | |||
+ | bdoc("Display the window list menu."), | ||
+ | mpress("Button2", "mod_menu.pmenu(_, _sub, 'windowlist')"), | ||
+ | |||
+ | bdoc("Forward-circulate focus."), | ||
+ | -- '_chld' used here stands to for an actual child window that may not | ||
+ | -- be managed by the screen itself, unlike '_sub', that is likely to be | ||
+ | -- the managing group of that window. The right/left directions are | ||
+ | -- used instead of next/prev, because they work better in conjunction | ||
+ | -- with tilings. | ||
+ | kpress(META.."Tab", "ioncore.goto_next(_chld, 'right')", | ||
+ | "_chld:non-nil"), | ||
+ | submap(META.."K", { | ||
+ | bdoc("Backward-circulate focus."), | ||
+ | kpress("AnyModifier+Tab", "ioncore.goto_next(_chld, 'left')", | ||
+ | "_chld:non-nil"), | ||
+ | |||
+ | bdoc("Raise focused object, if possible."), | ||
+ | kpress("AnyModifier+R", "WRegion.rqorder(_chld, 'front')", | ||
+ | "_chld:non-nil"), | ||
+ | }), | ||
+ | |||
+ | }) | ||
+ | |||
+ | |||
+ | -- Client window bindings | ||
+ | -- | ||
+ | -- These bindings affect client windows directly. | ||
+ | |||
+ | defbindings("WClientWin", { | ||
+ | bdoc("Nudge the client window. This might help with some ".. | ||
+ | "programs' resizing problems."), | ||
+ | kpress_wait(META.."L", "WClientWin.nudge(_)"), | ||
+ | |||
+ | submap(META.."K", { | ||
+ | bdoc("Kill client owning the client window."), | ||
+ | kpress("C", "WClientWin.kill(_)"), | ||
+ | |||
+ | bdoc("Send next key press to the client window. ".. | ||
+ | "Some programs may not allow this by default."), | ||
+ | kpress("Q", "WClientWin.quote_next(_)"), | ||
+ | }), | ||
+ | }) | ||
+ | |||
+ | |||
+ | -- Client window group bindings | ||
+ | |||
+ | defbindings("WGroupCW", { | ||
+ | bdoc("Toggle client window group full-screen mode"), | ||
+ | kpress_wait(META.."Return", "WGroup.set_fullscreen(_, 'toggle')"), | ||
+ | }) | ||
+ | |||
+ | |||
+ | -- WMPlex context bindings | ||
+ | -- | ||
+ | -- These bindings work in frames and on screens. The innermost of such | ||
+ | -- contexts/objects always gets to handle the key press. | ||
+ | |||
+ | defbindings("WMPlex", { | ||
+ | bdoc("Close current object."), | ||
+ | kpress_wait(META.."C", "WRegion.rqclose_propagate(_, _sub)"), | ||
+ | |||
+ | submap(META.."K", { | ||
+ | bdoc("Detach (float) or reattach an object to its previous location."), | ||
+ | -- By using _chld instead of _sub, we can detach/reattach queries | ||
+ | -- attached to a group. The detach code checks if the parameter | ||
+ | -- (_chld) is a group 'bottom' and detaches the whole group in that | ||
+ | -- case. | ||
+ | kpress("D", "ioncore.detach(_chld, 'toggle')", "_chld:non-nil"), | ||
+ | }), | ||
+ | }) | ||
+ | |||
+ | -- Frames for transient windows ignore this bindmap | ||
+ | |||
+ | defbindings("WMPlex.toplevel", { | ||
+ | bdoc("Toggle tag of current object."), | ||
+ | kpress(META.."T", "WRegion.set_tagged(_sub, 'toggle')", "_sub:non-nil"), | ||
+ | |||
+ | -- bdoc("Query for manual page to be displayed."), | ||
+ | -- kpress(ALTMETA.."F1", "mod_query.query_man(_, ':man')"), | ||
+ | |||
+ | -- bdoc("Show the Ion manual page."), | ||
+ | -- kpress(META.."F1", "ioncore.exec_on(_, ':man ion3')"), | ||
+ | |||
+ | bdoc("Run a terminal emulator."), | ||
+ | kpress(META.."T", "ioncore.exec_on(_, XTERM or 'x-terminal-emulator')"), | ||
+ | |||
+ | |||
+ | bdoc("Run a terminal emulator."), | ||
+ | kpress(META.."E", "ioncore.exec_on(_, XTERM or 'Esetroot /home/tobi/Bilder/Wallpaper/Modells/Models003.png')"), | ||
+ | |||
+ | |||
+ | bdoc("Run a terminal emulator."), | ||
+ | kpress(META.."R", "ioncore.exec_on(_, XTERM or 'rxvt -bg black -fg white -cr red -fb Monospace-9 +sb')"), | ||
+ | |||
+ | |||
+ | bdoc("Query for command line to execute."), | ||
+ | kpress(META.."P", "mod_query.query_exec(_)"), | ||
+ | |||
+ | -- bdoc("Query for Lua code to execute."), | ||
+ | -- kpress(META.."F3", "mod_query.query_lua(_)"), | ||
+ | |||
+ | -- bdoc("Query for host to connect to with SSH."), | ||
+ | -- kpress(ALTMETA.."F4", "mod_query.query_ssh(_, ':ssh')"), | ||
+ | |||
+ | -- bdoc("Query for file to edit."), | ||
+ | -- kpress(ALTMETA.."F5", | ||
+ | -- "mod_query.query_editfile(_, 'run-mailcap --action=edit')"), | ||
+ | |||
+ | -- bdoc("Query for file to view."), | ||
+ | -- kpress(ALTMETA.."F6", | ||
+ | -- "mod_query.query_runfile(_, 'run-mailcap --action=view')"), | ||
+ | |||
+ | -- bdoc("Query for workspace to go to or create a new one."), | ||
+ | -- kpress(ALTMETA.."F9", "mod_query.query_workspace(_)"), | ||
+ | |||
+ | bdoc("Query for a client window to go to."), | ||
+ | kpress(META.."G", "mod_query.query_gotoclient(_)"), | ||
+ | |||
+ | bdoc("Display context menu."), | ||
+ | --kpress(META.."M", "mod_menu.menu(_, _sub, 'ctxmenu')"), | ||
+ | kpress(META.."M", "mod_query.query_menu(_, _sub, 'ctxmenu', 'Context menu:')"), | ||
+ | }) | ||
+ | |||
+ | |||
+ | -- WFrame context bindings | ||
+ | -- | ||
+ | -- These bindings are common to all types of frames. Some additional | ||
+ | -- frame bindings are found in some modules' configuration files. | ||
+ | |||
+ | defbindings("WFrame", { | ||
+ | submap(META.."K", { | ||
+ | bdoc("Maximize the frame horizontally/vertically."), | ||
+ | kpress("H", "WFrame.maximize_horiz(_)"), | ||
+ | kpress("V", "WFrame.maximize_vert(_)"), | ||
+ | }), | ||
+ | |||
+ | bdoc("Display context menu."), | ||
+ | mpress("Button3", "mod_menu.pmenu(_, _sub, 'ctxmenu')"), | ||
+ | |||
+ | bdoc("Begin move/resize mode."), | ||
+ | kpress(META.."R", "WFrame.begin_kbresize(_)"), | ||
+ | |||
+ | bdoc("Switch the frame to display the object indicated by the tab."), | ||
+ | mclick("Button1@tab", "WFrame.p_switch_tab(_)"), | ||
+ | mclick("Button2@tab", "WFrame.p_switch_tab(_)"), | ||
+ | |||
+ | bdoc("Resize the frame."), | ||
+ | mdrag("Button1@border", "WFrame.p_resize(_)"), | ||
+ | mdrag(META.."Button3", "WFrame.p_resize(_)"), | ||
+ | |||
+ | bdoc("Move the frame."), | ||
+ | mdrag(META.."Button1", "WFrame.p_move(_)"), | ||
+ | |||
+ | bdoc("Move objects between frames by dragging and dropping the tab."), | ||
+ | mdrag("Button1@tab", "WFrame.p_tabdrag(_)"), | ||
+ | mdrag("Button2@tab", "WFrame.p_tabdrag(_)"), | ||
+ | |||
+ | }) | ||
+ | |||
+ | -- Frames for transient windows ignore this bindmap | ||
+ | |||
+ | defbindings("WFrame.toplevel", { | ||
+ | bdoc("Query for a client window to attach."), | ||
+ | kpress(META.."A", "mod_query.query_attachclient(_)"), | ||
+ | |||
+ | submap(META.."K", { | ||
+ | -- Display tab numbers when modifiers are released | ||
+ | submap_wait("ioncore.tabnum.show(_)"), | ||
+ | |||
+ | bdoc("Switch to n:th object within the frame."), | ||
+ | kpress("1", "WFrame.switch_nth(_, 0)"), | ||
+ | kpress("2", "WFrame.switch_nth(_, 1)"), | ||
+ | kpress("3", "WFrame.switch_nth(_, 2)"), | ||
+ | kpress("4", "WFrame.switch_nth(_, 3)"), | ||
+ | kpress("5", "WFrame.switch_nth(_, 4)"), | ||
+ | kpress("6", "WFrame.switch_nth(_, 5)"), | ||
+ | kpress("7", "WFrame.switch_nth(_, 6)"), | ||
+ | kpress("8", "WFrame.switch_nth(_, 7)"), | ||
+ | kpress("9", "WFrame.switch_nth(_, 8)"), | ||
+ | kpress("0", "WFrame.switch_nth(_, 9)"), | ||
+ | |||
+ | bdoc("Switch to next/previous object within the frame."), | ||
+ | kpress("N", "WFrame.switch_next(_)"), | ||
+ | kpress("P", "WFrame.switch_prev(_)"), | ||
+ | |||
+ | bdoc("Move current object within the frame left/right."), | ||
+ | kpress("comma", "WFrame.dec_index(_, _sub)", "_sub:non-nil"), | ||
+ | kpress("period", "WFrame.inc_index(_, _sub)", "_sub:non-nil"), | ||
+ | |||
+ | bdoc("Maximize the frame horizontally/vertically."), | ||
+ | kpress("H", "WFrame.maximize_horiz(_)"), | ||
+ | kpress("V", "WFrame.maximize_vert(_)"), | ||
+ | |||
+ | bdoc("Attach tagged objects to this frame."), | ||
+ | kpress("A", "ioncore.tagged_attach(_)"), | ||
+ | }), | ||
+ | }) | ||
+ | |||
+ | -- Bindings for floating frames. | ||
+ | |||
+ | defbindings("WFrame.floating", { | ||
+ | bdoc("Toggle shade mode"), | ||
+ | mdblclick("Button1@tab", "WFrame.set_shaded(_, 'toggle')"), | ||
+ | |||
+ | bdoc("Raise the frame."), | ||
+ | mpress("Button1@tab", "WRegion.rqorder(_, 'front')"), | ||
+ | mpress("Button1@border", "WRegion.rqorder(_, 'front')"), | ||
+ | mclick(META.."Button1", "WRegion.rqorder(_, 'front')"), | ||
+ | |||
+ | bdoc("Lower the frame."), | ||
+ | mclick(META.."Button3", "WRegion.rqorder(_, 'back')"), | ||
+ | |||
+ | bdoc("Move the frame."), | ||
+ | mdrag("Button1@tab", "WFrame.p_move(_)"), | ||
+ | }) | ||
+ | |||
+ | |||
+ | -- WMoveresMode context bindings | ||
+ | -- | ||
+ | -- These bindings are available keyboard move/resize mode. The mode | ||
+ | -- is activated on frames with the command begin_kbresize (bound to | ||
+ | -- META.."R" above by default). | ||
+ | |||
+ | defbindings("WMoveresMode", { | ||
+ | bdoc("Cancel the resize mode."), | ||
+ | kpress("AnyModifier+Escape","WMoveresMode.cancel(_)"), | ||
+ | |||
+ | bdoc("End the resize mode."), | ||
+ | kpress("AnyModifier+Return","WMoveresMode.finish(_)"), | ||
+ | |||
+ | bdoc("Grow in specified direction."), | ||
+ | kpress("Left", "WMoveresMode.resize(_, 1, 0, 0, 0)"), | ||
+ | kpress("Right", "WMoveresMode.resize(_, 0, 1, 0, 0)"), | ||
+ | kpress("Up", "WMoveresMode.resize(_, 0, 0, 1, 0)"), | ||
+ | kpress("Down", "WMoveresMode.resize(_, 0, 0, 0, 1)"), | ||
+ | kpress("F", "WMoveresMode.resize(_, 1, 0, 0, 0)"), | ||
+ | kpress("B", "WMoveresMode.resize(_, 0, 1, 0, 0)"), | ||
+ | kpress("P", "WMoveresMode.resize(_, 0, 0, 1, 0)"), | ||
+ | kpress("N", "WMoveresMode.resize(_, 0, 0, 0, 1)"), | ||
+ | |||
+ | bdoc("Shrink in specified direction."), | ||
+ | kpress("Shift+Left", "WMoveresMode.resize(_,-1, 0, 0, 0)"), | ||
+ | kpress("Shift+Right", "WMoveresMode.resize(_, 0,-1, 0, 0)"), | ||
+ | kpress("Shift+Up", "WMoveresMode.resize(_, 0, 0,-1, 0)"), | ||
+ | kpress("Shift+Down", "WMoveresMode.resize(_, 0, 0, 0,-1)"), | ||
+ | kpress("Shift+F", "WMoveresMode.resize(_,-1, 0, 0, 0)"), | ||
+ | kpress("Shift+B", "WMoveresMode.resize(_, 0,-1, 0, 0)"), | ||
+ | kpress("Shift+P", "WMoveresMode.resize(_, 0, 0,-1, 0)"), | ||
+ | kpress("Shift+N", "WMoveresMode.resize(_, 0, 0, 0,-1)"), | ||
+ | |||
+ | bdoc("Move in specified direction."), | ||
+ | kpress(META.."Left", "WMoveresMode.move(_,-1, 0)"), | ||
+ | kpress(META.."Right", "WMoveresMode.move(_, 1, 0)"), | ||
+ | kpress(META.."Up", "WMoveresMode.move(_, 0,-1)"), | ||
+ | kpress(META.."Down", "WMoveresMode.move(_, 0, 1)"), | ||
+ | kpress(META.."F", "WMoveresMode.move(_,-1, 0)"), | ||
+ | kpress(META.."B", "WMoveresMode.move(_, 1, 0)"), | ||
+ | kpress(META.."P", "WMoveresMode.move(_, 0,-1)"), | ||
+ | kpress(META.."N", "WMoveresMode.move(_, 0, 1)"), | ||
+ | }) | ||
+ | |||
+ | |||
+ | -- | ||
+ | -- Menu definitions | ||
+ | -- | ||
+ | |||
+ | |||
+ | -- Main menu | ||
+ | defmenu("mainmenu", { | ||
+ | menuentry("Run...", "mod_query.query_exec(_)"), | ||
+ | menuentry("Terminal", "ioncore.exec_on(_, XTERM or 'x-terminal-emulator')"), | ||
+ | menuentry("Lock screen", | ||
+ | "ioncore.exec_on(_, ioncore.lookup_script('ion-lock'))"), | ||
+ | menuentry("Help", "mod_query.query_man(_)"), | ||
+ | menuentry("About Ion", "mod_query.show_about_ion(_)"), | ||
+ | submenu("Styles", "stylemenu"), | ||
+ | submenu("Debian", "Debian"), | ||
+ | submenu("Session", "sessionmenu"), | ||
+ | }) | ||
+ | |||
+ | |||
+ | -- Session control menu | ||
+ | defmenu("sessionmenu", { | ||
+ | menuentry("Save", "ioncore.snapshot()"), | ||
+ | menuentry("Restart", "ioncore.restart()"), | ||
+ | menuentry("Restart TWM", "ioncore.restart_other('twm')"), | ||
+ | menuentry("Exit", "ioncore.shutdown()"), | ||
+ | }) | ||
+ | |||
+ | |||
+ | -- Context menu (frame actions etc.) | ||
+ | defctxmenu("WFrame", "Frame", { | ||
+ | -- Note: this propagates the close to any subwindows; it does not | ||
+ | -- destroy the frame itself, unless empty. An entry to destroy tiled | ||
+ | -- frames is configured in cfg_tiling.lua. | ||
+ | menuentry("Close", "WRegion.rqclose_propagate(_, _sub)"), | ||
+ | -- Low-priority entries | ||
+ | menuentry("Attach tagged", "ioncore.tagged_attach(_)", { priority = 0 }), | ||
+ | menuentry("Clear tags", "ioncore.tagged_clear()", { priority = 0 }), | ||
+ | menuentry("Window info", "mod_query.show_tree(_, _sub)", { priority = 0 }), | ||
+ | }) | ||
+ | |||
+ | |||
+ | -- Context menu for groups (workspaces, client windows) | ||
+ | defctxmenu("WGroup", "Group", { | ||
+ | menuentry("Toggle tag", "WRegion.set_tagged(_, 'toggle')"), | ||
+ | menuentry("De/reattach", "ioncore.detach(_, 'toggle')"), | ||
+ | }) | ||
+ | |||
+ | |||
+ | -- Context menu for workspaces | ||
+ | defctxmenu("WGroupWS", "Workspace", { | ||
+ | menuentry("Close", "WRegion.rqclose(_)"), | ||
+ | menuentry("Rename", "mod_query.query_renameworkspace(nil, _)"), | ||
+ | menuentry("Attach tagged", "ioncore.tagged_attach(_)"), | ||
+ | }) | ||
+ | |||
+ | |||
+ | -- Context menu for client windows | ||
+ | defctxmenu("WClientWin", "Client window", { | ||
+ | menuentry("Kill", "WClientWin.kill(_)"), | ||
+ | }) | ||
+ | |||
+ | -- Auto-generated Debian menu definitions | ||
+ | if os and os.execute("test -x /usr/bin/update-menus") == 0 then | ||
+ | if ioncore.is_i18n() then | ||
+ | dopath("debian-menu-i18n") | ||
+ | else | ||
+ | dopath("debian-menu") | ||
+ | end | ||
+ | |||
+ | </pre> | ||
+ | |||
+ | <br> | ||
+ | |||
+ | == cfg_statusbar.lua == | ||
+ | |||
+ | Um die Statuszeile in Ion anzupassen muess die cfg_statusbar.lua angepasst werden. | ||
+ | |||
+ | <pre> | ||
+ | -- | ||
+ | -- Ion statusbar module configuration file | ||
+ | -- | ||
+ | |||
+ | |||
+ | -- Create a statusbar | ||
+ | mod_statusbar.create{ | ||
+ | -- First screen, bottom left corner | ||
+ | screen=0, | ||
+ | pos='bl', | ||
+ | -- Set this to true if you want a full-width statusbar | ||
+ | fullsize=false, | ||
+ | -- Swallow systray windows | ||
+ | systray=true, | ||
+ | |||
+ | -- Template. Tokens %string are replaced with the value of the | ||
+ | -- corresponding meter. Currently supported meters are: | ||
+ | -- date date | ||
+ | -- load load average (1min, 5min, 15min) | ||
+ | -- load_Nmin N minute load average (N=1, 5, 15) | ||
+ | -- mail_new mail count (mbox format file $MAIL) | ||
+ | -- mail_unread mail count | ||
+ | -- mail_total mail count | ||
+ | -- mail_*_new mail count (from an alternate mail folder, see below) | ||
+ | -- mail_*_unread mail count | ||
+ | -- mail_*_total mail count | ||
+ | -- | ||
+ | -- Space preceded by % adds stretchable space for alignment of variable | ||
+ | -- meter value widths. > before meter name aligns right using this | ||
+ | -- stretchable space , < left, and | centers. | ||
+ | -- Meter values may be zero-padded to a width preceding the meter name. | ||
+ | -- These alignment and padding specifiers and the meter name may be | ||
+ | -- enclosed in braces {}. | ||
+ | -- | ||
+ | -- %filler causes things on the marker's sides to be aligned left and | ||
+ | -- right, respectively, and %systray is a placeholder for system tray | ||
+ | -- windows and icons. | ||
+ | -- | ||
+ | |||
+ | |||
+ | -- Zusatzliche Lua Skripte werden in die Statusbar mit eingebunden. | ||
+ | -- template="[ %date || load:% %>load || MEM Used: %mem_hused MB - Free: %mem_hfree MB || CPU: %cpustat_user || KB/s In: %netmon_kbsin Out: %netmon_kbsout ]", | ||
+ | |||
+ | -- Default Statusbar | ||
+ | -- template="[ %date || load: %05load_1min || mail: %02mail_new/%02mail_total ] %filler%systray", | ||
+ | |||
+ | -- Derzeit aktiev | ||
+ | template="[ %date || load: %05load_1min", | ||
+ | |||
+ | } | ||
+ | |||
+ | |||
+ | -- Launch ion-statusd. This must be done after creating any statusbars | ||
+ | -- for necessary statusd modules to be parsed from the templates. | ||
+ | mod_statusbar.launch_statusd{ | ||
+ | |||
+ | -- Date meter | ||
+ | date={ | ||
+ | -- ISO-8601 date format with additional abbreviated day name | ||
+ | date_format='%a %Y-%m-%d %H:%M', | ||
+ | -- Finnish etc. date format | ||
+ | --date_format='%a %d.%m.%Y %H:%M', | ||
+ | -- Locale date format (usually shows seconds, which would require | ||
+ | -- updating rather often and can be distracting) | ||
+ | --date_format='%c', | ||
+ | |||
+ | -- Additional date formats. | ||
+ | --[[ | ||
+ | formats={ | ||
+ | time = '%H:%M', -- %date_time | ||
+ | } | ||
+ | --]] | ||
+ | }, | ||
+ | |||
+ | -- Load meter | ||
+ | load={ | ||
+ | --update_interval=10*1000, | ||
+ | --important_threshold=1.5, | ||
+ | --critical_threshold=4.0, | ||
+ | }, | ||
+ | |||
+ | -- Mail meter | ||
+ | -- | ||
+ | -- To monitor more mbox files, add them to the files table. For | ||
+ | -- example, add mail_work_new and mail_junk_new to the template | ||
+ | -- above, and define them in the files table: | ||
+ | -- | ||
+ | -- files = { work = "/path/to/work_email", junk = "/path/to/junk" } | ||
+ | -- | ||
+ | -- Don't use the keyword 'spool' as it's reserved for mbox. | ||
+ | mail={ | ||
+ | --update_interval=60*1000, | ||
+ | --mbox=os.getenv("MAIL"), | ||
+ | --files={}, | ||
+ | }, | ||
+ | |||
+ | |||
+ | </pre> | ||
+ | |||
+ | Die Zeile | ||
+ | |||
+ | <pre> | ||
+ | template="[ %date || load: %05load_1min ", | ||
+ | </pre> | ||
+ | |||
+ | ist die interessante. Hier kann entsprechend konfiguriert werden. In meinem Beispiel wird der Tag, Datum, Uhrzeit und Loadwert angezeigt. Ich habe die Defaulteinstellung ebenfalls in der Datei stehen lassen und zudem eine von mir verwendete Version mit eingetragen bei welcher ein paar Lua Skripte mit eingebunden werden um CPU Auslastung, RAM Speicherverbrauch und Netzwerkdurchlass anzuzeigen. | ||
+ | |||
+ | Damit zusaetzliche Lua Skripte unter Ion funktionieren muessen sie ins ''ion3'' Verzeichniss kopiert werden. In den Skripten selbst ist meistens genau beschrieben wie weiter vorgegangen werden muss. Meistens muessen Pfade angepasst werden oder ein paar kleine Einstellungen wie z.B. Netzwerkinterface usw. Bekommen tut man diese Skripte auf der Ion Webseite oder beim Distributor. Ich fuege ein paar Skripte hier ins Wiki mit ein, es sind diese welche auch in dem Konfigurationsbeispiel der cfg_statusbar.lua eingetragen sind. | ||
+ | |||
+ | [http://modeemi.fi/~tuomov/repos/ion-scripts-3/ Download Ion Scripts] | ||
+ | |||
+ | <br> | ||
+ | |||
+ | === statusd_mem.lua === | ||
+ | |||
+ | Fuer die Anzeige des freien RAM Speichers in der Statusbar. | ||
+ | |||
+ | Wird durch ''MEM Used: %mem_hused MB - Free: %mem_hfree MB'' eingebunden. | ||
+ | |||
+ | <pre> | ||
+ | ------------------------------------------------------------------------------------------- | ||
+ | -- | ||
+ | -- PURPOSE: | ||
+ | -- Shows system available memory catching [free] command outputs. | ||
+ | -- It is intended to make it simpler than statusd_meminfo, plus user configurable | ||
+ | -- measurement units and alarms for "all" available memory metters. | ||
+ | -- | ||
+ | -- USAGE: | ||
+ | -- Just set any of the following labels on cfg_statusbar.lua: %mem_hused, %mem_shared | ||
+ | -- %mem_free, %mem_hfree, %mem_swap, %mem_used, %mem_cached. Example: [MF: %mem_free] | ||
+ | -- | ||
+ | -- MEANINGS: | ||
+ | --> ** "mem_hfree" poses as "htop free memory" or "mem_free +cached +buffers", | ||
+ | -- in oposition, "mem_hused" is "mem_used -cached -buffers"; other labels have | ||
+ | -- transparent meanings. | ||
+ | -- | ||
+ | ------- CONFIG EXAMPLE: ------------------------------------------------------------------ | ||
+ | -- | ||
+ | -- To modify settings is quite simple and flexible, write (on cfg_statusbar.lua) | ||
+ | -- something like this, without comments: | ||
+ | -- mem = { | ||
+ | -- update_interval = 15*1000, --> Milliseconds | ||
+ | -- free_alarm = 25, --> Limits percentaje ... | ||
+ | -- used_alarm = 65, | ||
+ | -- units = "m" --> "g" or "k" too | ||
+ | -- } | ||
+ | -- Write only the settings that do you want to change or leave this section as is... | ||
+ | --> ** "update_interval" means "time in milliseconds to update info (default = 15)" | ||
+ | -- "xx_alarm" means "do a color advise when memory *percentage* reaches this value". | ||
+ | -- (both defaults are 50). "units" means Gb "g", Mb "m" or Kb "k" (default = "m") | ||
+ | ------------------------------------------------------------------------------------------ | ||
+ | -- | ||
+ | -- NOTES: | ||
+ | -- * Alarms for used memory are inverse to alarms for free memory (think about it...) | ||
+ | -- "mem_total" label is useless. If total memory varies, its time to open your | ||
+ | -- hardware and check this script from barebone. Seriously, may be your video or wifi | ||
+ | -- devices were claiming some free R.A.M. on your machine start-up. | ||
+ | -- However, I included "mem_total" just in case. | ||
+ | -- ** This script has non blocking I/O. | ||
+ | -- | ||
+ | -- LICENSE: | ||
+ | -- GPL2 Copyright(C)2006 Mario Garcia H. | ||
+ | -- (Please see http://www.gnu.org/licenses/gpl.html to read complete license) | ||
+ | -- | ||
+ | -- T.STAMP: Thu Dec 7 03:28:04 2006 | ||
+ | -- | ||
+ | -- DEPENDS: "free" command. Probably, all GNU/Linux distros have one. | ||
+ | -- | ||
+ | -- INSECTS: Not known. | ||
+ | -- | ||
+ | -- CONTACT: | ||
+ | -- G.H. <drosophila (at) nmental (dot) com> | ||
+ | -- | ||
+ | ------- DEFAULT SETTINGS :----------------------------------------------------------------- | ||
+ | |||
+ | local mem_timer | ||
+ | local defaults = { update_interval = 15*1000, free_alarm = 50, used_alarm = 50, units = "m" } | ||
+ | local settings = table.join(statusd.get_config("mem"), defaults) | ||
+ | |||
+ | ------- MEM MONITOR :---------------------------------------------------------------------- | ||
+ | |||
+ | local function show_meminfo(status) | ||
+ | while status do | ||
+ | local ok, _, total, used, free, shared, buffers, cached =-- | ||
+ | string.find(status, "Mem:%s+(%d+)%s+(%d+)%s+(%d+)%s+(%d+)%s+(%d+)%s+(%d+)") | ||
+ | -- | ||
+ | if not ok then statusd.inform("mem_template", "--") return end | ||
+ | -- | ||
+ | statusd.inform("mem_total", total) | ||
+ | statusd.inform("mem_used", used) | ||
+ | statusd.inform("mem_free", free) | ||
+ | statusd.inform("mem_shared", shared) | ||
+ | statusd.inform("mem_buffers", buffers) | ||
+ | statusd.inform("mem_cached", cached) | ||
+ | statusd.inform("mem_hused", tostring(used - cached - buffers)) | ||
+ | statusd.inform("mem_hfree", tostring(free + cached + buffers)) | ||
+ | -- | ||
+ | statusd.inform("mem_used_hint", | ||
+ | used*100/total >= settings.used_alarm and "critical" or "important") | ||
+ | statusd.inform("mem_hused_hint", | ||
+ | (used - cached - buffers)*100/total >= settings.used_alarm and "critical" or "important") | ||
+ | statusd.inform("mem_free_hint", | ||
+ | free*100/total <= settings.free_alarm and "critical" or "important") | ||
+ | statusd.inform("mem_hfree_hint", | ||
+ | (free + cached + buffers)*100/total <= settings.free_alarm and "critical" or "important") | ||
+ | -- | ||
+ | status = coroutine.yield() | ||
+ | end | ||
+ | end | ||
+ | |||
+ | local function update_mem() | ||
+ | statusd.popen_bgread("free -"..settings.units.."o", coroutine.wrap(show_meminfo)) | ||
+ | mem_timer:set(settings.update_interval, update_mem) | ||
+ | end | ||
+ | |||
+ | mem_timer = statusd.create_timer() | ||
+ | update_mem() | ||
+ | </pre> | ||
+ | |||
+ | <br> | ||
+ | |||
+ | === statusd_cpustat.lua === | ||
+ | |||
+ | Fuer die Anzeige der CPU Auslastung in der Statuszeile. | ||
+ | |||
+ | ''CPU: %cpustat_user'' | ||
+ | |||
+ | <pre> | ||
+ | -- $Id: statusd_cpustat.lua 80 2007-03-10 00:16:09Z tibi $ | ||
+ | |||
+ | -- statusd_cpustat.lua -- CPU monitor for Ion3's statusbar | ||
+ | |||
+ | -- version : 0.3 | ||
+ | -- date : 2007-03-10 | ||
+ | -- author : Tibor Csögör <tibi@tiborius.net> | ||
+ | |||
+ | -- Shows the CPU utilization of the system similiar to top(1). | ||
+ | -- This script depends on the /proc filesystem and thus only works on Linux. | ||
+ | -- Tested with kernel 2.6.16. | ||
+ | |||
+ | -- Configuration: | ||
+ | -- The following placeholders (with a "cpustat_" prefix) can be used in the | ||
+ | -- statusbar template: `user', `nice', `idle', `system', `iowait', `irq', | ||
+ | -- `softirq' and `steal'. In addition, `system_adj' sums up the last 5 fields. | ||
+ | -- For a compact output simply use the `cpustat' placeholder. | ||
+ | |||
+ | -- This software is in the public domain. | ||
+ | |||
+ | -------------------------------------------------------------------------------- | ||
+ | |||
+ | |||
+ | local defaults = { | ||
+ | update_interval = 1000, -- 1 second | ||
+ | } | ||
+ | |||
+ | local settings = table.join(statusd.get_config("cpustat"), defaults) | ||
+ | |||
+ | local last_stat, current_stat | ||
+ | local last_uptime, current_uptime = 0, 0 | ||
+ | local first_run = true | ||
+ | |||
+ | function math.round(number, precision) | ||
+ | local m = 10^(precision or 0) | ||
+ | return math.floor((number*m)+(1/2)) / m | ||
+ | end | ||
+ | |||
+ | -- this function reads stats from /proc/stat and /proc/uptime and calculates the | ||
+ | -- CPU time used in the measurement interval | ||
+ | local function get_cpustat() | ||
+ | local f1, f2, s, s2 | ||
+ | f1 = io.open('/proc/stat', 'r') | ||
+ | f2 = io.open('/proc/uptime', 'r') | ||
+ | if ((f1 == nil ) or (f2 == nil)) then return nil end | ||
+ | s = f1:read("*l") | ||
+ | s2 = f2:read("*l") | ||
+ | f1:close() | ||
+ | f2:close() | ||
+ | |||
+ | last_uptime = current_uptime | ||
+ | local tmp, tmp, up1, up2 | ||
+ | tmp, tmp, up1, up2 = string.find(s2, "(%d+)\.(%d+)%s%d") | ||
+ | current_uptime = tonumber(up1 .. up2) | ||
+ | local uptime_interv = current_uptime - last_uptime | ||
+ | |||
+ | local t = {} | ||
+ | for tmp in string.gfind(s, "%s+(%d+)") do | ||
+ | table.insert(t, tonumber(tmp)) | ||
+ | end | ||
+ | |||
+ | last_stat = current_stat | ||
+ | current_stat = t | ||
+ | if (first_run) then | ||
+ | last_stat = t | ||
+ | first_run = false | ||
+ | end | ||
+ | |||
+ | local c = {} | ||
+ | for i = 1, table.getn(t) do | ||
+ | table.insert(c, math.round(((current_stat[i] - last_stat[i]) | ||
+ | / uptime_interv) * 100)) | ||
+ | end | ||
+ | |||
+ | -- adjusted system CPU time (= system + iowait + irq + softirq + steal) | ||
+ | table.insert(c, math.round((((current_stat[3] - last_stat[3]) + | ||
+ | (current_stat[5] - last_stat[5]) + | ||
+ | (current_stat[6] - last_stat[6]) + | ||
+ | (current_stat[7] - last_stat[7]) + | ||
+ | (current_stat[8] - last_stat[8])) | ||
+ | / uptime_interv) * 100)) | ||
+ | return c | ||
+ | end | ||
+ | |||
+ | local cpustat_timer = statusd.create_timer() | ||
+ | |||
+ | local function update_cpustat() | ||
+ | local t = get_cpustat() | ||
+ | if (t == nil) then return nil end | ||
+ | statusd.inform("cpustat_user", t[1] .. "%") | ||
+ | statusd.inform("cpustat_nice", t[2] .. "%") | ||
+ | statusd.inform("cpustat_system", t[3] .. "%") | ||
+ | statusd.inform("cpustat_system_adj", t[9] .. "%") | ||
+ | statusd.inform("cpustat_idle", t[4] .. "%") | ||
+ | statusd.inform("cpustat_iowait", t[5] .. "%") | ||
+ | statusd.inform("cpustat_irq", t[6] .. "%") | ||
+ | statusd.inform("cpustat_softirq", t[7] .. "%") | ||
+ | statusd.inform("cpustat_steal", t[8] .. "%") | ||
+ | statusd.inform("cpustat", string.format("%3d%% us,%3d%% sy,%3d%% ni", | ||
+ | t[1], t[9], t[2])) | ||
+ | cpustat_timer:set(settings.update_interval, update_cpustat) | ||
+ | end | ||
+ | |||
+ | update_cpustat() | ||
+ | |||
+ | -- EOF | ||
+ | </pre> | ||
+ | |||
+ | <br> | ||
+ | |||
+ | === statusd_netmon.lua === | ||
+ | |||
+ | Fuer die Anzeige des Netzwerk In/Out Puts in KB/s. | ||
+ | |||
+ | ''KB/s In: %netmon_kbsin Out: %netmon_kbsout'' | ||
+ | |||
+ | <pre> | ||
+ | -- statusd_netmon.lua: monitor the speed of a network interface | ||
+ | -- | ||
+ | -- Thanx to Tuomo for pointing out a problem in the previous script. | ||
+ | -- | ||
+ | -- In case this doesn't work for someone, do let me know :) | ||
+ | -- | ||
+ | -- Author | ||
+ | -- Sadrul Habib Chowdhury (Adil) | ||
+ | -- imadil at gmail dot com | ||
+ | -- | ||
+ | -- Support for per-stat monitors and thresholds added by Jeremy | ||
+ | -- Hankins. | ||
+ | -- | ||
+ | -- | ||
+ | -- Monitor values available with this monitor: | ||
+ | -- | ||
+ | -- netmon | ||
+ | -- netmon_kbsin | ||
+ | -- netmon_kbsout | ||
+ | -- netmon_avgin | ||
+ | -- netmon_avgout | ||
+ | -- netmon_count | ||
+ | -- | ||
+ | -- To use the average values or the count you need show_avg and | ||
+ | -- show_count turned on, respectively. If you want the default format | ||
+ | -- (which you get with %netmon) but with colors for important and | ||
+ | -- critical thresholds, try: | ||
+ | -- | ||
+ | -- %netmon_kbsin/%netmon_kbsout (%netmon_avgin/%netmon_avgout) | ||
+ | |||
+ | if not statusd_netmon then | ||
+ | statusd_netmon = { | ||
+ | device = "eth0", | ||
+ | show_avg = 1, -- show average stat? | ||
+ | avg_sec = 60, -- default, shows average of 1 minute | ||
+ | show_count = 0, -- show tcp connection count? | ||
+ | interval = 1*1000, -- update every second | ||
+ | |||
+ | -- Threshold information. These values should likely be tweaked to | ||
+ | -- suit local conditions. | ||
+ | important = { | ||
+ | kbsin = 1/10, | ||
+ | kbsout = 1/10, | ||
+ | avgin = 1/10, | ||
+ | avgout = 1/10, | ||
+ | count = 4, | ||
+ | }, | ||
+ | |||
+ | critical = { | ||
+ | kbsin = 1200, | ||
+ | kbsout = 120, | ||
+ | avgin = 5, | ||
+ | avgout = 5, | ||
+ | count = 50, | ||
+ | } | ||
+ | } | ||
+ | end | ||
+ | |||
+ | local timer = nil -- the timer | ||
+ | local positions = {} -- positions where the entries will be | ||
+ | local last = {} -- the last readings | ||
+ | local history_in = {} -- history to calculate the average | ||
+ | local history_out = {} | ||
+ | local total_in, total_out = 0, 0 | ||
+ | local counter = 0 -- | ||
+ | |||
+ | local settings = table.join(statusd.get_config("netmon"), statusd_netmon) | ||
+ | |||
+ | -- | ||
+ | -- tokenize the string | ||
+ | -- | ||
+ | local function tokenize(str) | ||
+ | local ret = {} | ||
+ | local i = 0 | ||
+ | local k = nil | ||
+ | |||
+ | for k in string.gfind(str, '(%w+)') do | ||
+ | ret[i] = k | ||
+ | i = i + 1 | ||
+ | end | ||
+ | return ret | ||
+ | end | ||
+ | |||
+ | -- | ||
+ | -- get the connection count | ||
+ | -- | ||
+ | local function get_connection_count() | ||
+ | local f = io.popen('netstat -st', 'r') | ||
+ | if not f then return nil end | ||
+ | |||
+ | local output = f:read('*a') | ||
+ | if string.len(output) == 0 then return nil end | ||
+ | |||
+ | local s, e, connections = | ||
+ | string.find(output, '%s+(%d+)%s+connections established%s') | ||
+ | f:close() | ||
+ | return tonumber(connections) | ||
+ | end | ||
+ | |||
+ | -- | ||
+ | -- calculate the average | ||
+ | -- | ||
+ | local function calc_avg(lin, lout) | ||
+ | if counter == settings.avg_sec then | ||
+ | counter = 0 | ||
+ | end | ||
+ | |||
+ | total_in = total_in - history_in[counter] + lin | ||
+ | history_in[counter] = lin | ||
+ | |||
+ | total_out = total_out - history_out[counter] + lout | ||
+ | history_out[counter] = lout | ||
+ | |||
+ | counter = counter + 1 | ||
+ | |||
+ | return total_in/settings.avg_sec, total_out/settings.avg_sec | ||
+ | end | ||
+ | |||
+ | -- | ||
+ | -- parse the information | ||
+ | -- | ||
+ | local function parse_netmon_info() | ||
+ | local s | ||
+ | local lin, lout | ||
+ | |||
+ | for s in io.lines('/proc/net/dev') do | ||
+ | local f = string.find(s, settings.device) | ||
+ | if f then | ||
+ | local t = tokenize(s) | ||
+ | return t[positions[0]], t[positions[1]] | ||
+ | end | ||
+ | end | ||
+ | return nil, nil | ||
+ | end | ||
+ | |||
+ | -- | ||
+ | -- Return a hint value for the given meter | ||
+ | -- | ||
+ | local function get_hint(meter, val) | ||
+ | local hint = "normal" | ||
+ | local crit = settings.critical[meter] | ||
+ | local imp = settings.important[meter] | ||
+ | if crit and val > crit then | ||
+ | hint = "critical" | ||
+ | elseif imp and val > imp then | ||
+ | hint = "important" | ||
+ | end | ||
+ | return hint | ||
+ | end | ||
+ | |||
+ | -- | ||
+ | -- update the netmon monitor | ||
+ | -- | ||
+ | local function update_netmon_info() | ||
+ | local s | ||
+ | local lin, lout | ||
+ | |||
+ | local function fmt(num) | ||
+ | return(string.format("%.1fK", num)) | ||
+ | end | ||
+ | |||
+ | lin, lout = parse_netmon_info() | ||
+ | if not lin or not lout then | ||
+ | -- you should never reach here | ||
+ | statusd.inform("netmon", "oops") | ||
+ | statusd.inform("netmon_hint", "critical") | ||
+ | return | ||
+ | end | ||
+ | |||
+ | last[0], lin = lin, lin - last[0] | ||
+ | last[1], lout = lout, lout - last[1] | ||
+ | |||
+ | local kbsin = lin/1024 | ||
+ | local kbsout = lout/1024 | ||
+ | |||
+ | local output = string.format("%.1fK/%.1fK", kbsin, kbsout) | ||
+ | |||
+ | if settings.show_avg == 1 then | ||
+ | local avgin, avgout = calc_avg(lin/1024, lout/1024) | ||
+ | output = output .. string.format(" (%.1fK/%.1fK)", avgin, avgout) | ||
+ | |||
+ | statusd.inform("netmon_avgin", fmt(avgin)) | ||
+ | statusd.inform("netmon_avgin_hint", | ||
+ | get_hint("avgin", avgin)) | ||
+ | statusd.inform("netmon_avgout", fmt(avgout)) | ||
+ | statusd.inform("netmon_avgout_hint", | ||
+ | get_hint("avgout", avgout)) | ||
+ | end | ||
+ | if settings.show_count == 1 then | ||
+ | local count = get_connection_count() | ||
+ | if count then | ||
+ | output = "[" .. tostring(count) .. "] " .. output | ||
+ | |||
+ | statusd.inform("netmon_count", tostring(count)) | ||
+ | statusd.inform("netmon_count_hint", | ||
+ | get_hint("count", count)) | ||
+ | else | ||
+ | output = "[?] " .. output | ||
+ | statusd.inform("netmon_count", "?") | ||
+ | statusd.inform("netmon_count_hint", "critical") | ||
+ | end | ||
+ | end | ||
+ | |||
+ | statusd.inform("netmon_kbsin", fmt(kbsin)) | ||
+ | statusd.inform("netmon_kbsin_hint", | ||
+ | get_hint("kbsin", kbsin)) | ||
+ | statusd.inform("netmon_kbsout", fmt(kbsout)) | ||
+ | statusd.inform("netmon_kbsout_hint", | ||
+ | get_hint("kbsout", kbsout)) | ||
+ | statusd.inform("netmon", output) | ||
+ | |||
+ | timer:set(settings.interval, update_netmon_info) | ||
+ | end | ||
+ | |||
+ | -- | ||
+ | -- is everything ok to begin with? | ||
+ | -- | ||
+ | local function sanity_check() | ||
+ | local f = io.open('/proc/net/dev', 'r') | ||
+ | local e | ||
+ | |||
+ | if not f then | ||
+ | return false | ||
+ | end | ||
+ | |||
+ | local s = f:read('*line') | ||
+ | s = f:read('*line') -- the second line, which should give | ||
+ | -- us the positions of the info we seek | ||
+ | |||
+ | local t = tokenize(s) | ||
+ | local n = table.getn(t) | ||
+ | local i = 0 | ||
+ | |||
+ | for i = 0,n do | ||
+ | if t[i] == "bytes" then | ||
+ | positions[0] = i | ||
+ | break | ||
+ | end | ||
+ | end | ||
+ | |||
+ | i = positions[0] + 1 | ||
+ | |||
+ | for i=i,n do | ||
+ | if t[i] == "bytes" then | ||
+ | positions[1] = i | ||
+ | break | ||
+ | end | ||
+ | end | ||
+ | |||
+ | if not positions[0] or not positions[1] then | ||
+ | return false | ||
+ | end | ||
+ | |||
+ | s = f:read('*a') -- read the whole file | ||
+ | if not string.find(s, settings.device) then | ||
+ | return false -- the device does not exist | ||
+ | end | ||
+ | |||
+ | return true | ||
+ | end | ||
+ | |||
+ | -- | ||
+ | -- start the timer | ||
+ | -- | ||
+ | local function init_netmon_monitor() | ||
+ | if sanity_check() then | ||
+ | timer = statusd.create_timer() | ||
+ | last[0], last[1] = parse_netmon_info() | ||
+ | |||
+ | if settings.show_avg == 1 then | ||
+ | for i=0,settings.avg_sec-1 do | ||
+ | history_in[i], history_out[i] = 0, 0 | ||
+ | end | ||
+ | end | ||
+ | |||
+ | statusd.inform("netmon_template", "xxxxxxxxxxxxxxxxxxxxxxx") | ||
+ | update_netmon_info() | ||
+ | else | ||
+ | statusd.inform("netmon", "oops") | ||
+ | statusd.inform("netmon_hint", "critical") | ||
+ | end | ||
+ | end | ||
+ | |||
+ | init_netmon_monitor() | ||
+ | </pre> | ||
+ | |||
+ | <br> | ||
+ | |||
+ | == cfg_menu.lua == | ||
+ | |||
+ | Hier kann das Menue entsprechend angepasst werden. | ||
+ | |||
+ | <pre> | ||
+ | -- | ||
+ | -- Menu module configuration. | ||
+ | -- | ||
+ | -- Only bindings that are effect in menus are configured here. | ||
+ | -- See ion-menus.lua for menu definitions and ion-bindings.lua | ||
+ | -- for bindings to display menus. | ||
+ | -- | ||
+ | |||
+ | |||
+ | defbindings("WMenu", { | ||
+ | bdoc("Close the menu."), | ||
+ | kpress("Escape", "WMenu.cancel(_)"), | ||
+ | kpress("Control+G", "WMenu.cancel(_)"), | ||
+ | kpress("Control+C", "WMenu.cancel(_)"), | ||
+ | kpress("Left", "WMenu.cancel(_)"), | ||
+ | |||
+ | bdoc("Activate current menu entry."), | ||
+ | kpress("Return", "WMenu.finish(_)"), | ||
+ | kpress("KP_Enter", "WMenu.finish(_)"), | ||
+ | kpress("Control+M", "WMenu.finish(_)"), | ||
+ | kpress("Right", "WMenu.finish(_)"), | ||
+ | |||
+ | bdoc("Select next/previous menu entry."), | ||
+ | kpress("Control+N", "WMenu.select_next(_)"), | ||
+ | kpress("Control+P", "WMenu.select_prev(_)"), | ||
+ | kpress("Up", "WMenu.select_prev(_)"), | ||
+ | kpress("Down", "WMenu.select_next(_)"), | ||
+ | |||
+ | bdoc("Clear the menu's typeahead find buffer."), | ||
+ | kpress("BackSpace", "WMenu.typeahead_clear(_)"), | ||
+ | }) | ||
+ | |||
+ | </pre> | ||
+ | |||
+ | <br> | ||
+ | |||
+ | = Links = | ||
+ | |||
+ | * [http://modeemi.fi/~tuomov/ion/ Homepage] {{englisch}} | ||
+ | * [http://www-128.ibm.com/developerworks/linux/library/l-cpion.html Fun with the Ion window manager] {{englisch}} | ||
+ | * [http://www.linux.com/articles/55164 Ion, the efficient window manager] {{englisch}} | ||
+ | * [http://www.linux-user.de/ausgabe/2003/10/068-desktopia/ Bericht auf LinuxUser - ''Fliesenleger''] {{deutsch}} | ||
+ | * [http://news.gmane.org/gmane.comp.window-managers.ion.general Ion Newsgroup] {{englisch}} | ||
<br> | <br> | ||
Zeile 96: | Zeile 1.221: | ||
[[Category:Windowmanager]] | [[Category:Windowmanager]] | ||
− | |||
− |
Aktuelle Version vom 8. März 2009, 21:54 Uhr
Ion3 | |
---|---|
Ion3 Screenshot | |
Basisdaten | |
Entwickler: | Tuomo Valkonen |
Aktuelle Version: | ion-3-20090110 |
letzte Veröffentlichung: | 10. Januar 2009 |
Betriebssystem: | Linux, BSD, Unix |
Kategorie: | Windowmanager |
Lizenz: | LGPL mit Klausel |
Deutschsprachig: | |
Webseite: | Ion Webseite |
Diese Beschreibung wurde mit folgenden Distributionen getestet: |
Inhaltsverzeichnis
Info
Der Ion Fenster.- oder Windowsmanager ist der Nachvolger vom PWM Fenstermanager. Er läuft unter dem X11 System, ist extrem klein, schlank und schnell (Ressourcenschonend). Das besondere an Ion ist das sich alle geöffneten Fenster niemals überlappen. Dies heisst das alle geöffneten Fenster zu jeder Zeit sichtbar sind. Funktionieren tut die ganze Sache mit Hilfe eines Areals in welchem ein Fenster oder auch mehrere geöffnet werden können. Der gesamte Bildschirm wird unter den Areals oder auch Frames genannt aufgeteilt. Sind in einem Areal mehrere Fenster geöffnet, so bekommt hier jedes seine eigene Registerreiter ueber welche es angewählt werden kann. Im Screenshot neben an sind derzeit 4 Areals (Frames) zu sehen, in jedem ist die Konsole-RoxTerm und in ihr ein Programm gestartet. Diese gestartete Anwendung (RoxTerm/Programm) sind in einem Fenster untergebracht welches einen Registerreiter hat.
Lizenz
Der Macher von Ion - Tuomo Valkonen hat eine Lizenzaenderung vorgenommen:
„Versions not based on the copyright holder's latest release (on the corresponding "branch", such as Ion3(tm)), must within 28 days of this release, be prominently marked as (potentially) obsolete and unsupported. Significantly altered versions may be provided only if the user explicitly requests for those modifications to be applied, and is prominently notified that the software is no longer considered the standard version, and is not supported by the copyright holder. The version string displayed by the program must describe these modifications and the "support void" status.“
Dies heisst soviel wie das alle (Distributoren) die Ion3 Pakete anbieten, ihre Pakete die nach einem naechsten Ion3 Release von Tuomo Valkonen aktualisieren muessen. Falls dies nicht spaetestens nach 28 Tagen geschieht, muessen sie als veraltet oder unsupported markiert werden.
Nach dieser Bekanntgabe haben die Distributionen Arch Linux, FreeBSD und NetBSD ihre Ion3 Pakete herrausgenommen.
Alternativen
Als Alternative zu Ion gibt es folgende andere Fenstermanager:
- LarsWM
- Ratpoison
- StumpWM
- WMI
- WMII
- TrsWM
- DWM
Funktionstasten
In der Regel sind die Funktionstasten bei Ion folgendermaßen bestückt:
- F1 - Die Manpages anzeigen
- F2 - Ein eues Terminal
- F3 - Ein Programme starten
- F4 - Eine SSH-Verbindung herstellen
- F5 - Datei editieren
- F6 - Datei anzeigen
- F9 - Erstellen einer neuen Arbeitsfläche (Areal/Frame)
- F12 - Das Hauptmenü
- ALT + S - Eine Area oder Frame vertikal splitten
- ALT + KS - Eine Area oder Frame horizontal splitten
Installation
Debian
Wie immer gestaltet sich die Installation unter Debian recht einfach mit Hilfe von APT.
- Die Ion3 Version liegt derzeit bei GNU/Debian im SID Non-Free Bereich.
- Ausgenommen Debian Sarge:
- ion3 (20090110-1)
apt-get update apt-get install ion3
Konfigurationsdateien
ämtliche Konfigurationsdateien welche Systemweit für alle Benutzer gelten sind in der Regel unter /etc/X11/ion3 zu finden. Wer seinen Ion nicht Systemweit für alle gleich sondern für jeden Benutzer anderst konfigurieren möchte kann hierzu die entsprechenden Konfigurationsdateien im /home/ ~ /.ion3 Verzeichniss anlegen.
Die wohl wichtigsten Konfigurationsdateien sind:
- cfg_ioncore.lua
- cfg_statusbar.lua
- cfg_menu.lua
In der ersten Konfigurationsdateien koennen Tastenkombinationen entsprechend konfigurirt werden wie auch die F-Tasten Belegung. In der Zweiten werden Einstellungen zur Statusbar vorgenommen. Diverse Lua-Scripts fuer die Statusbar koennen hier eingebunden werden. In der letzten kann das Menue konfiguriert werden.
F-Tasten
Die Funktion der F-Tasten ist eigentlich gar nicht mal so schlecht, doch leider bei manchen Anwendungen welche selbst die F-Tasten benötigen extrem störend. zum Beispiel wird beim Arbeiten im MC das Betätigen der F-Tasten die Funktion vom Ion und nicht vom MC selbst ausführen. Drücke ich z.B. F-5 so wird die Option von Ion für das Editieren geöffnet anstelle die Option im MC für das Kopieren einer Datei. Wie können wir das Problem am einfachsten lösen. Ganz einfach, wir entfernen die Funktionen aus der entsprechenden Konfigurationsdatet so, das die F--Tasten von F1--10 keine Funktion mehr in Ion beim drücken haben.
Tastenkombinationen
Das aufrufen des Menüs lassen wir weiterhin auf der F12 Taste liegen. In dem von mir hier gezeigten Beispiel ist es als Terminal RoxTerm und Rxvt auf die Tastenkombination ALT+T und ALT+R gelegt. Mit der Kombination ALT+E wird Esetroot gestartet um ein Wallpaper bei transparentem Terminal anzeigen zu lassen (Der Pfad zum Wallpaper muss entsprechend angepasst werden). Bai ALT+W wird eine neue Arbeitsflaeche erstellt durch welche mit ALT+1 bis ALT+9 durchgewechselt werden kann.
cfg_ioncore.lua
-- -- Ion core configuration file -- -- -- Bindings. This includes global bindings and bindings common to -- screens and all types of frames only. See modules' configuration -- files for other bindings. -- -- WScreen context bindings -- -- The bindings in this context are available all the time. -- -- The variable META should contain a string of the form 'Mod1+' -- where Mod1 maybe replaced with the modifier you want to use for most -- of the bindings. Similarly ALTMETA may be redefined to add a -- modifier to some of the F-key bindings. defbindings("WScreen", { bdoc("Switch to n:th object (workspace, full screen client window) ".. "within current screen."), kpress(META.."1", "WScreen.switch_nth(_, 0)"), kpress(META.."2", "WScreen.switch_nth(_, 1)"), kpress(META.."3", "WScreen.switch_nth(_, 2)"), kpress(META.."4", "WScreen.switch_nth(_, 3)"), kpress(META.."5", "WScreen.switch_nth(_, 4)"), kpress(META.."6", "WScreen.switch_nth(_, 5)"), kpress(META.."7", "WScreen.switch_nth(_, 6)"), kpress(META.."8", "WScreen.switch_nth(_, 7)"), kpress(META.."9", "WScreen.switch_nth(_, 8)"), kpress(META.."0", "WScreen.switch_nth(_, 9)"), bdoc("Switch to next/previous object within current screen."), kpress(META.."comma", "WScreen.switch_prev(_)"), kpress(META.."period", "WScreen.switch_next(_)"), submap(META.."K", { bdoc("Go to first region demanding attention or previously active one."), kpress("K", "mod_menu.grabmenu(_, _sub, 'focuslist')"), -- Alternative without (cyclable) menu --kpress("K", "ioncore.goto_activity() or ioncore.goto_previous()"), --bdoc("Go to previous active object."), --kpress("K", "ioncore.goto_previous()"), --bdoc("Go to first object on activity/urgency list."), --kpress("I", "ioncore.goto_activity()"), bdoc("Clear all tags."), kpress("T", "ioncore.tagged_clear()"), }), bdoc("Go to n:th screen on multihead setup."), kpress(META.."Shift+1", "ioncore.goto_nth_screen(0)"), kpress(META.."Shift+2", "ioncore.goto_nth_screen(1)"), bdoc("Go to next/previous screen on multihead setup."), kpress(META.."Shift+comma", "ioncore.goto_prev_screen()"), kpress(META.."Shift+period", "ioncore.goto_next_screen()"), bdoc("Create a new workspace of chosen default type."), kpress(META.."W", "ioncore.create_ws(_)"), bdoc("Display the main menu."), kpress(ALTMETA.."F12", "mod_query.query_menu(_, _sub, 'mainmenu', 'Main menu:')"), --kpress(ALTMETA.."F12", "mod_menu.menu(_, _sub, 'mainmenu', {big=true})"), mpress("Button3", "mod_menu.pmenu(_, _sub, 'mainmenu')"), bdoc("Display the window list menu."), mpress("Button2", "mod_menu.pmenu(_, _sub, 'windowlist')"), bdoc("Forward-circulate focus."), -- '_chld' used here stands to for an actual child window that may not -- be managed by the screen itself, unlike '_sub', that is likely to be -- the managing group of that window. The right/left directions are -- used instead of next/prev, because they work better in conjunction -- with tilings. kpress(META.."Tab", "ioncore.goto_next(_chld, 'right')", "_chld:non-nil"), submap(META.."K", { bdoc("Backward-circulate focus."), kpress("AnyModifier+Tab", "ioncore.goto_next(_chld, 'left')", "_chld:non-nil"), bdoc("Raise focused object, if possible."), kpress("AnyModifier+R", "WRegion.rqorder(_chld, 'front')", "_chld:non-nil"), }), }) -- Client window bindings -- -- These bindings affect client windows directly. defbindings("WClientWin", { bdoc("Nudge the client window. This might help with some ".. "programs' resizing problems."), kpress_wait(META.."L", "WClientWin.nudge(_)"), submap(META.."K", { bdoc("Kill client owning the client window."), kpress("C", "WClientWin.kill(_)"), bdoc("Send next key press to the client window. ".. "Some programs may not allow this by default."), kpress("Q", "WClientWin.quote_next(_)"), }), }) -- Client window group bindings defbindings("WGroupCW", { bdoc("Toggle client window group full-screen mode"), kpress_wait(META.."Return", "WGroup.set_fullscreen(_, 'toggle')"), }) -- WMPlex context bindings -- -- These bindings work in frames and on screens. The innermost of such -- contexts/objects always gets to handle the key press. defbindings("WMPlex", { bdoc("Close current object."), kpress_wait(META.."C", "WRegion.rqclose_propagate(_, _sub)"), submap(META.."K", { bdoc("Detach (float) or reattach an object to its previous location."), -- By using _chld instead of _sub, we can detach/reattach queries -- attached to a group. The detach code checks if the parameter -- (_chld) is a group 'bottom' and detaches the whole group in that -- case. kpress("D", "ioncore.detach(_chld, 'toggle')", "_chld:non-nil"), }), }) -- Frames for transient windows ignore this bindmap defbindings("WMPlex.toplevel", { bdoc("Toggle tag of current object."), kpress(META.."T", "WRegion.set_tagged(_sub, 'toggle')", "_sub:non-nil"), -- bdoc("Query for manual page to be displayed."), -- kpress(ALTMETA.."F1", "mod_query.query_man(_, ':man')"), -- bdoc("Show the Ion manual page."), -- kpress(META.."F1", "ioncore.exec_on(_, ':man ion3')"), bdoc("Run a terminal emulator."), kpress(META.."T", "ioncore.exec_on(_, XTERM or 'x-terminal-emulator')"), bdoc("Run a terminal emulator."), kpress(META.."E", "ioncore.exec_on(_, XTERM or 'Esetroot /home/tobi/Bilder/Wallpaper/Modells/Models003.png')"), bdoc("Run a terminal emulator."), kpress(META.."R", "ioncore.exec_on(_, XTERM or 'rxvt -bg black -fg white -cr red -fb Monospace-9 +sb')"), bdoc("Query for command line to execute."), kpress(META.."P", "mod_query.query_exec(_)"), -- bdoc("Query for Lua code to execute."), -- kpress(META.."F3", "mod_query.query_lua(_)"), -- bdoc("Query for host to connect to with SSH."), -- kpress(ALTMETA.."F4", "mod_query.query_ssh(_, ':ssh')"), -- bdoc("Query for file to edit."), -- kpress(ALTMETA.."F5", -- "mod_query.query_editfile(_, 'run-mailcap --action=edit')"), -- bdoc("Query for file to view."), -- kpress(ALTMETA.."F6", -- "mod_query.query_runfile(_, 'run-mailcap --action=view')"), -- bdoc("Query for workspace to go to or create a new one."), -- kpress(ALTMETA.."F9", "mod_query.query_workspace(_)"), bdoc("Query for a client window to go to."), kpress(META.."G", "mod_query.query_gotoclient(_)"), bdoc("Display context menu."), --kpress(META.."M", "mod_menu.menu(_, _sub, 'ctxmenu')"), kpress(META.."M", "mod_query.query_menu(_, _sub, 'ctxmenu', 'Context menu:')"), }) -- WFrame context bindings -- -- These bindings are common to all types of frames. Some additional -- frame bindings are found in some modules' configuration files. defbindings("WFrame", { submap(META.."K", { bdoc("Maximize the frame horizontally/vertically."), kpress("H", "WFrame.maximize_horiz(_)"), kpress("V", "WFrame.maximize_vert(_)"), }), bdoc("Display context menu."), mpress("Button3", "mod_menu.pmenu(_, _sub, 'ctxmenu')"), bdoc("Begin move/resize mode."), kpress(META.."R", "WFrame.begin_kbresize(_)"), bdoc("Switch the frame to display the object indicated by the tab."), mclick("Button1@tab", "WFrame.p_switch_tab(_)"), mclick("Button2@tab", "WFrame.p_switch_tab(_)"), bdoc("Resize the frame."), mdrag("Button1@border", "WFrame.p_resize(_)"), mdrag(META.."Button3", "WFrame.p_resize(_)"), bdoc("Move the frame."), mdrag(META.."Button1", "WFrame.p_move(_)"), bdoc("Move objects between frames by dragging and dropping the tab."), mdrag("Button1@tab", "WFrame.p_tabdrag(_)"), mdrag("Button2@tab", "WFrame.p_tabdrag(_)"), }) -- Frames for transient windows ignore this bindmap defbindings("WFrame.toplevel", { bdoc("Query for a client window to attach."), kpress(META.."A", "mod_query.query_attachclient(_)"), submap(META.."K", { -- Display tab numbers when modifiers are released submap_wait("ioncore.tabnum.show(_)"), bdoc("Switch to n:th object within the frame."), kpress("1", "WFrame.switch_nth(_, 0)"), kpress("2", "WFrame.switch_nth(_, 1)"), kpress("3", "WFrame.switch_nth(_, 2)"), kpress("4", "WFrame.switch_nth(_, 3)"), kpress("5", "WFrame.switch_nth(_, 4)"), kpress("6", "WFrame.switch_nth(_, 5)"), kpress("7", "WFrame.switch_nth(_, 6)"), kpress("8", "WFrame.switch_nth(_, 7)"), kpress("9", "WFrame.switch_nth(_, 8)"), kpress("0", "WFrame.switch_nth(_, 9)"), bdoc("Switch to next/previous object within the frame."), kpress("N", "WFrame.switch_next(_)"), kpress("P", "WFrame.switch_prev(_)"), bdoc("Move current object within the frame left/right."), kpress("comma", "WFrame.dec_index(_, _sub)", "_sub:non-nil"), kpress("period", "WFrame.inc_index(_, _sub)", "_sub:non-nil"), bdoc("Maximize the frame horizontally/vertically."), kpress("H", "WFrame.maximize_horiz(_)"), kpress("V", "WFrame.maximize_vert(_)"), bdoc("Attach tagged objects to this frame."), kpress("A", "ioncore.tagged_attach(_)"), }), }) -- Bindings for floating frames. defbindings("WFrame.floating", { bdoc("Toggle shade mode"), mdblclick("Button1@tab", "WFrame.set_shaded(_, 'toggle')"), bdoc("Raise the frame."), mpress("Button1@tab", "WRegion.rqorder(_, 'front')"), mpress("Button1@border", "WRegion.rqorder(_, 'front')"), mclick(META.."Button1", "WRegion.rqorder(_, 'front')"), bdoc("Lower the frame."), mclick(META.."Button3", "WRegion.rqorder(_, 'back')"), bdoc("Move the frame."), mdrag("Button1@tab", "WFrame.p_move(_)"), }) -- WMoveresMode context bindings -- -- These bindings are available keyboard move/resize mode. The mode -- is activated on frames with the command begin_kbresize (bound to -- META.."R" above by default). defbindings("WMoveresMode", { bdoc("Cancel the resize mode."), kpress("AnyModifier+Escape","WMoveresMode.cancel(_)"), bdoc("End the resize mode."), kpress("AnyModifier+Return","WMoveresMode.finish(_)"), bdoc("Grow in specified direction."), kpress("Left", "WMoveresMode.resize(_, 1, 0, 0, 0)"), kpress("Right", "WMoveresMode.resize(_, 0, 1, 0, 0)"), kpress("Up", "WMoveresMode.resize(_, 0, 0, 1, 0)"), kpress("Down", "WMoveresMode.resize(_, 0, 0, 0, 1)"), kpress("F", "WMoveresMode.resize(_, 1, 0, 0, 0)"), kpress("B", "WMoveresMode.resize(_, 0, 1, 0, 0)"), kpress("P", "WMoveresMode.resize(_, 0, 0, 1, 0)"), kpress("N", "WMoveresMode.resize(_, 0, 0, 0, 1)"), bdoc("Shrink in specified direction."), kpress("Shift+Left", "WMoveresMode.resize(_,-1, 0, 0, 0)"), kpress("Shift+Right", "WMoveresMode.resize(_, 0,-1, 0, 0)"), kpress("Shift+Up", "WMoveresMode.resize(_, 0, 0,-1, 0)"), kpress("Shift+Down", "WMoveresMode.resize(_, 0, 0, 0,-1)"), kpress("Shift+F", "WMoveresMode.resize(_,-1, 0, 0, 0)"), kpress("Shift+B", "WMoveresMode.resize(_, 0,-1, 0, 0)"), kpress("Shift+P", "WMoveresMode.resize(_, 0, 0,-1, 0)"), kpress("Shift+N", "WMoveresMode.resize(_, 0, 0, 0,-1)"), bdoc("Move in specified direction."), kpress(META.."Left", "WMoveresMode.move(_,-1, 0)"), kpress(META.."Right", "WMoveresMode.move(_, 1, 0)"), kpress(META.."Up", "WMoveresMode.move(_, 0,-1)"), kpress(META.."Down", "WMoveresMode.move(_, 0, 1)"), kpress(META.."F", "WMoveresMode.move(_,-1, 0)"), kpress(META.."B", "WMoveresMode.move(_, 1, 0)"), kpress(META.."P", "WMoveresMode.move(_, 0,-1)"), kpress(META.."N", "WMoveresMode.move(_, 0, 1)"), }) -- -- Menu definitions -- -- Main menu defmenu("mainmenu", { menuentry("Run...", "mod_query.query_exec(_)"), menuentry("Terminal", "ioncore.exec_on(_, XTERM or 'x-terminal-emulator')"), menuentry("Lock screen", "ioncore.exec_on(_, ioncore.lookup_script('ion-lock'))"), menuentry("Help", "mod_query.query_man(_)"), menuentry("About Ion", "mod_query.show_about_ion(_)"), submenu("Styles", "stylemenu"), submenu("Debian", "Debian"), submenu("Session", "sessionmenu"), }) -- Session control menu defmenu("sessionmenu", { menuentry("Save", "ioncore.snapshot()"), menuentry("Restart", "ioncore.restart()"), menuentry("Restart TWM", "ioncore.restart_other('twm')"), menuentry("Exit", "ioncore.shutdown()"), }) -- Context menu (frame actions etc.) defctxmenu("WFrame", "Frame", { -- Note: this propagates the close to any subwindows; it does not -- destroy the frame itself, unless empty. An entry to destroy tiled -- frames is configured in cfg_tiling.lua. menuentry("Close", "WRegion.rqclose_propagate(_, _sub)"), -- Low-priority entries menuentry("Attach tagged", "ioncore.tagged_attach(_)", { priority = 0 }), menuentry("Clear tags", "ioncore.tagged_clear()", { priority = 0 }), menuentry("Window info", "mod_query.show_tree(_, _sub)", { priority = 0 }), }) -- Context menu for groups (workspaces, client windows) defctxmenu("WGroup", "Group", { menuentry("Toggle tag", "WRegion.set_tagged(_, 'toggle')"), menuentry("De/reattach", "ioncore.detach(_, 'toggle')"), }) -- Context menu for workspaces defctxmenu("WGroupWS", "Workspace", { menuentry("Close", "WRegion.rqclose(_)"), menuentry("Rename", "mod_query.query_renameworkspace(nil, _)"), menuentry("Attach tagged", "ioncore.tagged_attach(_)"), }) -- Context menu for client windows defctxmenu("WClientWin", "Client window", { menuentry("Kill", "WClientWin.kill(_)"), }) -- Auto-generated Debian menu definitions if os and os.execute("test -x /usr/bin/update-menus") == 0 then if ioncore.is_i18n() then dopath("debian-menu-i18n") else dopath("debian-menu") end
cfg_statusbar.lua
Um die Statuszeile in Ion anzupassen muess die cfg_statusbar.lua angepasst werden.
-- -- Ion statusbar module configuration file -- -- Create a statusbar mod_statusbar.create{ -- First screen, bottom left corner screen=0, pos='bl', -- Set this to true if you want a full-width statusbar fullsize=false, -- Swallow systray windows systray=true, -- Template. Tokens %string are replaced with the value of the -- corresponding meter. Currently supported meters are: -- date date -- load load average (1min, 5min, 15min) -- load_Nmin N minute load average (N=1, 5, 15) -- mail_new mail count (mbox format file $MAIL) -- mail_unread mail count -- mail_total mail count -- mail_*_new mail count (from an alternate mail folder, see below) -- mail_*_unread mail count -- mail_*_total mail count -- -- Space preceded by % adds stretchable space for alignment of variable -- meter value widths. > before meter name aligns right using this -- stretchable space , < left, and | centers. -- Meter values may be zero-padded to a width preceding the meter name. -- These alignment and padding specifiers and the meter name may be -- enclosed in braces {}. -- -- %filler causes things on the marker's sides to be aligned left and -- right, respectively, and %systray is a placeholder for system tray -- windows and icons. -- -- Zusatzliche Lua Skripte werden in die Statusbar mit eingebunden. -- template="[ %date || load:% %>load || MEM Used: %mem_hused MB - Free: %mem_hfree MB || CPU: %cpustat_user || KB/s In: %netmon_kbsin Out: %netmon_kbsout ]", -- Default Statusbar -- template="[ %date || load: %05load_1min || mail: %02mail_new/%02mail_total ] %filler%systray", -- Derzeit aktiev template="[ %date || load: %05load_1min", } -- Launch ion-statusd. This must be done after creating any statusbars -- for necessary statusd modules to be parsed from the templates. mod_statusbar.launch_statusd{ -- Date meter date={ -- ISO-8601 date format with additional abbreviated day name date_format='%a %Y-%m-%d %H:%M', -- Finnish etc. date format --date_format='%a %d.%m.%Y %H:%M', -- Locale date format (usually shows seconds, which would require -- updating rather often and can be distracting) --date_format='%c', -- Additional date formats. --[[ formats={ time = '%H:%M', -- %date_time } --]] }, -- Load meter load={ --update_interval=10*1000, --important_threshold=1.5, --critical_threshold=4.0, }, -- Mail meter -- -- To monitor more mbox files, add them to the files table. For -- example, add mail_work_new and mail_junk_new to the template -- above, and define them in the files table: -- -- files = { work = "/path/to/work_email", junk = "/path/to/junk" } -- -- Don't use the keyword 'spool' as it's reserved for mbox. mail={ --update_interval=60*1000, --mbox=os.getenv("MAIL"), --files={}, },
Die Zeile
template="[ %date || load: %05load_1min ",
ist die interessante. Hier kann entsprechend konfiguriert werden. In meinem Beispiel wird der Tag, Datum, Uhrzeit und Loadwert angezeigt. Ich habe die Defaulteinstellung ebenfalls in der Datei stehen lassen und zudem eine von mir verwendete Version mit eingetragen bei welcher ein paar Lua Skripte mit eingebunden werden um CPU Auslastung, RAM Speicherverbrauch und Netzwerkdurchlass anzuzeigen.
Damit zusaetzliche Lua Skripte unter Ion funktionieren muessen sie ins ion3 Verzeichniss kopiert werden. In den Skripten selbst ist meistens genau beschrieben wie weiter vorgegangen werden muss. Meistens muessen Pfade angepasst werden oder ein paar kleine Einstellungen wie z.B. Netzwerkinterface usw. Bekommen tut man diese Skripte auf der Ion Webseite oder beim Distributor. Ich fuege ein paar Skripte hier ins Wiki mit ein, es sind diese welche auch in dem Konfigurationsbeispiel der cfg_statusbar.lua eingetragen sind.
statusd_mem.lua
Fuer die Anzeige des freien RAM Speichers in der Statusbar.
Wird durch MEM Used: %mem_hused MB - Free: %mem_hfree MB eingebunden.
------------------------------------------------------------------------------------------- -- -- PURPOSE: -- Shows system available memory catching [free] command outputs. -- It is intended to make it simpler than statusd_meminfo, plus user configurable -- measurement units and alarms for "all" available memory metters. -- -- USAGE: -- Just set any of the following labels on cfg_statusbar.lua: %mem_hused, %mem_shared -- %mem_free, %mem_hfree, %mem_swap, %mem_used, %mem_cached. Example: [MF: %mem_free] -- -- MEANINGS: --> ** "mem_hfree" poses as "htop free memory" or "mem_free +cached +buffers", -- in oposition, "mem_hused" is "mem_used -cached -buffers"; other labels have -- transparent meanings. -- ------- CONFIG EXAMPLE: ------------------------------------------------------------------ -- -- To modify settings is quite simple and flexible, write (on cfg_statusbar.lua) -- something like this, without comments: -- mem = { -- update_interval = 15*1000, --> Milliseconds -- free_alarm = 25, --> Limits percentaje ... -- used_alarm = 65, -- units = "m" --> "g" or "k" too -- } -- Write only the settings that do you want to change or leave this section as is... --> ** "update_interval" means "time in milliseconds to update info (default = 15)" -- "xx_alarm" means "do a color advise when memory *percentage* reaches this value". -- (both defaults are 50). "units" means Gb "g", Mb "m" or Kb "k" (default = "m") ------------------------------------------------------------------------------------------ -- -- NOTES: -- * Alarms for used memory are inverse to alarms for free memory (think about it...) -- "mem_total" label is useless. If total memory varies, its time to open your -- hardware and check this script from barebone. Seriously, may be your video or wifi -- devices were claiming some free R.A.M. on your machine start-up. -- However, I included "mem_total" just in case. -- ** This script has non blocking I/O. -- -- LICENSE: -- GPL2 Copyright(C)2006 Mario Garcia H. -- (Please see http://www.gnu.org/licenses/gpl.html to read complete license) -- -- T.STAMP: Thu Dec 7 03:28:04 2006 -- -- DEPENDS: "free" command. Probably, all GNU/Linux distros have one. -- -- INSECTS: Not known. -- -- CONTACT: -- G.H. <drosophila (at) nmental (dot) com> -- ------- DEFAULT SETTINGS :----------------------------------------------------------------- local mem_timer local defaults = { update_interval = 15*1000, free_alarm = 50, used_alarm = 50, units = "m" } local settings = table.join(statusd.get_config("mem"), defaults) ------- MEM MONITOR :---------------------------------------------------------------------- local function show_meminfo(status) while status do local ok, _, total, used, free, shared, buffers, cached =-- string.find(status, "Mem:%s+(%d+)%s+(%d+)%s+(%d+)%s+(%d+)%s+(%d+)%s+(%d+)") -- if not ok then statusd.inform("mem_template", "--") return end -- statusd.inform("mem_total", total) statusd.inform("mem_used", used) statusd.inform("mem_free", free) statusd.inform("mem_shared", shared) statusd.inform("mem_buffers", buffers) statusd.inform("mem_cached", cached) statusd.inform("mem_hused", tostring(used - cached - buffers)) statusd.inform("mem_hfree", tostring(free + cached + buffers)) -- statusd.inform("mem_used_hint", used*100/total >= settings.used_alarm and "critical" or "important") statusd.inform("mem_hused_hint", (used - cached - buffers)*100/total >= settings.used_alarm and "critical" or "important") statusd.inform("mem_free_hint", free*100/total <= settings.free_alarm and "critical" or "important") statusd.inform("mem_hfree_hint", (free + cached + buffers)*100/total <= settings.free_alarm and "critical" or "important") -- status = coroutine.yield() end end local function update_mem() statusd.popen_bgread("free -"..settings.units.."o", coroutine.wrap(show_meminfo)) mem_timer:set(settings.update_interval, update_mem) end mem_timer = statusd.create_timer() update_mem()
statusd_cpustat.lua
Fuer die Anzeige der CPU Auslastung in der Statuszeile.
CPU: %cpustat_user
-- $Id: statusd_cpustat.lua 80 2007-03-10 00:16:09Z tibi $ -- statusd_cpustat.lua -- CPU monitor for Ion3's statusbar -- version : 0.3 -- date : 2007-03-10 -- author : Tibor Csögör <tibi@tiborius.net> -- Shows the CPU utilization of the system similiar to top(1). -- This script depends on the /proc filesystem and thus only works on Linux. -- Tested with kernel 2.6.16. -- Configuration: -- The following placeholders (with a "cpustat_" prefix) can be used in the -- statusbar template: `user', `nice', `idle', `system', `iowait', `irq', -- `softirq' and `steal'. In addition, `system_adj' sums up the last 5 fields. -- For a compact output simply use the `cpustat' placeholder. -- This software is in the public domain. -------------------------------------------------------------------------------- local defaults = { update_interval = 1000, -- 1 second } local settings = table.join(statusd.get_config("cpustat"), defaults) local last_stat, current_stat local last_uptime, current_uptime = 0, 0 local first_run = true function math.round(number, precision) local m = 10^(precision or 0) return math.floor((number*m)+(1/2)) / m end -- this function reads stats from /proc/stat and /proc/uptime and calculates the -- CPU time used in the measurement interval local function get_cpustat() local f1, f2, s, s2 f1 = io.open('/proc/stat', 'r') f2 = io.open('/proc/uptime', 'r') if ((f1 == nil ) or (f2 == nil)) then return nil end s = f1:read("*l") s2 = f2:read("*l") f1:close() f2:close() last_uptime = current_uptime local tmp, tmp, up1, up2 tmp, tmp, up1, up2 = string.find(s2, "(%d+)\.(%d+)%s%d") current_uptime = tonumber(up1 .. up2) local uptime_interv = current_uptime - last_uptime local t = {} for tmp in string.gfind(s, "%s+(%d+)") do table.insert(t, tonumber(tmp)) end last_stat = current_stat current_stat = t if (first_run) then last_stat = t first_run = false end local c = {} for i = 1, table.getn(t) do table.insert(c, math.round(((current_stat[i] - last_stat[i]) / uptime_interv) * 100)) end -- adjusted system CPU time (= system + iowait + irq + softirq + steal) table.insert(c, math.round((((current_stat[3] - last_stat[3]) + (current_stat[5] - last_stat[5]) + (current_stat[6] - last_stat[6]) + (current_stat[7] - last_stat[7]) + (current_stat[8] - last_stat[8])) / uptime_interv) * 100)) return c end local cpustat_timer = statusd.create_timer() local function update_cpustat() local t = get_cpustat() if (t == nil) then return nil end statusd.inform("cpustat_user", t[1] .. "%") statusd.inform("cpustat_nice", t[2] .. "%") statusd.inform("cpustat_system", t[3] .. "%") statusd.inform("cpustat_system_adj", t[9] .. "%") statusd.inform("cpustat_idle", t[4] .. "%") statusd.inform("cpustat_iowait", t[5] .. "%") statusd.inform("cpustat_irq", t[6] .. "%") statusd.inform("cpustat_softirq", t[7] .. "%") statusd.inform("cpustat_steal", t[8] .. "%") statusd.inform("cpustat", string.format("%3d%% us,%3d%% sy,%3d%% ni", t[1], t[9], t[2])) cpustat_timer:set(settings.update_interval, update_cpustat) end update_cpustat() -- EOF
statusd_netmon.lua
Fuer die Anzeige des Netzwerk In/Out Puts in KB/s.
KB/s In: %netmon_kbsin Out: %netmon_kbsout
-- statusd_netmon.lua: monitor the speed of a network interface -- -- Thanx to Tuomo for pointing out a problem in the previous script. -- -- In case this doesn't work for someone, do let me know :) -- -- Author -- Sadrul Habib Chowdhury (Adil) -- imadil at gmail dot com -- -- Support for per-stat monitors and thresholds added by Jeremy -- Hankins. -- -- -- Monitor values available with this monitor: -- -- netmon -- netmon_kbsin -- netmon_kbsout -- netmon_avgin -- netmon_avgout -- netmon_count -- -- To use the average values or the count you need show_avg and -- show_count turned on, respectively. If you want the default format -- (which you get with %netmon) but with colors for important and -- critical thresholds, try: -- -- %netmon_kbsin/%netmon_kbsout (%netmon_avgin/%netmon_avgout) if not statusd_netmon then statusd_netmon = { device = "eth0", show_avg = 1, -- show average stat? avg_sec = 60, -- default, shows average of 1 minute show_count = 0, -- show tcp connection count? interval = 1*1000, -- update every second -- Threshold information. These values should likely be tweaked to -- suit local conditions. important = { kbsin = 1/10, kbsout = 1/10, avgin = 1/10, avgout = 1/10, count = 4, }, critical = { kbsin = 1200, kbsout = 120, avgin = 5, avgout = 5, count = 50, } } end local timer = nil -- the timer local positions = {} -- positions where the entries will be local last = {} -- the last readings local history_in = {} -- history to calculate the average local history_out = {} local total_in, total_out = 0, 0 local counter = 0 -- local settings = table.join(statusd.get_config("netmon"), statusd_netmon) -- -- tokenize the string -- local function tokenize(str) local ret = {} local i = 0 local k = nil for k in string.gfind(str, '(%w+)') do ret[i] = k i = i + 1 end return ret end -- -- get the connection count -- local function get_connection_count() local f = io.popen('netstat -st', 'r') if not f then return nil end local output = f:read('*a') if string.len(output) == 0 then return nil end local s, e, connections = string.find(output, '%s+(%d+)%s+connections established%s') f:close() return tonumber(connections) end -- -- calculate the average -- local function calc_avg(lin, lout) if counter == settings.avg_sec then counter = 0 end total_in = total_in - history_in[counter] + lin history_in[counter] = lin total_out = total_out - history_out[counter] + lout history_out[counter] = lout counter = counter + 1 return total_in/settings.avg_sec, total_out/settings.avg_sec end -- -- parse the information -- local function parse_netmon_info() local s local lin, lout for s in io.lines('/proc/net/dev') do local f = string.find(s, settings.device) if f then local t = tokenize(s) return t[positions[0]], t[positions[1]] end end return nil, nil end -- -- Return a hint value for the given meter -- local function get_hint(meter, val) local hint = "normal" local crit = settings.critical[meter] local imp = settings.important[meter] if crit and val > crit then hint = "critical" elseif imp and val > imp then hint = "important" end return hint end -- -- update the netmon monitor -- local function update_netmon_info() local s local lin, lout local function fmt(num) return(string.format("%.1fK", num)) end lin, lout = parse_netmon_info() if not lin or not lout then -- you should never reach here statusd.inform("netmon", "oops") statusd.inform("netmon_hint", "critical") return end last[0], lin = lin, lin - last[0] last[1], lout = lout, lout - last[1] local kbsin = lin/1024 local kbsout = lout/1024 local output = string.format("%.1fK/%.1fK", kbsin, kbsout) if settings.show_avg == 1 then local avgin, avgout = calc_avg(lin/1024, lout/1024) output = output .. string.format(" (%.1fK/%.1fK)", avgin, avgout) statusd.inform("netmon_avgin", fmt(avgin)) statusd.inform("netmon_avgin_hint", get_hint("avgin", avgin)) statusd.inform("netmon_avgout", fmt(avgout)) statusd.inform("netmon_avgout_hint", get_hint("avgout", avgout)) end if settings.show_count == 1 then local count = get_connection_count() if count then output = "[" .. tostring(count) .. "] " .. output statusd.inform("netmon_count", tostring(count)) statusd.inform("netmon_count_hint", get_hint("count", count)) else output = "[?] " .. output statusd.inform("netmon_count", "?") statusd.inform("netmon_count_hint", "critical") end end statusd.inform("netmon_kbsin", fmt(kbsin)) statusd.inform("netmon_kbsin_hint", get_hint("kbsin", kbsin)) statusd.inform("netmon_kbsout", fmt(kbsout)) statusd.inform("netmon_kbsout_hint", get_hint("kbsout", kbsout)) statusd.inform("netmon", output) timer:set(settings.interval, update_netmon_info) end -- -- is everything ok to begin with? -- local function sanity_check() local f = io.open('/proc/net/dev', 'r') local e if not f then return false end local s = f:read('*line') s = f:read('*line') -- the second line, which should give -- us the positions of the info we seek local t = tokenize(s) local n = table.getn(t) local i = 0 for i = 0,n do if t[i] == "bytes" then positions[0] = i break end end i = positions[0] + 1 for i=i,n do if t[i] == "bytes" then positions[1] = i break end end if not positions[0] or not positions[1] then return false end s = f:read('*a') -- read the whole file if not string.find(s, settings.device) then return false -- the device does not exist end return true end -- -- start the timer -- local function init_netmon_monitor() if sanity_check() then timer = statusd.create_timer() last[0], last[1] = parse_netmon_info() if settings.show_avg == 1 then for i=0,settings.avg_sec-1 do history_in[i], history_out[i] = 0, 0 end end statusd.inform("netmon_template", "xxxxxxxxxxxxxxxxxxxxxxx") update_netmon_info() else statusd.inform("netmon", "oops") statusd.inform("netmon_hint", "critical") end end init_netmon_monitor()
Hier kann das Menue entsprechend angepasst werden.
-- -- Menu module configuration. -- -- Only bindings that are effect in menus are configured here. -- See ion-menus.lua for menu definitions and ion-bindings.lua -- for bindings to display menus. -- defbindings("WMenu", { bdoc("Close the menu."), kpress("Escape", "WMenu.cancel(_)"), kpress("Control+G", "WMenu.cancel(_)"), kpress("Control+C", "WMenu.cancel(_)"), kpress("Left", "WMenu.cancel(_)"), bdoc("Activate current menu entry."), kpress("Return", "WMenu.finish(_)"), kpress("KP_Enter", "WMenu.finish(_)"), kpress("Control+M", "WMenu.finish(_)"), kpress("Right", "WMenu.finish(_)"), bdoc("Select next/previous menu entry."), kpress("Control+N", "WMenu.select_next(_)"), kpress("Control+P", "WMenu.select_prev(_)"), kpress("Up", "WMenu.select_prev(_)"), kpress("Down", "WMenu.select_next(_)"), bdoc("Clear the menu's typeahead find buffer."), kpress("BackSpace", "WMenu.typeahead_clear(_)"), })
Links
- Homepage
- Fun with the Ion window manager
- Ion, the efficient window manager
- Bericht auf LinuxUser - Fliesenleger
- Ion Newsgroup