Preface
Goal: Separate Main Flow, Code, and Data.
So anyone can focus to alter special customization in Main Script,
without changing the whole stuff.
Which PHP
Since there many PHP version.
I should say that I use PHP7.
But don’t worry, it is portable.
I do not use any sophisticated code.
Reading
Before you jump off to scripting,
you might desire to read this overview.
All The Source Code:
Impatient coder like me, like to open many tab on browser.
Table of Content
1: Directory Structure
Directory Structure has been explained in preface.
This figure will explain how it looks
in PHP script
directory.
2: Modularizing in PHP
Nothing to say here. PHP is simple
Declare a module
No need to explicitly define what to export.
Nothing to write in helper Script
Call a module
require_once ( 'helper.php' );
3: System Calls
Here we wrap herbstclient
system call
in a function named hc
.
helper.php
function hc ( $arguments )
{
system ( "herbstclient $arguments " );
}
autostart.php
# Read the manual in $ man herbstluftwm
hc ( 'emit_hook reload' );
# gap counter
system ( "echo 35 > /tmp/herbstluftwm-gap" );
4: Array: Tag Names and Keys
config.php
$tag_names = range ( 1 , 9 );
$tag_keys = array_merge ( range ( 1 , 9 ), [ 0 ]);
5: Hash: Color Schemes
Using key-value pairs , a simple data structure.
gmc.php
$color = array (
'white' => '#ffffff' ,
'black' => '#000000' ,
'grey50' => '#fafafa' ,
'grey100' => '#f5f5f5' ,
);
autostart.php
# background before wallpaper
system ( "xsetroot -solid '" . COLOR [ 'blue500' ] . "'" );
View Source File:
6: Hash: Config
The Hash in Config is very similar with the colors above.
Except that it has string interpolation all over the place.
config.php
# Modifier variables
$s = 'Shift' ;
$c = 'Control' ;
$m = 'Mod4' ;
$a = 'Mod1' ;
$keybinds = array (
# session
" $m - $s -q" => 'quit' ,
" $m - $s -r" => 'reload' ,
" $m - $s -c" => 'close'
)
This config will be utilized in main script
as shown in the following code.
autostart.php
do_config ( "keybind" , $keybinds );
do_config ( "keybind" , $tagskeybinds );
do_config ( "mousebind" , $mousebinds );
do_config ( "attr" , $attributes );
do_config ( "set" , $sets );
do_config ( "rule" , $rules );
View Source File:
7: Processing The Hash Config
This is the heart of this script .
This do-config
function has two arguments,
the herbstclient command i.e “keybind”, and hash from config.
I can see how simple and clean, PHP is.
helper.php
function do_config ( $command , $hash )
{
# loop over hash
foreach ( $hash as $key => $value ) {
hc ( $command . ' ' . $key . ' ' . $value );
# uncomment to debug in terminal
# echo $command.' '.$key.' '.$value."\n";
}
}
Debug Herbstclient Command
I do not remove line where I do debug when I made this script,
so anyone can use it later, avoid examining blindly.
Sometimes strange things happen.
Just uncomment this line to see what happened.
echo $command . ' ' . $key . ' ' . $value . " \n " ;
You can see the debugging result in figure below.
View Source File:
Nothing special here,
PHP read all exported variable from modules,
but PHP function do not read the varable unless it defined global.
helper.php
function set_tags_with_name ()
{
global $tag_names , $tag_keys ;
hc ( "rename default ' $tag_names[0] ' 2>/dev/null || true" );
foreach ( $tag_names as $index => $value ) {
hc ( "add ' $value '" );
$key = $tag_keys [ $index ];
if ( ! empty ( $key )) {
hc ( "keybind Mod4- $key use_index ' $index '" );
hc ( "keybind Mod4-Shift- $key move_index ' $index '" );
}
}
}
9: Launch the Panel
Two more functions left, it is do_panel
and startup_run
.
This two also be easy to do in PHP.
helper.php
function do_panel ()
{
$panel = __dir__ . "/panel-lemonbar.php" ;
if ( ! is_executable ( $panel ))
$panel = "/etc/xdg/herbstluftwm/panel.sh" ;
$raw = shell_exec ( 'herbstclient list_monitors | cut -d: -f1' );
$monitors = explode ( " \n " , trim ( $raw ));
foreach ( $monitors as $monitor ) {
# start it on each monitor
system ( " $panel $monitor > /dev/null &" ); // no $output
}
}
10: Run Baby Run
This is the last part.
It is intended to be modified.
Everyone has their own personal preferences.
startup.php
function startup_run ()
{
$command = 'silent new_attr bool my_not_first_autostart' ;
system ( "herbstclient $command " , $exitcode );
# without redirection your app WILL HANG !
if ( ! (( bool ) trim ( $exitcode )) ) {
# non windowed app
system ( "compton > /dev/null &" );
system ( "dunst > /dev/null &" );
system ( "parcellite > /dev/null &" );
system ( "nitrogen --restore > /dev/null &" );
system ( "mpd > /dev/null &" );
# windowed app
exec ( "xfce4-terminal > /dev/null 2>&1 &" );
exec ( "firefox > /dev/null 2>&1 &" );
exec ( "geany > /dev/null 2>&1 &" );
exec ( "thunar > /dev/null 2>&1 &" );
}
}
Specific PHP Issue
Without redirection, your script will hang.
Be aware of the > /dev/null &
part in PHP.
It is mandatory for running background processing.
The PHP manual has said it clearly.
View Source File:
11: Putting It All Together
The last part is going to main script
and putting it all back together.
Now the flow is clear
Header Part: autostart.php
require_once ( 'gmc.php' );
require_once ( 'helper.php' );
require_once ( 'config.php' );
require_once ( 'startup.php' );
Procedural Part: autostart.php
# background before wallpaper
system ( "xsetroot -solid '" . COLOR [ 'blue500' ] . "'" );
# Read the manual in $ man herbstluftwm
hc ( 'emit_hook reload' );
# gap counter
system ( "echo 35 > /tmp/herbstluftwm-gap" );
# do not repaint until unlock
hc ( "lock" );
# standard
hc ( 'keyunbind --all' );
hc ( "mouseunbind --all" );
hc ( "unrule -F" );
set_tags_with_name ();
# do hash config
do_config ( "keybind" , $keybinds );
do_config ( "keybind" , $tagskeybinds );
do_config ( "mousebind" , $mousebinds );
do_config ( "attr" , $attributes );
do_config ( "set" , $sets );
do_config ( "rule" , $rules );
# unlock, just to be sure
hc ( "unlock" );
# launch statusbar panel
do_panel ();
# load on startup
startup_run ();
View Source File:
Coming up Next
After the Window Manager, comes the Panel.
Happy Configuring.