diff options
author | Felix Bellanger <keeguon@perception.(none)> | 2007-05-28 20:54:28 +0200 |
---|---|---|
committer | Felix Bellanger <keeguon@perception.(none)> | 2007-05-28 20:54:28 +0200 |
commit | e300a89dbb085d41dc1ed8f980087b345a4baaef (patch) | |
tree | fcdec43db72960bb9d20948a740b4179d455f1ab | |
parent | c4d9c8665fc2eeeefc264de0cbb5af4bad6a21d0 (diff) | |
download | compiz-icon-e300a89dbb085d41dc1ed8f980087b345a4baaef.tar.gz compiz-icon-e300a89dbb085d41dc1ed8f980087b345a4baaef.tar.bz2 |
Added env variables
modified: Makefile
modified: README
modified: bin/compiz-icon
new file: bin/compiz-manager
modified: setup.py
modified: src/compiz-icon.py
-rwxr-xr-x | Makefile | 7 | ||||
-rw-r--r-- | README | 8 | ||||
-rwxr-xr-x | bin/compiz-icon | 4 | ||||
-rwxr-xr-x | bin/compiz-manager | 631 | ||||
-rwxr-xr-x | setup.py | 9 | ||||
-rwxr-xr-x | src/compiz-icon.py | 6 |
6 files changed, 651 insertions, 14 deletions
@@ -12,6 +12,7 @@ install: clean: ./setup.py clean uninstall: - rm -R $(TARGET)/share/compiz-trayicon - rm -R $(TARGET)/share/pixmaps/compiz-trayicon - rm -R $(TARGET)/bin/compiz-trayicon + rm -R $(TARGET)/share/compiz-icon + rm -R $(TARGET)/share/pixmaps/compiz-icon + rm -R $(TARGET)/bin/compiz-icon + rm -R $(TARGET)/bin/compiz-manager @@ -1,5 +1,5 @@ -## Compiz Tray Icon ## -Compiz Tray Icon is a small program written in python which lets you control your GL Desktop it handles your different decorators (non-GL/GL) and configurators. +## Compiz Icon ## +Compiz Icon is a small program written in python which lets you control your GL Desktop it handles your different decorators (non-GL/GL) and configurators. ## Decorators Supported non-GL decorator(s): @@ -11,10 +11,10 @@ Supported GL decorator(s): => Emerald ## Installation -Untar the Compiz Tray Icon direcory and cd into it then run: +Untar the Compiz Icon direcory and cd into it then run: sudo make install -## Compiz Tray Icon Requirements +## Compiz Icon Requirements => It's written in python and using GTK so I think you might need these two and their libraries... ## Thanks to: diff --git a/bin/compiz-icon b/bin/compiz-icon index 8584df2..6933f4c 100755 --- a/bin/compiz-icon +++ b/bin/compiz-icon @@ -2,5 +2,5 @@ # Author(s): Keeguon # Execute Compiz Manager -cd /usr/share/compiz-manager -./compiz-manager.py +cd /usr/share/compiz-icon +./compiz-icon.py diff --git a/bin/compiz-manager b/bin/compiz-manager new file mode 100755 index 0000000..f7412b2 --- /dev/null +++ b/bin/compiz-manager @@ -0,0 +1,631 @@ +#!/bin/bash +# Compiz manager +# Copyright (c) 2007 Kristian Lyngstøl <kristian@bohemians.org> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# +# +# Much of this code is based on Beryl code, also licensed under the GPL. +# This script will detect what options we need to pass to compiz to get it +# started, read a simple configuration file, and start a default +# plugin and possibly window decorator. +# All of this should be possible to override in a configuration file. + + +# Todo: +# - GUI, possibly in a second script. +# - Testing on Xgl +# - Configuration file sanity tests + +######################################################################### +# You should NOT edit this, edit the configuration file instead. # +# This is left for completness and if you need to modify the script. # +# The generated configuration file should be equally documented. # +######################################################################### + +# Defaults +# Configuration file is based on XDG base dir. Set this to override the +# defaults. Leave empty if in doubt. Use -v to see exactly what +# configuration files compiz-manager looks for on your system. +#CONFIG="./compiz-managerrc" + +# Set to yes to enable verbose (-v) by default. +VERBOSE="no" + +# Default arguments. Others are added to this, and the configuration can +# override ALL arguments. +ARGS="--sm-disable --replace" + +# Ditto for enviromental variables. +ENV="" + +# Default plugins. Should probably be ini, gconf or ccp. +PLUGINS="ccp" + +# Defines the decorator and arguments. +# Set it to empty to not use a decorator. +DECORATOR="emerald" +DECORATORARGS="--replace" + +# Delay in seconds before we bring up the decorator(s) +# This avoids starting the decorator before the WM is up, +# even if it shouldn't be a problem. +DELAY="5" + +# Set to "no" to pipe all decorator error messages to /dev/null +DECOERRORS="no" + +# Internal, used to process options. +TASK="normal" + +# No indirect by default +INDIRECT=1 + +# Echos the arguments if verbose +function verbose +{ + if [ "x$VERBOSE" = "xyes" ]; then + echo -ne "$*" + fi +} + +### System checks +# These are used for checking what hardware and software we're dealing with, +# so we can decide what options to pass to compiz, if it's even possible to +# start compiz. + +# Check wether the composite extension is present +function check_composite +{ + verbose "Checking for Composite extension: " + if xdpyinfo -queryExtensions | grep -q Composite ; then + verbose "present. \n"; + return 0; + else + verbose "not present. \n"; + return 1; + fi +} + +function check_xdamage +{ + verbose "Checking for XDamage extension: " + if xdpyinfo -queryExtensions | grep -q DAMAGE ; then + verbose "present. \n"; + return 0; + else + verbose "not present. \n"; + return 1; + fi +} +# Check for existence if NV-GLX +function check_nvidia +{ + verbose "Checking for nVidia: " + if xdpyinfo | grep -q NV-GLX ; then + verbose "present. \n" + return 0; + else + verbose "not present. \n" + return 1; + fi +} + +# Detects if Xgl is running +function check_xgl +{ + verbose "Checking for Xgl: " + if xvinfo | grep -q Xgl ; then + verbose "present. \n" + return 0; + else + verbose "not present. \n" + return 1; + fi +} + +# Check for presence of FBConfig +function check_fbconfig +{ + verbose "Checking for FBConfig: " + if glxinfo 2> /dev/null | grep -q GLX_SGIX_fbconfig ; then + verbose "present. \n" + return 0; + else + verbose "not present. \n" + return 1; + fi +} + +# Check for TFP +function check_tfp +{ + verbose "Checking for texture_from_pixmap: " + if [ `glxinfo 2>/dev/null | grep GLX_EXT_texture_from_pixmap -c` -gt 2 ] ; then + verbose "present. \n" + return 0; + else + verbose "not present. \n" + if [ "$INDIRECT" -eq 0 ]; then + unset LIBGL_ALWAYS_INDIRECT + INDIRECT=1 + return 1; + else + verbose "Trying again with indirect rendering:\n"; + INDIRECT=0 + export LIBGL_ALWAYS_INDIRECT=1 + check_tfp; + return $? + fi + fi +} + +# Check for non power of two texture support +function check_npot_texture +{ + verbose "Checking for non power of two support: " + if glxinfo | egrep -q '(GL_ARB_texture_non_power_of_two|GL_NV_texture_rectangle|GL_EXT_texture_rectangle|GL_ARB_texture_rectangle)' ; then + verbose "present. \n"; + return 0; + else + verbose "Not present. \n" + return 1; + fi + +} + +function check_xsync +{ + verbose "Checking for XSync extension: "; + if xdpyinfo -queryExtensions | grep -q SYNC ; then + verbose "present. \n"; + return 0; + else + verbose "not present. \n" ; + fi +} + +# Counts how many screens we have, and the base value for DISPLAY= +# so we can easily start one decorator per screen +function check_multiscreen +{ + SCREENS=$(xdpyinfo | grep "screen #" | wc -l) + verbose "Detected $SCREENS screen(s)\n"; + if [ "$SCREENS" == "1" ]; then return 0; fi; + verbose "Multiscreen enviromental detection: \n" + DISPLAYBASE=$(xdpyinfo | grep name\ of\ display | sed 's/.* display: *//' | sed 's/\..*//') + verbose "\tDetected $DISPLAYBASE as the base of the DISPLAY variable\n"; + SCREENNUMBERS=$(xdpyinfo | grep "screen #" | sed -r 's/screen #(.):/\1/') + for a in $SCREENNUMBERS ; do + MULTIDISPLAY[$a]=${DISPLAYBASE}.$a + verbose "\tMULTIDISPLAY[$a] set to: ${MULTIDISPLAY[$a]}\n"; + done +} + +function possible_check +{ + if [ ! "$1" ]; then + echo "Fatal: Failed test: $2"; + return 1; + fi + return 0; +} +# Returns true if we think it's actually possible to start compiz +function check_possible +{ + POSSIBLE="1" + if ! possible_check "$TFP" "texture_from_pixmap support"; then return 1; fi + if ! possible_check "$NPOT" "non-power-of-two texture support"; then return 1; fi + if ! possible_check "$FBCONFIG" "FBConfig"; then return 1; fi + if ! possible_check "$COMPOSITE" "Composite extension"; then return 1; fi + if ! possible_check "$XDAMAGE" "XDamage extension"; then return 1; fi + if ! possible_check "$XSYNC" "XSync extension"; then return 1; fi + POSSIBLE="0"; + return 0; +} + + +### Work functions + +# Builds a new-line seperated string of enviromental variables we might want +function build_env +{ + if [ $NVIDIA -eq 0 ]; then + ENV="__GL_YIELD=NOTHING " + fi + if [ $INDIRECT -eq 0 ]; then + ENV="$ENV LIBGL_ALWAYS_INDIRECT=1 " + fi +} + +# Builds the argument list +function build_args +{ + if [ $NVIDIA -eq 0 -a $XGL -ne 0 -a $INDIRECT -ne 0 ]; then + ARGS="--loose-binding "$ARGS + fi + if [ $INDIRECT -eq 0 ]; then + ARGS="--indirect-rendering "$ARGS + fi +} + + +# Prints usage +function usage +{ + echo "Usage: $0 [-r <env|args>] [-v] [-h] [-i] [-f] [-d] [-w]" + echo -e "-r\toutputs recommended values for either " + echo -e " \tenviromental variables, or arguments." + echo -e "-v\tVerbose: Output the result of each individual test" + echo -e "-h\tDisplay this message"; + echo -e "-i\tIgnore config file(s)"; + echo -e "-f\tForce; This overwrites your existing config file." + echo -e "-d\tDry run: Do everything, but don't start." + echo -e "-w\tOnly start window decorator(s). One per screen."; + echo -e "Configuration" + echo -e "$0 automatically stores configuration the first time you run it."; + echo -e "You can use that to override checks, or pass custom arguments." + echo -e "To re-write the configuration, you can either use -f, to get one" + echo -e "based on your own settings, or -fi to create a fresh config." +} + +# Parses options +function parse_options +{ + while getopts "r:vhifdw" ARG + do + if [ "x$ARG" = "xr" ]; then + TASK="RECOMMEND"; + if [ "x$OPTARG" = "xenv" ]; then + REC="env"; + elif [ "x$OPTARG" = "xargs" ]; then + REC="args" + elif [ "x$OPTARG" = "xboth" ]; then + REC="both" + else + echo "Invalid recommend argument" + usage + exit 1 + fi + elif [ "x$ARG" = "xv" ]; then + VERBOSE="yes" + elif [ "x$ARG" = "xi" ]; then + no_config + IGNORECONFIG="yes" + elif [ "x$ARG" = "xd" ]; then + DRY="yes" + elif [ "x$ARG" = "xf" ]; then + FORCE="yes" + FORCECONFIG="yes" + elif [ "x$ARG" = "xw" ]; then + TASK="WINDOWDECORATOR"; + else + usage + exit 0 + fi + done +} + +# Store configuration +function store_config +{ + if [ -n "$IGNORECONFIG" ]; then + if [ "x$FORCECONFIG" != "xyes" ]; then return; fi; + fi + if [ -z $CONFIG ]; then return ; fi + if [ -f $CONFIG ]; then + if [ "x$FORCECONFIG" != "xyes" ]; then + verbose "Not writing config; allready exists.\n"; + return 1; + fi; + fi; + echo Writing configuration to: $CONFIG + echo "# Autogenerated configuration" > $CONFIG + echo "# Generated:" `date` >> $CONFIG + echo "# On $HOSTNAME by $USER" >> $CONFIG + echo >> $CONFIG + echo "# Behavior references: (yes/no)" >> $CONFIG + echo "# Set this to \"yes\" to get the same result as if you ran compiz-manager with -v" >> $CONFIG + echo "#VERBOSE=$VERBOSE" >> $CONFIG + echo >> $CONFIG + echo "# Plugins" >> $CONFIG + echo "PLUGINS=\"$PLUGINS\"" >> $CONFIG + echo "# Or, to append: " >> $CONFIG + echo "# PLUGINS=\"\$PLUGINS <... >\"" >> $CONFIG + echo >> $CONFIG + echo "# Arguments, same as plugins to append" >> $CONFIG + echo "# ARGS=\"\$ARGS <... >\"" >> $CONFIG + echo "#ARGS=\"$ARGS\"" >> $CONFIG + echo >> $CONFIG + echo "# Screen detection: " >> $CONFIG + echo "SCREENS=$SCREENS" >> $CONFIG + if [ -n "$SCREENNUMBERS" ]; then + echo "SCREENNUMBERS=\"$SCREENNUMBERS\"" >> $CONFIG + for a in ${SCREENNUMBERS}; do + echo "MULTIDISPLAY[$a]=${MULTIDISPLAY[$a]}" >> $CONFIG + done + fi + echo >> $CONFIG + echo "# Decorator" >> $CONFIG + echo "# Use \"unset DECORATOR\" or set DECORATOR=\"\" to not use one." >> $CONFIG + echo "DECORATOR=\"$DECORATOR\"" >> $CONFIG + echo "DECORATORARGS=\"$DECORATORARGS\"" >> $CONFIG + echo "# Delay in seconds before the decorator is started." >> $CONFIG + echo "DELAY=\"$DELAY\"" >> $CONFIG + echo "# Set this to \"no\" to send all decorator errors to /dev/null" >> $CONFIG + echo "DECOERRORS=\"$DECOERRORS\"" >> $CONFIG + echo >> $CONFIG + echo "# Values of 0 mean \"true\" (present), values of 1 means \"false\" (not present)" >> $CONFIG + echo "# Checks: " >> $CONFIG + echo NVIDIA=$NVIDIA >> $CONFIG + echo FBCONFIG=$FBCONFIG >> $CONFIG + echo XGL=$XGL >> $CONFIG + echo TFP=$TFP >> $CONFIG + echo NPOT=$NPOT >> $CONFIG + echo COMPOSITE=$COMPOSITE >> $CONFIG + echo XDAMAGE=$XDAMAGE >> $CONFIG + echo POSSIBLE=$POSSIBLE >> $CONFIG + echo XSYNC=$XSYNC >> $CONFIG + echo INDIRECT=$INDIRECT >> $CONFIG +} + +#### +# Execute checks, if necesarry. +function check_everything +{ + if [ -z "$NVIDIA" ]; then + check_nvidia + NVIDIA=$? + else + verbose "Skipping nVidia check, using stored value.\n" + fi + if [ -z "$XGL" ]; then + check_xgl + XGL=$? + else + verbose "Skipping Xgl check, using stored value.\n" + fi + + if [ -z "$FBCONFIG" ]; then + check_fbconfig + FBCONFIG=$? + else + verbose "Skipping FBConfig check, using stored value.\n" + fi + if [ -z "$TFP" ]; then + check_tfp + TFP=$? + else + verbose "Skipping texture_from_pixmap check, using stored value.\n" + fi + if [ -z "$NPOT" ]; then + check_npot_texture + NPOT=$? + else + verbose "Skipping non-power-of-two texture check, using stored value.\n" + fi + + if [ -z "$COMPOSITE" ]; then + check_composite + COMPOSITE=$? + else + verbose "Skipping Composite extension check, using stored value.\n" + fi + + if [ -z "$XDAMAGE" ]; then + check_xdamage + XDAMAGE=$? + else + verbose "Skipping Damage extension check, using stored value.\n" + fi + + if [ -z "$XSYNC" ]; then + check_xsync + XSYNC=$? + else + verbose "Skipping XSync extension check, using stored value.\n"; + fi + + if [ -z "$SCREENS" ]; then + check_multiscreen + else + verbose "Skipping screen detection check, using stored value.\n"; + fi +} + +### +# Check if a directory exists; creates it if it doesn't, returns false if the +# path isn't a directory. +function require_dir +{ + if ! [ -a "$1" ]; then + verbose "Creating directory $1\n"; + mkdir $1; + fi + if [ ! -d $1 ]; then + echo "Warning: $1 exists but isn't a directory."; + return 1; + fi + return 0; +} + + +#### +# Configuration handeling +# We attempt to follow the XDG basedir spec here; +# We can read both a global config, and a local one. +# The configuration file is extremly simple, as it's just a bash script. +# It might be a good idea to improve that a bit, specially with security +# in mind, an general errors. + +# No config, so unset and possibly warn. (Might do more later) +function no_config +{ + if [ -n "$1" ]; then + echo "$1"; + fi + unset CONFIG +} + +function get_config_name +{ + if [ -n "$CONFIG" ]; then + return 0; + fi + + if [ -z "$XDG_CONFIG_HOME" ]; then + if ! require_dir "$HOME/.config" ; then + no_config "Don't know how to treat config files. Ignoring them." + else + CONFIG="$HOME/.config/compiz-managerrc" + fi + else + if ! require_dir "$XDG_CONFIG_HOME" ; then + no_config "Don't know how to treat config files. Ignoring them." + else + CONFIG="$XDG_CONFIG_HOME/compiz-managerrc" + fi + fi +} + +function parse_config +{ + if [ -z "$XDG_CONFIG_DIRS" ]; then + XDG_CONFIG_DIRS="/etc/xdg/"; + fi + + verbose "Looking for configuration file(s): \n" + oldIFS=$IFS + IFS=":"; + for a in $XDG_CONFIG_DIRS; do + if [ -f "$a/compiz-managerrc" ]; then + verbose "\t Loading ${a}/compiz-managerrc\n"; + . $a/compiz-managerrc; + else + verbose "\t Not found: ${a}/compiz-managerrc\n"; + fi + done + IFS=$oldIFS + if [ -n "$CONFIG" ]; then + if [ -f "$CONFIG" ]; then + verbose "\t Loading $CONFIG\n" + . $CONFIG ; + else + verbose "\t Not found: \"$CONFIG\"\n"; + fi + fi +} + +### +# Let's get this show started! +function start_compiz +{ + ### + # No need to continue if we've determined it's not possible to start anyway + if [ $POSSIBLE != "0" ]; then + echo "Checks indicate that it's impossible to start compiz on your system." + exit 1; + else + verbose "Checks indicate compiz should work on your system\n" + fi; + verbose "Exporting: $ENV \n" + export $ENV + verbose Executing: compiz $ARGS $PLUGINS "\n" + if [ "x$DRY" = "xyes" ]; then exit 0; fi + compiz $ARGS $PLUGINS +} + +#### +# Starts one decorator per screen +function start_decorators +{ + if [ -z "$DECORATOR" ]; then return 1; fi + if [ "$SCREENS" == "1" ]; then + verbose "Starting delayed decorator in the background: " + verbose "sleep $DELAY && $DECORATOR $DECORATORARGS &\n" + if [ "x$DRY" = "xyes" ]; then return 0; fi + if [ "$DECOERRORS" = "no" ]; then + sleep $DELAY && $DECORATOR $DECORATORARGS 2>/dev/null & + else + sleep $DELAY && $DECORATOR $DECORATORARGS & + fi + return 0; + fi + verbose "Starting decorators for all screens: \n" + for a in $SCREENNUMBERS; do + verbose "\t Screen $a: " + verbose "sleep $DELAY && DISPLAY=${MULTIDISPLAY[$a]} $DECORATOR $DECORATORARGS\n" + if [ "x$DRY" != "xyes" ]; then + if [ "$DECOERRORS" = "no" ]; then + sleep $DELAY && DISPLAY=${MULTIDISPLAY[$a]} $DECORATOR $DECORATORARGS 2>/dev/null & + else + sleep $DELAY && DISPLAY=${MULTIDISPLAY[$a]} $DECORATOR $DECORATORARGS & + fi + + fi + done +} + +#################### +# Execution begins here. +# First get options, check for configuration +# Check everything if necesarry, build the enviroment and arguments +# and eventually select a task. + +parse_options $* + +# We need this even when ignoring, or we won't know where to store force +# configuration files +get_config_name + +if [ -z "$IGNORECONFIG" ]; then parse_config +else verbose "Ignoring configuration files as you requested\n"; fi +if [ -z "$NOCHECKS" ]; then check_everything; fi + +### +# This is the master-test, it has to be done last. +if [ -z "$POSSIBLE" ]; then check_possible +else verbose "Skipping \"possible\" test, using stored value.\n"; fi + +#### +# Builds the enviromental variables list and argument list based +# on the result of the checks +build_env +build_args + +case "$TASK" in + RECOMMEND) + if [ "x$REC" = "xenv" ]; then + echo -e $ENV; + elif [ "x$REC" = "xargs" ]; then + echo -e $ARGS + elif [ "x$REC" = "xboth" ]; then + echo -e $ARGS $PLUGINS + echo -e $ENV + fi + if [ $POSSIBLE != "0" ]; then return 1; fi + ;; + WINDOWDECORATOR) + echo "start window decorator here..." + start_decorators + ;; + *) + store_config + start_decorators + start_compiz + ;; +esac + @@ -17,16 +17,15 @@ setup( description = 'Compiz-Manager is a tray icon tool to launch Compiz with different window manager or window decorator. You can also ask Compiz to start different options or configure active plugins with some configuring tools...', # Files that needs to be installed data_files = [ - (INSTALL_PREFIX + '/share/compiz-trayicon', + (INSTALL_PREFIX + '/share/compiz-icon', ['src/compiz-icon.py']), - (INSTALL_PREFIX + '/share/pixmaps/compiz-trayicon', + (INSTALL_PREFIX + '/share/pixmaps/compiz-icon', ['pixmaps/about.png', 'pixmaps/tray-icon.svg', 'pixmaps/wm-select.png', 'pixmaps/wd-select.png']), (INSTALL_PREFIX + '/bin', - ['bin/compiz-trayicon']), - #(INSTALL_PREFIX + '/share/compiz-manager/docs', - # ['docs/*.*']), + ['bin/compiz-icon', + 'bin/compiz-manager']), ] ) diff --git a/src/compiz-icon.py b/src/compiz-icon.py index be6c562..85115c5 100755 --- a/src/compiz-icon.py +++ b/src/compiz-icon.py @@ -65,6 +65,8 @@ def activate_config_ini(): # Window Manager active_wm = configuration.get('window_manager', 'set_active_wm') if active_wm == 'compiz': + # Get Env Variables + env_variables = getoutput('compiz-manager -r env') # Compiz Options wm_replace = configuration.get('window_manager', 'wm_replace') sm_disable = configuration.get('default_compiz_options', 'sm_disable') @@ -77,6 +79,7 @@ def activate_config_ini(): decorator_replace = configuration.get('decorator', 'decorator_replace') # Start Compiz WM Popen(['killall' , 'compiz.real' , 'metacity' , 'kwin']) + system('export' + env_variables) Popen(['compiz.real' , wm_replace , sm_disable , fast_filter , indirect_rendering , loose_binding , backend]) # Start GL Decorator Popen(['killall' , 'gtk-window-decorator' , 'kde-window-decorator' , 'emerald']) @@ -121,6 +124,8 @@ def start_wm(widget): activate_config_ini() def compiz_menu_activate(widget): + # Get Env Variables + env_variables = getoutput('compiz-manager -r env') # Set compiz wm configuration.set('window_manager', 'set_active_wm', 'compiz') configuration.write(open(config_file, 'w')) @@ -138,6 +143,7 @@ def compiz_menu_activate(widget): decorator_replace = configuration.get('decorator', 'decorator_replace') # Run compiz Popen(['killall' , 'compiz.real' , 'gtk-window-decorator' , 'kde-window-decorator' , 'emerald' , 'metacity' , 'kwin']) + system('export' + env_variables) Popen(['compiz.real' , wm_replace , sm_disable , fast_filter , indirect_rendering , loose_binding , backend]) Popen([set_active_decorator , decorator_replace]) |