2002-01-09 14:07:09 +00:00
// fluxbox.cc for Fluxbox Window Manager
2006-02-16 06:53:05 +00:00
// Copyright (c) 2001 - 2006 Henrik Kinnunen (fluxgen at fluxbox dot org)
2002-01-08 00:29:12 +00:00
//
2001-12-11 20:47:02 +00:00
// blackbox.cc for blackbox - an X11 Window manager
2003-01-09 18:32:09 +00:00
// Copyright (c) 1997 - 2000 Brad Hughes (bhughes at tcac.net)
2001-12-11 20:47:02 +00:00
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2003-01-09 18:32:09 +00:00
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
2001-12-11 20:47:02 +00:00
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
2002-08-13 21:19:00 +00:00
# include "fluxbox.hh"
2001-12-11 20:47:02 +00:00
# include "Screen.hh"
# include "Window.hh"
# include "Workspace.hh"
2002-09-07 20:25:39 +00:00
# include "AtomHandler.hh"
2003-02-17 12:31:17 +00:00
# include "FbCommands.hh"
2003-04-14 15:28:52 +00:00
# include "WinClient.hh"
2003-04-15 12:22:52 +00:00
# include "Keys.hh"
# include "FbAtoms.hh"
2006-02-18 11:39:38 +00:00
# include "FocusControl.hh"
2006-02-20 21:04:35 +00:00
# include "Layer.hh"
2006-02-18 11:39:38 +00:00
2003-06-30 20:37:57 +00:00
# include "defaults.hh"
2010-03-17 15:35:07 +00:00
# include "Debug.hh"
2003-05-12 04:23:31 +00:00
2004-06-07 11:46:05 +00:00
# include "FbTk/I18n.hh"
2003-08-22 21:38:58 +00:00
# include "FbTk/Image.hh"
2004-12-18 01:29:22 +00:00
# include "FbTk/FileUtil.hh"
2003-12-19 00:35:08 +00:00
# include "FbTk/ImageControl.hh"
# include "FbTk/EventManager.hh"
# include "FbTk/StringUtil.hh"
# include "FbTk/Resource.hh"
2004-01-13 12:55:25 +00:00
# include "FbTk/SimpleCommand.hh"
2003-12-19 00:35:08 +00:00
# include "FbTk/XrmDatabaseHelper.hh"
2004-01-11 13:10:39 +00:00
# include "FbTk/Command.hh"
# include "FbTk/RefCount.hh"
2004-02-27 12:32:54 +00:00
# include "FbTk/CompareEqual.hh"
2004-09-12 14:56:20 +00:00
# include "FbTk/Transparent.hh"
2005-05-02 12:10:01 +00:00
# include "FbTk/Select2nd.hh"
# include "FbTk/Compose.hh"
2006-06-22 07:46:12 +00:00
# include "FbTk/KeyUtil.hh"
2008-09-18 20:27:16 +00:00
# include "FbTk/MemFun.hh"
2003-08-22 21:38:58 +00:00
2002-08-13 21:19:00 +00:00
//Use GNU extensions
# ifndef _GNU_SOURCE
# define _GNU_SOURCE
# endif // _GNU_SOURCE
2003-01-09 18:32:09 +00:00
# ifdef HAVE_CONFIG_H
2003-05-07 23:17:38 +00:00
# include "config.h"
2002-08-13 21:19:00 +00:00
# endif // HAVE_CONFIG_H
2002-10-25 21:17:15 +00:00
# ifdef USE_GNOME
# include "Gnome.hh"
# endif // USE_GNOME
# ifdef USE_NEWWMSPEC
# include "Ewmh.hh"
2003-04-26 05:42:36 +00:00
# endif // USE_NEWWMSPEC
# ifdef REMEMBER
# include "Remember.hh"
# endif // REMEMBER
2002-10-25 21:17:15 +00:00
2002-08-17 22:14:00 +00:00
// X headers
2002-01-06 11:07:42 +00:00
# include <X11/Xlib.h>
# include <X11/Xutil.h>
# include <X11/Xresource.h>
# include <X11/Xatom.h>
# include <X11/keysym.h>
2003-06-12 14:32:08 +00:00
2003-05-12 04:23:31 +00:00
// X extensions
2002-08-02 13:00:23 +00:00
# ifdef SHAPE
2002-01-06 11:07:42 +00:00
# include <X11/extensions/shape.h>
# endif // SHAPE
2003-05-12 04:23:31 +00:00
# ifdef HAVE_RANDR
# include <X11/extensions/Xrandr.h>
# endif // HAVE_RANDR
// system headers
2002-01-06 11:07:42 +00:00
2004-08-31 15:26:40 +00:00
# ifdef HAVE_CSTDIO
# include <cstdio>
# else
# include <stdio.h>
# endif
# ifdef HAVE_CSTDLIB
# include <cstdlib>
# else
# include <stdlib.h>
# endif
# ifdef HAVE_CSTRING
# include <cstring>
# else
# include <string.h>
# endif
2001-12-11 20:47:02 +00:00
2002-08-02 13:00:23 +00:00
# ifdef HAVE_UNISTD_H
# include <sys/types.h>
# include <unistd.h>
2001-12-11 20:47:02 +00:00
# endif // HAVE_UNISTD_H
2002-08-02 13:00:23 +00:00
# ifdef HAVE_SYS_PARAM_H
# include <sys/param.h>
2001-12-11 20:47:02 +00:00
# endif // HAVE_SYS_PARAM_H
2002-08-02 13:00:23 +00:00
# ifdef HAVE_SYS_SELECT_H
# include <sys/select.h>
2001-12-11 20:47:02 +00:00
# endif // HAVE_SYS_SELECT_H
2003-05-11 22:19:17 +00:00
# ifdef HAVE_SYS_STAT_H
2002-10-25 21:17:15 +00:00
# include <sys/types.h>
# include <sys/stat.h>
2001-12-11 20:47:02 +00:00
# endif // HAVE_SYS_STAT_H
2002-08-14 00:01:10 +00:00
# include <sys/wait.h>
2001-12-11 20:47:02 +00:00
# include <iostream>
2002-01-09 15:08:22 +00:00
# include <memory>
2002-07-14 01:00:23 +00:00
# include <algorithm>
2002-09-07 20:25:39 +00:00
# include <typeinfo>
2002-01-20 02:19:16 +00:00
2006-10-30 19:31:15 +00:00
using std : : cerr ;
using std : : endl ;
using std : : string ;
using std : : vector ;
using std : : list ;
using std : : pair ;
using std : : bind2nd ;
using std : : mem_fun ;
using std : : equal_to ;
using std : : hex ;
using std : : dec ;
2002-08-14 00:01:10 +00:00
using namespace FbTk ;
2001-12-11 20:47:02 +00:00
2003-08-12 21:00:54 +00:00
namespace {
2003-05-10 14:32:35 +00:00
2004-12-18 01:29:22 +00:00
Window last_bad_window = None ;
2006-06-22 07:46:12 +00:00
// *** NOTE: if you want to debug here the X errors are
2005-04-26 01:41:55 +00:00
// coming from, you should turn on the XSynchronise call below
2004-12-18 01:29:22 +00:00
int handleXErrors ( Display * d , XErrorEvent * e ) {
2004-09-11 12:33:14 +00:00
if ( e - > error_code = = BadWindow )
last_bad_window = e - > resourceid ;
2003-05-10 14:32:35 +00:00
# ifdef DEBUG
2004-09-11 12:33:14 +00:00
else {
2004-10-21 10:18:40 +00:00
// ignore bad window ones, they happen a lot
2004-09-11 12:33:14 +00:00
// when windows close themselves
char errtxt [ 128 ] ;
XGetErrorText ( d , e - > error_code , errtxt , 128 ) ;
cerr < < " Fluxbox: X Error: " < < errtxt < < " ( " < < ( int ) e - > error_code < < " ) opcodes " < <
( int ) e - > request_code < < " / " < < ( int ) e - > minor_code < < " resource 0x " < < hex < < ( int ) e - > resourceid < < dec < < endl ;
2006-03-20 11:31:24 +00:00
// if (e->error_code != 9 && e->error_code != 183)
// kill(0, 2);
2004-09-11 12:33:14 +00:00
}
2003-05-10 14:32:35 +00:00
# endif // !DEBUG
return False ;
}
2004-12-18 01:29:22 +00:00
} // end anonymous
2003-05-10 14:32:35 +00:00
2001-12-11 20:47:02 +00:00
//static singleton var
2003-04-25 16:00:03 +00:00
Fluxbox * Fluxbox : : s_singleton = 0 ;
2001-12-11 20:47:02 +00:00
2008-08-22 13:12:01 +00:00
Fluxbox : : Fluxbox ( int argc , char * * argv , const char * dpy_name ,
const char * rcfilename , bool xsync )
2003-05-10 14:32:35 +00:00
: FbTk : : App ( dpy_name ) ,
2003-04-15 12:22:52 +00:00
m_fbatoms ( new FbAtoms ( ) ) ,
2004-10-21 10:18:40 +00:00
m_resourcemanager ( rcfilename , true ) ,
2003-07-18 15:40:55 +00:00
// TODO: shouldn't need a separate one for screen
m_screen_rm ( m_resourcemanager ) ,
2003-05-04 16:55:40 +00:00
m_rc_ignoreborder ( m_resourcemanager , false , " session.ignoreBorder " , " Session.IgnoreBorder " ) ,
2004-09-12 14:56:20 +00:00
m_rc_pseudotrans ( m_resourcemanager , false , " session.forcePseudoTransparency " , " Session.forcePseudoTransparency " ) ,
2004-10-21 10:18:40 +00:00
m_rc_colors_per_channel ( m_resourcemanager , 4 ,
2003-04-25 16:00:03 +00:00
" session.colorsPerChannel " , " Session.ColorsPerChannel " ) ,
2003-12-19 00:35:08 +00:00
m_rc_double_click_interval ( m_resourcemanager , 250 , " session.doubleClickInterval " , " Session.DoubleClickInterval " ) ,
2006-03-20 11:31:24 +00:00
m_rc_tabs_padding ( m_resourcemanager , 0 , " session.tabPadding " , " Session.TabPadding " ) ,
2005-01-12 06:16:03 +00:00
m_rc_stylefile ( m_resourcemanager , DEFAULTSTYLE , " session.styleFile " , " Session.StyleFile " ) ,
2007-07-07 23:11:04 +00:00
m_rc_styleoverlayfile ( m_resourcemanager , " ~/. " + realProgramName ( " fluxbox " ) + " /overlay " , " session.styleOverlay " , " Session.StyleOverlay " ) ,
2002-12-01 13:42:15 +00:00
m_rc_menufile ( m_resourcemanager , DEFAULTMENU , " session.menuFile " , " Session.MenuFile " ) ,
m_rc_keyfile ( m_resourcemanager , DEFAULTKEYSFILE , " session.keyFile " , " Session.KeyFile " ) ,
2007-07-07 23:11:04 +00:00
m_rc_slitlistfile ( m_resourcemanager , " ~/. " + realProgramName ( " fluxbox " ) + " /slitlist " , " session.slitlistFile " , " Session.SlitlistFile " ) ,
m_rc_appsfile ( m_resourcemanager , " ~/. " + realProgramName ( " fluxbox " ) + " /apps " , " session.appsFile " , " Session.AppsFile " ) ,
2004-04-22 21:07:57 +00:00
m_rc_tabs_attach_area ( m_resourcemanager , ATTACH_AREA_WINDOW , " session.tabsAttachArea " , " Session.TabsAttachArea " ) ,
2002-12-01 13:42:15 +00:00
m_rc_cache_life ( m_resourcemanager , 5 , " session.cacheLife " , " Session.CacheLife " ) ,
m_rc_cache_max ( m_resourcemanager , 200 , " session.cacheMax " , " Session.CacheMax " ) ,
2003-10-05 06:28:47 +00:00
m_rc_auto_raise_delay ( m_resourcemanager , 250 , " session.autoRaiseDelay " , " Session.AutoRaiseDelay " ) ,
2006-02-18 20:19:22 +00:00
m_masked_window ( 0 ) ,
2003-06-30 15:05:26 +00:00
m_mousescreen ( 0 ) ,
m_keyscreen ( 0 ) ,
2003-04-25 16:00:03 +00:00
m_last_time ( 0 ) ,
2003-12-30 20:56:41 +00:00
m_masked ( 0 ) ,
2003-04-25 16:00:03 +00:00
m_rc_file ( rcfilename ? rcfilename : " " ) ,
2003-05-10 14:32:35 +00:00
m_argv ( argv ) , m_argc ( argc ) ,
2006-07-25 21:54:58 +00:00
m_showing_dialog ( false ) ,
2003-05-10 14:32:35 +00:00
m_starting ( true ) ,
2004-10-18 01:26:54 +00:00
m_restarting ( false ) ,
2003-05-10 14:32:35 +00:00
m_shutdown ( false ) ,
2003-05-11 22:19:17 +00:00
m_server_grabs ( 0 ) ,
2003-05-12 04:23:31 +00:00
m_randr_event_type ( 0 ) ,
2007-07-07 23:11:04 +00:00
m_RC_PATH ( realProgramName ( " fluxbox " ) ) ,
2003-12-30 20:56:41 +00:00
m_RC_INIT_FILE ( " init " ) {
2004-10-21 10:18:40 +00:00
2004-06-07 11:46:05 +00:00
_FB_USES_NLS ;
2003-05-13 11:43:44 +00:00
if ( s_singleton ! = 0 )
2006-06-21 14:41:16 +00:00
throw _FB_CONSOLETEXT ( Fluxbox , FatalSingleton , " Fatal! There can only one instance of fluxbox class. " , " Error displayed on weird error where an instance of the Fluxbox class already exists! " ) ;
2003-05-13 11:43:44 +00:00
if ( display ( ) = = 0 ) {
2006-06-21 14:41:16 +00:00
throw _FB_CONSOLETEXT ( Fluxbox , NoDisplay ,
2006-05-20 15:08:14 +00:00
" Can not connect to X server. \n Make sure you started X before you start Fluxbox. " ,
" Error message when no X display appears to exist " ) ;
2002-12-01 13:42:15 +00:00
}
2004-08-18 16:30:33 +00:00
2004-09-08 16:50:42 +00:00
Display * disp = FbTk : : App : : instance ( ) - > display ( ) ;
2003-07-27 13:53:34 +00:00
// For KDE dock applets
// KDE v1.x
2004-09-08 16:50:42 +00:00
m_kwm1_dockwindow = XInternAtom ( disp ,
2003-07-27 13:53:34 +00:00
" KWM_DOCKWINDOW " , False ) ;
// KDE v2.x
2004-09-08 16:50:42 +00:00
m_kwm2_dockwindow = XInternAtom ( disp ,
2003-07-27 13:53:34 +00:00
" _KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR " , False ) ;
2003-05-10 14:32:35 +00:00
// setup X error handler
XSetErrorHandler ( ( XErrorHandler ) handleXErrors ) ;
2002-12-01 13:42:15 +00:00
//catch system signals
2004-10-21 10:18:40 +00:00
SignalHandler & sigh = SignalHandler : : instance ( ) ;
2003-05-13 11:43:44 +00:00
sigh . registerHandler ( SIGSEGV , this ) ;
sigh . registerHandler ( SIGFPE , this ) ;
2007-08-04 17:14:13 +00:00
sigh . registerHandler ( SIGPIPE , this ) ; // e.g. output sent to grep
2003-05-13 11:43:44 +00:00
sigh . registerHandler ( SIGTERM , this ) ;
sigh . registerHandler ( SIGINT , this ) ;
sigh . registerHandler ( SIGCHLD , this ) ;
sigh . registerHandler ( SIGHUP , this ) ;
2004-10-21 10:18:40 +00:00
sigh . registerHandler ( SIGUSR1 , this ) ;
2003-05-13 11:43:44 +00:00
sigh . registerHandler ( SIGUSR2 , this ) ;
2003-12-19 13:37:28 +00:00
//
// setup timer
// This timer is used to we can issue a safe reconfig command.
// Because when the command is executed we shouldn't do reconfig directly
// because it could affect ongoing menu stuff so we need to reconfig in
// the next event "round".
2008-01-11 07:41:22 +00:00
FbTk : : RefCount < FbTk : : Command < void > > reconfig_cmd ( new FbTk : : SimpleCommand < Fluxbox > ( * this , & Fluxbox : : timed_reconfigure ) ) ;
2003-12-19 13:37:28 +00:00
timeval to ;
to . tv_sec = 0 ;
to . tv_usec = 1 ;
m_reconfig_timer . setTimeout ( to ) ;
m_reconfig_timer . setCommand ( reconfig_cmd ) ;
m_reconfig_timer . fireOnce ( true ) ;
2006-07-23 09:51:54 +00:00
2008-08-22 13:12:01 +00:00
if ( xsync )
XSynchronize ( disp , True ) ;
2003-05-13 11:43:44 +00:00
2003-04-25 16:00:03 +00:00
s_singleton = this ;
2003-05-14 14:37:06 +00:00
m_have_shape = false ;
m_shape_eventbase = 0 ;
# ifdef SHAPE
2004-10-21 10:18:40 +00:00
int shape_err ;
2003-05-14 14:37:06 +00:00
m_have_shape = XShapeQueryExtension ( disp , & m_shape_eventbase , & shape_err ) ;
# endif // SHAPE
2002-12-01 13:42:15 +00:00
2003-05-12 04:23:31 +00:00
# ifdef HAVE_RANDR
// get randr event type
2004-01-09 11:37:01 +00:00
int randr_error_base ;
XRRQueryExtension ( disp , & m_randr_event_type , & randr_error_base ) ;
2003-05-12 04:23:31 +00:00
# endif // HAVE_RANDR
2003-07-18 15:40:55 +00:00
load_rc ( ) ;
2002-12-01 13:42:15 +00:00
grab ( ) ;
2004-10-21 10:18:40 +00:00
2002-12-01 13:42:15 +00:00
setupConfigFiles ( ) ;
2004-10-21 10:18:40 +00:00
2002-12-01 13:42:15 +00:00
if ( ! XSupportsLocale ( ) )
2006-11-12 17:16:56 +00:00
cerr < < _FB_CONSOLETEXT ( Fluxbox , WarningLocale ,
" Warning: X server does not support locale " ,
" XSupportsLocale returned false " ) < < endl ;
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
if ( XSetLocaleModifiers ( " " ) = = 0 )
2006-11-12 17:16:56 +00:00
cerr < < _FB_CONSOLETEXT ( Fluxbox , WarningLocaleModifiers ,
" Warning: cannot set locale modifiers " ,
" XSetLocaleModifiers returned false " ) < < endl ;
2001-12-11 20:47:02 +00:00
2002-08-14 23:03:07 +00:00
# ifdef HAVE_GETPID
2003-04-25 16:00:03 +00:00
m_fluxbox_pid = XInternAtom ( disp , " _BLACKBOX_PID " , False ) ;
2002-08-14 23:03:07 +00:00
# endif // HAVE_GETPID
2001-12-11 20:47:02 +00:00
2003-06-12 14:32:08 +00:00
2007-12-16 08:50:59 +00:00
// setup theme manager to have our style file ready to be scanned
FbTk : : ThemeManager : : instance ( ) . load ( getStyleFilename ( ) , getStyleOverlayFilename ( ) ) ;
2007-10-13 21:51:37 +00:00
// Create keybindings handler and load keys file
// Note: this needs to be done before creating screens
m_key . reset ( new Keys ) ;
2008-05-12 19:16:37 +00:00
m_key - > reconfigure ( ) ;
2007-10-13 21:51:37 +00:00
2005-03-16 22:51:54 +00:00
vector < int > screens ;
int i ;
2003-06-12 14:32:08 +00:00
2005-03-16 22:51:54 +00:00
// default is "use all screens"
for ( i = 0 ; i < ScreenCount ( disp ) ; i + + )
screens . push_back ( i ) ;
2003-05-12 04:28:05 +00:00
2005-03-16 22:51:54 +00:00
// find out, on what "screens" fluxbox should run
2005-11-22 21:09:43 +00:00
// FIXME(php-coder): maybe it worths moving this code to main.cc, where command line is parsed?
2005-03-16 22:51:54 +00:00
for ( i = 1 ; i < m_argc ; i + + ) {
if ( ! strcmp ( m_argv [ i ] , " -screen " ) ) {
if ( ( + + i ) > = m_argc ) {
2006-11-12 17:16:56 +00:00
cerr < < _FB_CONSOLETEXT ( main , ScreenRequiresArg ,
" error, -screen requires argument " ,
" the -screen option requires a file argument " ) < < endl ;
2008-01-25 07:21:55 +00:00
exit ( EXIT_FAILURE ) ;
2005-03-16 22:51:54 +00:00
}
2004-05-02 20:48:16 +00:00
2005-03-16 22:51:54 +00:00
// "all" is default
if ( ! strcmp ( m_argv [ i ] , " all " ) )
break ;
vector < string > vals ;
vector < int > scrtmp ;
int scrnr = 0 ;
FbTk : : StringUtil : : stringtok ( vals , m_argv [ i ] , " ,: " ) ;
2006-06-22 07:46:12 +00:00
for ( vector < string > : : iterator scrit = vals . begin ( ) ;
2005-03-16 22:51:54 +00:00
scrit ! = vals . end ( ) ; scrit + + ) {
scrnr = atoi ( scrit - > c_str ( ) ) ;
if ( scrnr > = 0 & & scrnr < ScreenCount ( disp ) )
scrtmp . push_back ( scrnr ) ;
}
2004-06-21 15:23:42 +00:00
2005-03-16 22:51:54 +00:00
if ( ! vals . empty ( ) )
swap ( scrtmp , screens ) ;
2002-12-01 13:42:15 +00:00
}
2005-03-16 22:51:54 +00:00
}
2006-06-22 07:46:12 +00:00
2007-01-01 01:44:35 +00:00
// create screens
for ( size_t s = 0 ; s < screens . size ( ) ; s + + ) {
char scrname [ 128 ] , altscrname [ 128 ] ;
sprintf ( scrname , " session.screen%d " , screens [ s ] ) ;
sprintf ( altscrname , " session.Screen%d " , screens [ s ] ) ;
BScreen * screen = new BScreen ( m_screen_rm . lock ( ) ,
scrname , altscrname ,
2007-03-03 23:27:16 +00:00
screens [ s ] , : : Layer : : NUM_LAYERS ) ;
2007-01-01 01:44:35 +00:00
// already handled
if ( ! screen - > isScreenManaged ( ) ) {
delete screen ;
continue ;
}
2003-12-03 00:33:30 +00:00
2007-01-01 01:44:35 +00:00
// add to our list
m_screen_list . push_back ( screen ) ;
}
2003-12-03 00:33:30 +00:00
2004-01-21 13:36:09 +00:00
if ( m_screen_list . empty ( ) ) {
2006-06-21 14:41:16 +00:00
throw _FB_CONSOLETEXT ( Fluxbox , ErrorNoScreens ,
2006-06-22 07:46:12 +00:00
" Couldn't find screens to manage. \n Make sure you don't have another window manager running. " ,
2006-05-20 15:08:14 +00:00
" Error message when no unmanaged screens found - usually means another window manager is running " ) ;
2002-12-01 13:42:15 +00:00
}
2001-12-11 20:47:02 +00:00
2007-01-03 18:59:43 +00:00
m_keyscreen = m_mousescreen = m_screen_list . front ( ) ;
2007-01-08 16:47:27 +00:00
# ifdef USE_NEWWMSPEC
addAtomHandler ( new Ewmh ( ) , " ewmh " ) ; // for Extended window manager atom support
# endif // USE_NEWWMSPEC
# ifdef USE_GNOME
addAtomHandler ( new Gnome ( ) , " gnome " ) ; // for gnome 1 atom support
# endif //USE_GNOME
2007-12-19 08:07:47 +00:00
// parse apps file after creating screens (so we can tell if it's a restart
// for [startup] items) but before creating windows
// this needs to be after ewmh and gnome, so state atoms don't get
// overwritten before they're applied
# ifdef REMEMBER
2008-01-02 21:41:50 +00:00
addAtomHandler ( new Remember ( ) , " remember " ) ; // for remembering window attribs
2007-12-19 08:07:47 +00:00
# endif // REMEMBER
2007-01-01 01:44:35 +00:00
// init all "screens"
ScreenList : : iterator it = m_screen_list . begin ( ) ;
ScreenList : : iterator it_end = m_screen_list . end ( ) ;
for ( ; it ! = it_end ; + + it )
initScreen ( * it ) ;
XAllowEvents ( disp , ReplayPointer , CurrentTime ) ;
2005-04-10 18:18:14 +00:00
//XSynchronize(disp, False);
2003-12-04 21:31:02 +00:00
sync ( false ) ;
2003-04-25 16:00:03 +00:00
2008-05-11 15:54:18 +00:00
m_reconfigure_wait = false ;
2004-09-11 12:33:14 +00:00
2003-07-18 15:40:55 +00:00
m_resourcemanager . unlock ( ) ;
2002-12-01 13:42:15 +00:00
ungrab ( ) ;
2006-06-22 07:46:12 +00:00
2010-03-17 15:35:07 +00:00
if ( m_resourcemanager . lockDepth ( ) ! = 0 ) {
fbdbg < < " --- resource manager lockdepth = " < < m_resourcemanager . lockDepth ( ) < < endl ;
}
2003-05-10 14:32:35 +00:00
m_starting = false ;
2004-10-21 10:18:40 +00:00
//
2003-12-19 00:35:08 +00:00
// For dumping theme items
// FbTk::ThemeManager::instance().listItems();
//
2003-12-19 03:58:36 +00:00
// m_resourcemanager.dump();
2004-07-14 23:39:29 +00:00
2001-12-11 20:47:02 +00:00
}
2002-09-07 20:25:39 +00:00
Fluxbox : : ~ Fluxbox ( ) {
2004-10-18 01:26:54 +00:00
2007-04-24 16:06:22 +00:00
// this needs to be destroyed before screens; otherwise, menus stored in
// key commands cause a segfault when the XLayerItem is destroyed
m_key . reset ( 0 ) ;
2008-09-21 10:02:49 +00:00
leaveAll ( ) ; // leave all connections
2006-04-24 13:34:14 +00:00
// destroy screens (after others, as they may do screen things)
while ( ! m_screen_list . empty ( ) ) {
delete m_screen_list . back ( ) ;
m_screen_list . pop_back ( ) ;
}
2008-01-13 01:49:50 +00:00
// destroy atomhandlers
for ( AtomHandlerContainerIt it = m_atomhandler . begin ( ) ;
it ! = m_atomhandler . end ( ) ;
it + + ) {
delete ( * it ) . first ;
}
m_atomhandler . clear ( ) ;
2001-12-11 20:47:02 +00:00
}
2005-03-16 22:51:54 +00:00
2007-01-01 01:44:35 +00:00
void Fluxbox : : initScreen ( BScreen * screen ) {
2006-06-22 07:46:12 +00:00
2005-03-16 22:51:54 +00:00
// now we can create menus (which needs this screen to be in screen_list)
screen - > initMenus ( ) ;
screen - > initWindows ( ) ;
// attach screen signals to this
2008-09-28 14:00:48 +00:00
join ( screen - > workspaceAreaSig ( ) ,
FbTk : : MemFun ( * this , & Fluxbox : : workspaceAreaChanged ) ) ;
2008-09-21 17:32:40 +00:00
2008-09-28 08:46:49 +00:00
join ( screen - > focusedWindowSig ( ) ,
FbTk : : MemFun ( * this , & Fluxbox : : focusedWindowChanged ) ) ;
2008-09-21 17:32:40 +00:00
join ( screen - > clientListSig ( ) ,
FbTk : : MemFun ( * this , & Fluxbox : : clientListChanged ) ) ;
2005-03-16 22:51:54 +00:00
2008-09-21 13:25:47 +00:00
join ( screen - > workspaceNamesSig ( ) ,
FbTk : : MemFun ( * this , & Fluxbox : : workspaceNamesChanged ) ) ;
2008-09-21 11:44:48 +00:00
join ( screen - > currentWorkspaceSig ( ) ,
FbTk : : MemFun ( * this , & Fluxbox : : workspaceChanged ) ) ;
join ( screen - > workspaceCountSig ( ) ,
FbTk : : MemFun ( * this , & Fluxbox : : workspaceCountChanged ) ) ;
2008-09-18 20:27:16 +00:00
2005-03-16 22:51:54 +00:00
// initiate atomhandler for screen specific stuff
for ( AtomHandlerContainerIt it = m_atomhandler . begin ( ) ;
it ! = m_atomhandler . end ( ) ;
it + + ) {
( * it ) . first - > initForScreen ( * screen ) ;
}
2006-02-18 20:19:22 +00:00
FocusControl : : revertFocus ( * screen ) ; // make sure focus style is correct
2005-03-16 22:51:54 +00:00
}
2003-05-10 14:32:35 +00:00
void Fluxbox : : eventLoop ( ) {
2003-10-09 16:48:09 +00:00
Display * disp = display ( ) ;
2003-05-10 14:43:45 +00:00
while ( ! m_shutdown ) {
2003-10-09 16:48:09 +00:00
if ( XPending ( disp ) ) {
2003-05-10 14:32:35 +00:00
XEvent e ;
2003-10-09 16:48:09 +00:00
XNextEvent ( disp , & e ) ;
2003-05-10 14:32:35 +00:00
2004-10-21 10:18:40 +00:00
if ( last_bad_window ! = None & & e . xany . window = = last_bad_window & &
2003-06-08 00:13:41 +00:00
e . type ! = DestroyNotify ) { // we must let the actual destroys through
2007-10-13 21:51:37 +00:00
if ( e . type = = FocusOut )
2008-01-01 18:29:36 +00:00
revertFocus ( ) ;
2007-10-13 21:51:37 +00:00
else
2010-03-17 15:35:07 +00:00
fbdbg < < " Fluxbox::eventLoop(): removing bad window from event queue " < < endl ;
2003-05-10 14:32:35 +00:00
} else {
last_bad_window = None ;
handleEvent ( & e ) ;
}
} else {
2003-10-09 16:48:09 +00:00
FbTk : : Timer : : updateTimers ( ConnectionNumber ( disp ) ) ; //handle all timers
2003-05-10 14:32:35 +00:00
}
}
}
bool Fluxbox : : validateWindow ( Window window ) const {
XEvent event ;
if ( XCheckTypedWindowEvent ( display ( ) , window , DestroyNotify , & event ) ) {
XPutBackEvent ( display ( ) , & event ) ;
return false ;
}
return true ;
}
void Fluxbox : : grab ( ) {
if ( ! m_server_grabs + + )
XGrabServer ( display ( ) ) ;
}
void Fluxbox : : ungrab ( ) {
if ( ! - - m_server_grabs )
XUngrabServer ( display ( ) ) ;
2004-07-14 23:39:29 +00:00
2003-05-10 14:32:35 +00:00
if ( m_server_grabs < 0 )
m_server_grabs = 0 ;
}
2003-04-14 15:28:52 +00:00
/**
2004-10-21 10:18:40 +00:00
setup the configutation files in
2003-04-14 15:28:52 +00:00
home directory
*/
2002-02-26 22:42:23 +00:00
void Fluxbox : : setupConfigFiles ( ) {
2008-04-25 08:36:26 +00:00
bool create_init = false , create_keys = false , create_menu = false ,
2008-06-20 03:48:26 +00:00
create_apps = false , create_overlay = false , create_windowmenu = false ;
2002-12-01 13:42:15 +00:00
2008-06-20 03:48:26 +00:00
string dirname = getDefaultDataFilename ( " " ) ;
string init_file = getDefaultDataFilename ( m_RC_INIT_FILE ) ;
string keys_file = getDefaultDataFilename ( " keys " ) ;
string menu_file = getDefaultDataFilename ( " menu " ) ;
string apps_file = getDefaultDataFilename ( " apps " ) ;
string overlay_file = getDefaultDataFilename ( " overlay " ) ;
string windowmenu_file = getDefaultDataFilename ( " windowmenu " ) ;
2002-12-01 13:42:15 +00:00
struct stat buf ;
// is file/dir already there?
if ( ! stat ( dirname . c_str ( ) , & buf ) ) {
2004-10-21 10:18:40 +00:00
2002-12-01 13:42:15 +00:00
// check if anything with those name exists, if not create new
2003-04-25 16:00:03 +00:00
if ( stat ( init_file . c_str ( ) , & buf ) )
create_init = true ;
if ( stat ( keys_file . c_str ( ) , & buf ) )
create_keys = true ;
if ( stat ( menu_file . c_str ( ) , & buf ) )
create_menu = true ;
2008-04-25 08:36:26 +00:00
if ( stat ( apps_file . c_str ( ) , & buf ) )
create_apps = true ;
2008-04-26 00:56:51 +00:00
if ( stat ( overlay_file . c_str ( ) , & buf ) )
create_overlay = true ;
2008-06-20 03:48:26 +00:00
if ( stat ( windowmenu_file . c_str ( ) , & buf ) )
create_windowmenu = true ;
2002-12-01 13:42:15 +00:00
} else {
2010-03-17 15:35:07 +00:00
fbdbg < < " Creating dir: " < < dirname . c_str ( ) < < endl ;
2004-06-07 11:46:05 +00:00
_FB_USES_NLS ;
2002-12-01 13:42:15 +00:00
// create directory with perm 700
if ( mkdir ( dirname . c_str ( ) , 0700 ) ) {
2006-06-21 14:41:16 +00:00
fprintf ( stderr , _FB_CONSOLETEXT ( Fluxbox , ErrorCreatingDirectory ,
2006-06-22 07:46:12 +00:00
" Can't create %s directory " ,
" Can't create a directory, one %s for directory name " ) . c_str ( ) ,
2005-04-29 02:53:34 +00:00
dirname . c_str ( ) ) ;
2004-06-07 11:46:05 +00:00
cerr < < endl ;
2004-10-21 10:18:40 +00:00
return ;
2002-12-01 13:42:15 +00:00
}
2004-10-21 10:18:40 +00:00
2002-12-01 13:42:15 +00:00
//mark creation of files
2008-08-13 09:05:31 +00:00
create_init = create_keys = create_menu = create_apps = create_overlay =
create_windowmenu = true ;
2002-12-01 13:42:15 +00:00
}
2003-08-12 21:00:54 +00:00
// copy key configuration
if ( create_keys )
2004-12-18 01:29:22 +00:00
FbTk : : FileUtil : : copyFile ( DEFAULTKEYSFILE , keys_file . c_str ( ) ) ;
2002-12-01 13:42:15 +00:00
2003-08-12 21:00:54 +00:00
// copy menu configuration
if ( create_menu )
2004-12-18 01:29:22 +00:00
FbTk : : FileUtil : : copyFile ( DEFAULTMENU , menu_file . c_str ( ) ) ;
2002-12-01 13:42:15 +00:00
2008-04-25 08:36:26 +00:00
// copy apps file
if ( create_apps )
FbTk : : FileUtil : : copyFile ( DEFAULT_APPSFILE , apps_file . c_str ( ) ) ;
2008-04-26 00:56:51 +00:00
// copy overlay file
if ( create_overlay )
FbTk : : FileUtil : : copyFile ( DEFAULT_OVERLAY , overlay_file . c_str ( ) ) ;
2003-08-12 21:00:54 +00:00
// copy init file
if ( create_init )
2004-12-18 01:29:22 +00:00
FbTk : : FileUtil : : copyFile ( DEFAULT_INITFILE , init_file . c_str ( ) ) ;
2002-12-01 13:42:15 +00:00
2008-06-20 03:48:26 +00:00
if ( create_windowmenu )
FbTk : : FileUtil : : copyFile ( DEFAULT_WINDOWMENU , windowmenu_file . c_str ( ) ) ;
2010-08-20 17:01:25 +00:00
# define CONFIG_VERSION 12
2007-02-09 18:13:01 +00:00
FbTk : : Resource < int > config_version ( m_resourcemanager , 0 ,
" session.configVersion " , " Session.ConfigVersion " ) ;
if ( * config_version < CONFIG_VERSION ) {
// configs are out of date, so run fluxbox-update_configs
2007-07-07 23:11:04 +00:00
string commandargs = realProgramName ( " fluxbox-update_configs " ) ;
commandargs + = " -rc " + init_file ;
2007-02-09 18:13:01 +00:00
# ifdef HAVE_GETPID
// add the fluxbox pid so fbuc can have us reload rc if necessary
pid_t bpid = getpid ( ) ;
char intbuff [ 64 ] ;
sprintf ( intbuff , " %d " , bpid ) ;
commandargs + = " -pid " ;
commandargs + = intbuff ;
# endif // HAVE_GETPID
FbCommands : : ExecuteCmd fbuc ( commandargs , 0 ) ;
fbuc . execute ( ) ;
}
2002-02-26 22:42:23 +00:00
}
2001-12-11 20:47:02 +00:00
2002-08-17 22:14:00 +00:00
void Fluxbox : : handleEvent ( XEvent * const e ) {
2004-06-07 11:46:05 +00:00
_FB_USES_NLS ;
2003-06-30 15:05:26 +00:00
m_last_event = * e ;
2001-12-11 20:47:02 +00:00
2003-03-22 05:13:08 +00:00
// it is possible (e.g. during moving) for a window
2004-10-21 10:18:40 +00:00
// to mask all events to go to it
2003-12-30 20:56:41 +00:00
if ( ( m_masked = = e - > xany . window ) & & m_masked_window ) {
if ( e - > type = = MotionNotify ) {
m_last_time = e - > xmotion . time ;
m_masked_window - > motionNotifyEvent ( e - > xmotion ) ;
2003-10-05 02:31:23 +00:00
return ;
2003-12-30 20:56:41 +00:00
} else if ( e - > type = = ButtonRelease ) {
e - > xbutton . window = m_masked_window - > fbWindow ( ) . window ( ) ;
}
2004-10-21 10:18:40 +00:00
2002-12-01 13:42:15 +00:00
}
2003-10-05 02:31:23 +00:00
2003-12-21 22:42:31 +00:00
// update key/mouse screen and last time before we enter other eventhandlers
2003-12-19 03:58:36 +00:00
if ( e - > type = = KeyPress | |
e - > type = = KeyRelease ) {
m_keyscreen = searchScreen ( e - > xkey . root ) ;
} else if ( e - > type = = ButtonPress | |
e - > type = = ButtonRelease | |
e - > type = = MotionNotify ) {
2003-12-21 22:42:31 +00:00
if ( e - > type = = MotionNotify )
m_last_time = e - > xmotion . time ;
else
m_last_time = e - > xbutton . time ;
2003-12-19 03:58:36 +00:00
m_mousescreen = searchScreen ( e - > xbutton . root ) ;
} else if ( e - > type = = EnterNotify | |
e - > type = = LeaveNotify ) {
2003-12-21 22:42:31 +00:00
m_last_time = e - > xcrossing . time ;
2003-12-19 03:58:36 +00:00
m_mousescreen = searchScreen ( e - > xcrossing . root ) ;
2005-05-10 16:29:00 +00:00
} else if ( e - > type = = PropertyNotify ) {
2003-12-21 22:42:31 +00:00
m_last_time = e - > xproperty . time ;
2005-05-10 16:29:00 +00:00
// check transparency atoms if it's a root pm
2006-06-22 07:46:12 +00:00
2005-05-10 16:29:00 +00:00
BScreen * screen = searchScreen ( e - > xproperty . window ) ;
if ( screen ) {
2007-07-03 18:50:53 +00:00
screen - > propertyNotify ( e - > xproperty . atom ) ;
2005-05-10 16:29:00 +00:00
}
}
2003-12-21 22:42:31 +00:00
2002-12-03 23:58:06 +00:00
// try FbTk::EventHandler first
FbTk : : EventManager : : instance ( ) - > handleEvent ( * e ) ;
2002-12-01 13:42:15 +00:00
switch ( e - > type ) {
case ButtonRelease :
case ButtonPress :
2004-10-21 10:18:40 +00:00
break ;
2003-04-25 16:00:03 +00:00
case ConfigureRequest : {
2004-10-21 10:18:40 +00:00
if ( ! searchWindow ( e - > xconfigurerequest . window ) ) {
2003-04-25 16:00:03 +00:00
grab ( ) ;
if ( validateWindow ( e - > xconfigurerequest . window ) ) {
XWindowChanges xwc ;
xwc . x = e - > xconfigurerequest . x ;
xwc . y = e - > xconfigurerequest . y ;
xwc . width = e - > xconfigurerequest . width ;
xwc . height = e - > xconfigurerequest . height ;
xwc . border_width = e - > xconfigurerequest . border_width ;
xwc . sibling = e - > xconfigurerequest . above ;
xwc . stack_mode = e - > xconfigurerequest . detail ;
XConfigureWindow ( FbTk : : App : : instance ( ) - > display ( ) ,
e - > xconfigurerequest . window ,
e - > xconfigurerequest . value_mask , & xwc ) ;
2002-12-01 13:42:15 +00:00
}
2001-12-11 20:47:02 +00:00
2003-04-25 16:00:03 +00:00
ungrab ( ) ;
2004-10-21 10:18:40 +00:00
} // else already handled in FluxboxWindow::handleEvent
2003-04-25 16:00:03 +00:00
}
2002-12-02 23:49:56 +00:00
break ;
2003-01-05 22:41:21 +00:00
case MapRequest : {
2003-07-23 10:43:30 +00:00
2010-03-17 15:35:07 +00:00
fbdbg < < " MapRequest for 0x " < < hex < < e - > xmaprequest . window < < dec < < endl ;
2002-12-02 23:49:56 +00:00
2003-07-28 15:06:36 +00:00
WinClient * winclient = searchWindow ( e - > xmaprequest . window ) ;
2003-01-05 22:41:21 +00:00
2003-07-28 15:06:36 +00:00
if ( ! winclient ) {
2004-01-18 12:42:47 +00:00
BScreen * screen = 0 ;
int screen_num ;
XWindowAttributes attr ;
// find screen
if ( XGetWindowAttributes ( display ( ) ,
e - > xmaprequest . window ,
& attr ) & & attr . screen ! = 0 ) {
screen_num = XScreenNumberOfScreen ( attr . screen ) ;
2004-10-21 10:18:40 +00:00
2004-01-18 12:42:47 +00:00
// find screen
2004-02-27 12:32:54 +00:00
ScreenList : : iterator screen_it = find_if ( m_screen_list . begin ( ) ,
m_screen_list . end ( ) ,
FbTk : : CompareEqual < BScreen > ( & BScreen : : screenNumber , screen_num ) ) ;
if ( screen_it ! = m_screen_list . end ( ) )
screen = * screen_it ;
2004-01-18 12:42:47 +00:00
}
// try with parent if we failed to find screen num
if ( screen = = 0 )
screen = searchScreen ( e - > xmaprequest . parent ) ;
2004-10-21 10:18:40 +00:00
2004-01-18 12:42:47 +00:00
if ( screen = = 0 ) {
2006-06-21 14:41:16 +00:00
cerr < < " Fluxbox " < < _FB_CONSOLETEXT ( Fluxbox , CantMapWindow , " Warning! Could not find screen to map window on! " , " " ) < < endl ;
2004-01-18 12:42:47 +00:00
} else
2007-04-01 21:42:01 +00:00
screen - > createWindow ( e - > xmaprequest . window ) ;
2003-05-11 15:24:09 +00:00
2003-07-28 15:06:36 +00:00
} else {
2007-04-01 21:42:01 +00:00
// we don't handle MapRequest in FluxboxWindow::handleEvent
if ( winclient - > fbwindow ( ) )
winclient - > fbwindow ( ) - > mapRequestEvent ( e - > xmaprequest ) ;
2003-01-05 22:41:21 +00:00
}
2003-07-28 15:06:36 +00:00
2003-01-05 22:41:21 +00:00
}
2002-12-02 23:49:56 +00:00
break ;
2004-07-14 23:39:29 +00:00
case MapNotify :
2003-04-27 00:36:28 +00:00
// handled directly in FluxboxWindow::handleEvent
2004-07-14 23:39:29 +00:00
break ;
2002-12-01 13:42:15 +00:00
case UnmapNotify :
handleUnmapNotify ( e - > xunmap ) ;
2004-10-21 10:18:40 +00:00
break ;
2003-04-15 00:50:25 +00:00
case MappingNotify :
// Update stored modifier mapping
2010-03-17 15:35:07 +00:00
fbdbg < < " MappingNotify " < < endl ;
2005-05-06 09:22:53 +00:00
if ( e - > xmapping . request = = MappingKeyboard
| | e - > xmapping . request = = MappingModifier ) {
XRefreshKeyboardMapping ( & e - > xmapping ) ;
FbTk : : KeyUtil : : instance ( ) . init ( ) ; // reinitialise the key utils
// reconfigure keys (if the mapping changes, they don't otherwise update
2008-11-02 00:03:32 +00:00
m_key - > regrab ( ) ;
2005-05-06 09:22:53 +00:00
}
2003-04-15 00:50:25 +00:00
break ;
2002-12-01 13:42:15 +00:00
case CreateNotify :
2002-08-16 11:09:25 +00:00
break ;
2002-12-01 13:42:15 +00:00
case DestroyNotify : {
2004-10-21 10:18:40 +00:00
WinClient * winclient = searchWindow ( e - > xdestroywindow . window ) ;
2003-07-28 15:06:36 +00:00
if ( winclient ! = 0 ) {
FluxboxWindow * win = winclient - > fbwindow ( ) ;
if ( win )
2003-04-14 15:28:52 +00:00
win - > destroyNotifyEvent ( e - > xdestroywindow ) ;
2004-10-21 10:18:40 +00:00
}
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
}
2002-12-02 23:49:56 +00:00
break ;
2004-10-21 10:18:40 +00:00
case MotionNotify :
2003-12-21 16:23:59 +00:00
m_last_time = e - > xmotion . time ;
2002-12-02 23:49:56 +00:00
break ;
2003-06-18 13:51:37 +00:00
case PropertyNotify : {
2003-04-25 16:00:03 +00:00
m_last_time = e - > xproperty . time ;
2003-07-28 15:06:36 +00:00
WinClient * winclient = searchWindow ( e - > xproperty . window ) ;
if ( winclient = = 0 )
2003-06-18 13:51:37 +00:00
break ;
// most of them are handled in FluxboxWindow::handleEvent
2004-10-21 10:18:40 +00:00
// but some special cases like ewmh propertys needs to be checked
for ( AtomHandlerContainerIt it = m_atomhandler . begin ( ) ;
2004-04-18 21:16:06 +00:00
it ! = m_atomhandler . end ( ) ; it + + ) {
if ( ( * it ) . first - > propertyNotify ( * winclient , e - > xproperty . atom ) )
2003-06-18 13:51:37 +00:00
break ;
}
} break ;
2002-12-01 13:42:15 +00:00
case EnterNotify : {
2004-07-14 23:39:29 +00:00
2003-04-25 16:00:03 +00:00
m_last_time = e - > xcrossing . time ;
2002-12-03 23:58:06 +00:00
BScreen * screen = 0 ;
2002-12-01 13:42:15 +00:00
if ( e - > xcrossing . mode = = NotifyGrab )
break ;
if ( ( e - > xcrossing . window = = e - > xcrossing . root ) & &
( screen = searchScreen ( e - > xcrossing . window ) ) ) {
2003-05-15 23:30:07 +00:00
screen - > imageControl ( ) . installRootColormap ( ) ;
2001-12-11 20:47:02 +00:00
2003-02-22 15:10:43 +00:00
}
2004-10-21 10:18:40 +00:00
2003-04-25 16:00:03 +00:00
} break ;
2002-12-01 13:42:15 +00:00
case LeaveNotify :
2003-04-25 16:00:03 +00:00
m_last_time = e - > xcrossing . time ;
2002-12-02 23:49:56 +00:00
break ;
2002-12-01 13:42:15 +00:00
case Expose :
2002-12-02 23:49:56 +00:00
break ;
2003-04-15 00:50:25 +00:00
case KeyRelease :
2002-12-01 13:42:15 +00:00
case KeyPress :
2002-02-06 17:12:09 +00:00
break ;
2002-12-01 13:42:15 +00:00
case ColormapNotify : {
BScreen * screen = searchScreen ( e - > xcolormap . window ) ;
if ( screen ! = 0 ) {
screen - > setRootColormapInstalled ( ( e - > xcolormap . state = =
2003-04-25 16:00:03 +00:00
ColormapInstalled ) ? true : false ) ;
2002-12-01 13:42:15 +00:00
}
2003-04-25 16:00:03 +00:00
} break ;
2002-12-01 13:42:15 +00:00
case FocusIn : {
2003-12-09 12:28:24 +00:00
2003-09-14 11:23:48 +00:00
// a grab is something of a pseudo-focus event, so we ignore
// them, here we ignore some window receiving it
if ( e - > xfocus . mode = = NotifyGrab | |
2008-09-11 21:01:36 +00:00
e - > xfocus . mode = = NotifyUngrab | |
2003-12-09 12:28:24 +00:00
e - > xfocus . detail = = NotifyPointer | |
e - > xfocus . detail = = NotifyInferior )
2002-12-01 13:42:15 +00:00
break ;
2008-01-01 18:29:36 +00:00
if ( FbTk : : Menu : : focused ( ) & &
FbTk : : Menu : : focused ( ) - > window ( ) = = e - > xfocus . window ) {
m_keyscreen = findScreen ( FbTk : : Menu : : focused ( ) - > screenNumber ( ) ) ;
2008-01-31 14:37:52 +00:00
FocusControl : : setFocusedWindow ( 0 ) ;
2008-01-01 18:29:36 +00:00
break ;
}
2003-07-28 15:06:36 +00:00
WinClient * winclient = searchWindow ( e - > xfocus . window ) ;
2008-01-31 14:37:52 +00:00
if ( winclient )
m_keyscreen = & winclient - > screen ( ) ;
2008-01-01 18:29:36 +00:00
FocusControl : : setFocusedWindow ( winclient ) ;
2003-12-09 12:28:24 +00:00
2002-12-01 13:42:15 +00:00
} break ;
2003-07-01 20:29:44 +00:00
case FocusOut : {
2003-09-14 11:23:48 +00:00
// and here we ignore some window losing the special grab focus
2003-09-14 11:56:11 +00:00
if ( e - > xfocus . mode = = NotifyGrab | |
2003-12-09 12:28:24 +00:00
e - > xfocus . detail = = NotifyPointer | |
e - > xfocus . detail = = NotifyInferior )
2003-07-01 20:29:44 +00:00
break ;
2003-12-09 12:28:24 +00:00
2003-07-28 15:06:36 +00:00
WinClient * winclient = searchWindow ( e - > xfocus . window ) ;
2008-01-13 00:47:40 +00:00
if ( ( winclient = = FocusControl : : focusedWindow ( ) | |
FocusControl : : focusedWindow ( ) = = 0 ) & &
2004-03-03 12:29:31 +00:00
// we don't unfocus a moving window
2008-01-13 00:47:40 +00:00
( ! winclient | | ! winclient - > fbwindow ( ) | |
! winclient - > fbwindow ( ) - > isMoving ( ) ) )
2008-01-01 18:29:36 +00:00
revertFocus ( ) ;
2003-07-01 20:29:44 +00:00
}
2002-02-06 17:12:09 +00:00
break ;
2002-12-01 13:42:15 +00:00
case ClientMessage :
handleClientMessage ( e - > xclient ) ;
2002-02-06 17:12:09 +00:00
break ;
2002-12-01 13:42:15 +00:00
default : {
2004-10-21 10:18:40 +00:00
2003-05-12 04:23:31 +00:00
# ifdef HAVE_RANDR
if ( e - > type = = m_randr_event_type ) {
2008-09-03 18:00:40 +00:00
# ifdef HAVE_RANDR1_2
2007-06-28 18:35:35 +00:00
XRRUpdateConfiguration ( e ) ;
2008-09-03 18:00:40 +00:00
# endif
2003-05-12 04:23:31 +00:00
// update root window size in screen
BScreen * scr = searchScreen ( e - > xany . window ) ;
if ( scr ! = 0 )
2004-10-21 10:18:40 +00:00
scr - > updateSize ( ) ;
2003-05-14 14:37:06 +00:00
}
2003-05-12 04:23:31 +00:00
# endif // HAVE_RANDR
2002-12-02 23:49:56 +00:00
}
2003-05-10 14:32:35 +00:00
2002-12-01 13:42:15 +00:00
}
2002-02-06 17:12:09 +00:00
}
2001-12-11 20:47:02 +00:00
2002-02-17 18:43:30 +00:00
void Fluxbox : : handleUnmapNotify ( XUnmapEvent & ue ) {
2002-12-01 13:42:15 +00:00
BScreen * screen = searchScreen ( ue . event ) ;
2006-06-22 07:46:12 +00:00
2009-01-30 15:47:24 +00:00
if ( screen ) {
/* Ignore all EnterNotify events until the pointer actually moves */
screen - > focusControl ( ) . ignoreAtPointer ( ) ;
}
2005-01-10 09:04:46 +00:00
if ( ue . event ! = ue . window & & ( ! screen | | ! ue . send_event ) ) {
2002-12-01 13:42:15 +00:00
return ;
2005-01-10 09:04:46 +00:00
}
2008-08-16 11:36:08 +00:00
WinClient * winclient = searchWindow ( ue . window ) ;
2003-04-15 08:54:40 +00:00
2008-08-16 11:36:08 +00:00
if ( winclient ! = 0 ) {
2002-12-01 13:42:15 +00:00
2008-08-16 11:36:08 +00:00
FluxboxWindow * win = winclient - > fbwindow ( ) ;
if ( ! win ) {
delete winclient ;
return ;
2004-10-21 10:18:40 +00:00
}
2005-01-10 09:04:46 +00:00
2008-08-16 11:36:08 +00:00
// this should delete client and adjust m_focused_window if necessary
win - > unmapNotifyEvent ( ue ) ;
2005-01-10 09:04:46 +00:00
// according to http://tronche.com/gui/x/icccm/sec-4.html#s-4.1.4
2006-06-22 07:46:12 +00:00
// a XWithdrawWindow is
2005-01-10 09:04:46 +00:00
// 1) unmapping the window (which leads to the upper branch
// 2) sends an synthetic unampevent (which is handled below)
} else if ( screen & & ue . send_event ) {
XDeleteProperty ( display ( ) , ue . window , FbAtoms : : instance ( ) - > getWMStateAtom ( ) ) ;
2005-01-11 04:56:29 +00:00
XUngrabButton ( display ( ) , AnyButton , AnyModifier , ue . window ) ;
2002-12-01 13:42:15 +00:00
}
2002-02-17 18:43:30 +00:00
}
2003-04-14 15:28:52 +00:00
/**
* Handles XClientMessageEvent
*/
2002-02-06 17:12:09 +00:00
void Fluxbox : : handleClientMessage ( XClientMessageEvent & ce ) {
2004-01-19 18:33:05 +00:00
2004-01-21 15:30:27 +00:00
# ifdef DEBUG
2004-01-11 16:10:51 +00:00
char * atom = 0 ;
2003-10-14 16:23:16 +00:00
if ( ce . message_type )
atom = XGetAtomName ( FbTk : : App : : instance ( ) - > display ( ) , ce . message_type ) ;
2010-03-17 15:35:07 +00:00
fbdbg < < __FILE__ < < " ( " < < __LINE__ < < " ): ClientMessage. data.l[0]=0x " < < hex < < ce . data . l [ 0 ] < <
2003-10-14 16:23:16 +00:00
" message_type=0x " < < ce . message_type < < dec < < " = \" " < < atom < < " \" " < < endl ;
if ( ce . message_type & & atom ) XFree ( ( char * ) atom ) ;
2004-01-21 15:30:27 +00:00
# endif // DEBUG
2004-01-19 18:33:05 +00:00
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
if ( ce . format ! = 32 )
return ;
2004-10-21 10:18:40 +00:00
2003-04-15 12:22:52 +00:00
if ( ce . message_type = = m_fbatoms - > getWMChangeStateAtom ( ) ) {
2003-07-28 15:06:36 +00:00
WinClient * winclient = searchWindow ( ce . window ) ;
if ( ! winclient | | ! winclient - > fbwindow ( ) | | ! winclient - > validateClient ( ) )
2002-12-01 13:42:15 +00:00
return ;
if ( ce . data . l [ 0 ] = = IconicState )
2003-07-28 15:06:36 +00:00
winclient - > fbwindow ( ) - > iconify ( ) ;
2002-12-01 13:42:15 +00:00
if ( ce . data . l [ 0 ] = = NormalState )
2003-07-28 15:06:36 +00:00
winclient - > fbwindow ( ) - > deiconify ( ) ;
2002-12-01 13:42:15 +00:00
} else {
2003-07-28 15:06:36 +00:00
WinClient * winclient = searchWindow ( ce . window ) ;
2002-12-01 13:42:15 +00:00
BScreen * screen = searchScreen ( ce . window ) ;
2004-10-21 10:18:40 +00:00
// note: we dont need screen nor winclient to be non-null,
2003-08-15 13:57:18 +00:00
// it's up to the atomhandler to check that
2004-10-21 10:18:40 +00:00
for ( AtomHandlerContainerIt it = m_atomhandler . begin ( ) ;
2004-04-18 21:16:06 +00:00
it ! = m_atomhandler . end ( ) ; it + + ) {
( * it ) . first - > checkClientMessage ( ce , screen , winclient ) ;
2002-12-01 13:42:15 +00:00
}
2003-08-15 13:57:18 +00:00
2002-12-01 13:42:15 +00:00
}
2001-12-11 20:47:02 +00:00
}
2003-04-14 15:28:52 +00:00
/// handle system signals
2002-11-27 22:00:19 +00:00
void Fluxbox : : handleSignal ( int signum ) {
2004-06-07 11:46:05 +00:00
_FB_USES_NLS ;
2002-12-01 13:42:15 +00:00
static int re_enter = 0 ;
switch ( signum ) {
case SIGCHLD : // we don't want the child process to kill us
2006-07-03 01:56:59 +00:00
// more than one process may have terminated
while ( waitpid ( - 1 , 0 , WNOHANG | WUNTRACED ) > 0 ) ;
2002-12-01 13:42:15 +00:00
break ;
case SIGHUP :
2005-02-02 15:22:58 +00:00
restart ( ) ;
2002-12-01 13:42:15 +00:00
break ;
case SIGUSR1 :
2005-02-02 15:22:58 +00:00
load_rc ( ) ;
2002-12-01 13:42:15 +00:00
break ;
case SIGUSR2 :
2007-07-07 23:11:04 +00:00
reconfigure ( ) ;
2002-12-01 13:42:15 +00:00
break ;
case SIGSEGV :
abort ( ) ;
break ;
case SIGFPE :
case SIGINT :
2007-08-04 17:14:13 +00:00
case SIGPIPE :
2002-12-01 13:42:15 +00:00
case SIGTERM :
shutdown ( ) ;
break ;
default :
fprintf ( stderr ,
2008-01-11 07:41:22 +00:00
_FB_CONSOLETEXT ( BaseDisplay , SignalCaught , " %s: signal %d caught \n " , " signal catch debug message. Include %s for Command<void> and %d for signal number " ) . c_str ( ) ,
2003-05-10 14:32:35 +00:00
m_argv [ 0 ] , signum ) ;
2002-12-01 13:42:15 +00:00
2003-05-10 14:32:35 +00:00
if ( ! m_starting & & ! re_enter ) {
2002-12-01 13:42:15 +00:00
re_enter = 1 ;
2006-06-21 14:41:16 +00:00
cerr < < _FB_CONSOLETEXT ( BaseDisplay , ShuttingDown , " Shutting Down \n " , " Quitting because of signal, end with newline " ) ;
2002-12-01 13:42:15 +00:00
shutdown ( ) ;
}
2002-01-18 01:23:54 +00:00
2004-10-21 10:18:40 +00:00
2006-06-21 14:41:16 +00:00
cerr < < _FB_CONSOLETEXT ( BaseDisplay , Aborting , " Aborting... dumping core \n " , " Aboring and dumping core, end with newline " ) ;
2002-12-01 13:42:15 +00:00
abort ( ) ;
break ;
}
2002-09-07 20:25:39 +00:00
}
2002-01-18 01:23:54 +00:00
2002-08-14 00:01:10 +00:00
2002-09-07 20:25:39 +00:00
void Fluxbox : : update ( FbTk : : Subject * changedsub ) {
2003-04-14 15:28:52 +00:00
//TODO: fix signaling, this does not look good
2007-10-13 21:51:37 +00:00
FluxboxWindow * fbwin = 0 ;
WinClient * client = 0 ;
2003-03-03 21:51:13 +00:00
if ( typeid ( * changedsub ) = = typeid ( FluxboxWindow : : WinSubject ) ) {
2002-12-01 13:42:15 +00:00
FluxboxWindow : : WinSubject * winsub = dynamic_cast < FluxboxWindow : : WinSubject * > ( changedsub ) ;
2007-10-13 21:51:37 +00:00
fbwin = & winsub - > win ( ) ;
} else if ( typeid ( * changedsub ) = = typeid ( Focusable : : FocusSubject ) ) {
Focusable : : FocusSubject * winsub = dynamic_cast < Focusable : : FocusSubject * > ( changedsub ) ;
fbwin = winsub - > win ( ) . fbwindow ( ) ;
if ( typeid ( winsub - > win ( ) ) = = typeid ( WinClient ) )
client = dynamic_cast < WinClient * > ( & winsub - > win ( ) ) ;
}
2003-04-14 15:28:52 +00:00
2007-10-13 21:51:37 +00:00
if ( fbwin & & & fbwin - > stateSig ( ) = = changedsub ) { // state signal
for ( AtomHandlerContainerIt it = m_atomhandler . begin ( ) ;
it ! = m_atomhandler . end ( ) ; + + it ) {
if ( ( * it ) . first - > update ( ) )
( * it ) . first - > updateState ( * fbwin ) ;
}
// if window changed to iconic state
// add to icon list
if ( fbwin - > isIconic ( ) ) {
fbwin - > screen ( ) . addIcon ( fbwin ) ;
Workspace * space = fbwin - > screen ( ) . getWorkspace ( fbwin - > workspaceNumber ( ) ) ;
if ( space ! = 0 )
space - > removeWindow ( fbwin , true ) ;
}
2003-04-14 15:28:52 +00:00
2007-10-13 21:51:37 +00:00
if ( fbwin - > isStuck ( ) ) {
// if we're sticky then reassociate window
// to all workspaces
BScreen & scr = fbwin - > screen ( ) ;
if ( scr . currentWorkspaceID ( ) ! = fbwin - > workspaceNumber ( ) ) {
scr . reassociateWindow ( fbwin ,
scr . currentWorkspaceID ( ) ,
true ) ;
2003-02-02 16:32:41 +00:00
}
2007-10-13 21:51:37 +00:00
}
} else if ( fbwin & & & fbwin - > layerSig ( ) = = changedsub ) { // layer signal
AtomHandlerContainerIt it = m_atomhandler . begin ( ) ;
for ( ; it ! = m_atomhandler . end ( ) ; + + it ) {
if ( ( * it ) . first - > update ( ) )
( * it ) . first - > updateLayer ( * fbwin ) ;
}
} else if ( fbwin & & & fbwin - > dieSig ( ) = = changedsub ) { // window death signal
AtomHandlerContainerIt it = m_atomhandler . begin ( ) ;
for ( ; it ! = m_atomhandler . end ( ) ; + + it ) {
if ( ( * it ) . first - > update ( ) )
( * it ) . first - > updateFrameClose ( * fbwin ) ;
}
2006-06-22 07:46:12 +00:00
2007-10-13 21:51:37 +00:00
// make sure each workspace get this
BScreen & scr = fbwin - > screen ( ) ;
scr . removeWindow ( fbwin ) ;
if ( FocusControl : : focusedFbWindow ( ) = = fbwin )
FocusControl : : setFocusedFbWindow ( 0 ) ;
} else if ( fbwin & & & fbwin - > workspaceSig ( ) = = changedsub ) { // workspace signal
for ( AtomHandlerContainerIt it = m_atomhandler . begin ( ) ;
it ! = m_atomhandler . end ( ) ; + + it ) {
if ( ( * it ) . first - > update ( ) )
( * it ) . first - > updateWorkspace ( * fbwin ) ;
}
} else if ( client & & & client - > dieSig ( ) = = changedsub ) { // client death
for ( AtomHandlerContainerIt it = m_atomhandler . begin ( ) ;
it ! = m_atomhandler . end ( ) ; + + it ) {
if ( ( * it ) . first - > update ( ) )
( * it ) . first - > updateClientClose ( * client ) ;
}
2004-11-20 18:12:51 +00:00
2007-10-13 21:51:37 +00:00
BScreen & screen = client - > screen ( ) ;
2003-08-11 16:06:51 +00:00
2007-10-13 21:51:37 +00:00
// At this point, we trust that this client is no longer in the
// client list of its frame (but it still has reference to the frame)
// We also assume that any remaining active one is the last focused one
2004-10-21 10:18:40 +00:00
2007-10-13 21:51:37 +00:00
// This is where we revert focus on window close
// NOWHERE ELSE!!!
if ( FocusControl : : focusedWindow ( ) = = client ) {
FocusControl : : unfocusWindow ( * client ) ;
// make sure nothing else uses this window before focus reverts
FocusControl : : setFocusedWindow ( 0 ) ;
2008-01-13 00:47:40 +00:00
} else if ( FocusControl : : expectingFocus ( ) = = client ) {
FocusControl : : setExpectingFocus ( 0 ) ;
revertFocus ( ) ;
2007-10-13 21:51:37 +00:00
}
2007-11-09 04:25:53 +00:00
screen . removeClient ( * client ) ;
2002-12-01 13:42:15 +00:00
}
2002-09-07 20:25:39 +00:00
}
void Fluxbox : : attachSignals ( FluxboxWindow & win ) {
2002-12-01 13:42:15 +00:00
win . hintSig ( ) . attach ( this ) ;
win . stateSig ( ) . attach ( this ) ;
win . workspaceSig ( ) . attach ( this ) ;
2003-02-02 16:32:41 +00:00
win . layerSig ( ) . attach ( this ) ;
2003-03-03 21:51:13 +00:00
win . dieSig ( ) . attach ( this ) ;
2004-10-21 10:18:40 +00:00
for ( AtomHandlerContainerIt it = m_atomhandler . begin ( ) ;
2004-04-18 21:16:06 +00:00
it ! = m_atomhandler . end ( ) ; + + it ) {
( * it ) . first - > setupFrame ( win ) ;
2003-07-04 01:03:41 +00:00
}
}
void Fluxbox : : attachSignals ( WinClient & winclient ) {
winclient . dieSig ( ) . attach ( this ) ;
2004-10-21 10:18:40 +00:00
for ( AtomHandlerContainerIt it = m_atomhandler . begin ( ) ;
2004-04-18 21:16:06 +00:00
it ! = m_atomhandler . end ( ) ; + + it ) {
( * it ) . first - > setupClient ( winclient ) ;
2002-12-01 13:42:15 +00:00
}
2001-12-11 20:47:02 +00:00
}
BScreen * Fluxbox : : searchScreen ( Window window ) {
2004-02-27 12:32:54 +00:00
2004-10-21 10:18:40 +00:00
ScreenList : : iterator it = m_screen_list . begin ( ) ;
2003-04-25 16:00:03 +00:00
ScreenList : : iterator it_end = m_screen_list . end ( ) ;
2002-12-01 13:42:15 +00:00
for ( ; it ! = it_end ; + + it ) {
2003-08-24 11:19:45 +00:00
if ( * it & & ( * it ) - > rootWindow ( ) = = window )
2004-02-27 12:32:54 +00:00
return * it ;
2002-12-01 13:42:15 +00:00
}
2003-04-14 15:28:52 +00:00
return 0 ;
2001-12-11 20:47:02 +00:00
}
2004-04-18 21:16:06 +00:00
2006-10-30 19:31:15 +00:00
AtomHandler * Fluxbox : : getAtomHandler ( const string & name ) {
2004-04-18 21:16:06 +00:00
if ( name ! = " " ) {
2005-05-02 12:10:01 +00:00
using namespace FbTk ;
AtomHandlerContainerIt it = find_if ( m_atomhandler . begin ( ) ,
m_atomhandler . end ( ) ,
Compose ( bind2nd ( equal_to < string > ( ) , name ) ,
Select2nd < AtomHandlerContainer : : value_type > ( ) ) ) ;
if ( it ! = m_atomhandler . end ( ) )
return ( * it ) . first ;
2003-04-25 16:00:03 +00:00
}
2004-04-18 21:16:06 +00:00
return 0 ;
}
2006-10-30 19:31:15 +00:00
void Fluxbox : : addAtomHandler ( AtomHandler * atomh , const string & name ) {
2008-08-14 05:53:38 +00:00
m_atomhandler [ atomh ] = name ;
2003-04-25 16:00:03 +00:00
}
void Fluxbox : : removeAtomHandler ( AtomHandler * atomh ) {
2004-04-18 21:16:06 +00:00
for ( AtomHandlerContainerIt it = m_atomhandler . begin ( ) ;
2004-10-21 10:18:40 +00:00
it ! = m_atomhandler . end ( ) ;
2004-04-18 21:16:06 +00:00
+ + it ) {
if ( ( * it ) . first = = atomh ) {
2003-04-25 16:00:03 +00:00
m_atomhandler . erase ( it ) ;
return ;
}
}
}
2001-12-11 20:47:02 +00:00
2003-07-28 15:06:36 +00:00
WinClient * Fluxbox : : searchWindow ( Window window ) {
2005-05-02 12:10:01 +00:00
WinClientMap : : iterator it = m_window_search . find ( window ) ;
2003-10-14 16:23:16 +00:00
if ( it ! = m_window_search . end ( ) )
2003-07-28 15:06:36 +00:00
return it - > second ;
2003-10-14 16:23:16 +00:00
2005-05-02 12:10:01 +00:00
WindowMap : : iterator git = m_window_search_group . find ( window ) ;
2003-07-28 15:06:36 +00:00
return git = = m_window_search_group . end ( ) ? 0 : & git - > second - > winClient ( ) ;
2001-12-11 20:47:02 +00:00
}
2003-07-28 15:06:36 +00:00
/* Not implemented until we know how it'll be used
* Recall that this refers to ICCCM groups , not fluxbox tabgroups
* See ICCCM 4.1 .11 for details
*/
/*
WinClient * Fluxbox : : searchGroup ( Window window ) {
2001-12-11 20:47:02 +00:00
}
2003-07-28 15:06:36 +00:00
*/
2001-12-11 20:47:02 +00:00
2003-07-28 15:06:36 +00:00
void Fluxbox : : saveWindowSearch ( Window window , WinClient * data ) {
2003-04-25 16:00:03 +00:00
m_window_search [ window ] = data ;
2001-12-11 20:47:02 +00:00
}
2003-07-28 15:06:36 +00:00
/* some windows relate to the whole group */
void Fluxbox : : saveWindowSearchGroup ( Window window , FluxboxWindow * data ) {
m_window_search_group [ window ] = data ;
}
2001-12-11 20:47:02 +00:00
2003-07-28 15:06:36 +00:00
void Fluxbox : : saveGroupSearch ( Window window , WinClient * data ) {
2009-10-03 11:38:41 +00:00
m_group_search . insert ( pair < const Window , WinClient * > ( window , data ) ) ;
2001-12-11 20:47:02 +00:00
}
void Fluxbox : : removeWindowSearch ( Window window ) {
2003-04-25 16:00:03 +00:00
m_window_search . erase ( window ) ;
2001-12-11 20:47:02 +00:00
}
2003-07-28 15:06:36 +00:00
void Fluxbox : : removeWindowSearchGroup ( Window window ) {
m_window_search_group . erase ( window ) ;
}
2001-12-11 20:47:02 +00:00
void Fluxbox : : removeGroupSearch ( Window window ) {
2003-04-25 16:00:03 +00:00
m_group_search . erase ( window ) ;
2001-12-11 20:47:02 +00:00
}
2003-04-25 16:00:03 +00:00
/// restarts fluxbox
2001-12-11 20:47:02 +00:00
void Fluxbox : : restart ( const char * prog ) {
2002-12-01 13:42:15 +00:00
shutdown ( ) ;
2001-12-11 20:47:02 +00:00
2004-10-18 01:26:54 +00:00
m_restarting = true ;
2002-12-01 13:42:15 +00:00
if ( prog ) {
2004-10-18 01:26:54 +00:00
m_restart_argument = prog ;
2002-12-01 13:42:15 +00:00
}
2001-12-11 20:47:02 +00:00
}
2003-04-25 16:00:03 +00:00
/// prepares fluxbox for a shutdown
2002-10-15 20:41:08 +00:00
void Fluxbox : : shutdown ( ) {
2004-08-27 17:24:49 +00:00
if ( m_shutdown )
return ;
m_shutdown = true ;
2001-12-11 20:47:02 +00:00
2003-04-25 16:00:03 +00:00
XSetInputFocus ( FbTk : : App : : instance ( ) - > display ( ) , PointerRoot , None , CurrentTime ) ;
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
//send shutdown to all screens
2004-10-21 10:18:40 +00:00
for_each ( m_screen_list . begin ( ) ,
2004-10-18 01:26:54 +00:00
m_screen_list . end ( ) , mem_fun ( & BScreen : : shutdown ) ) ;
2003-08-24 11:19:45 +00:00
2003-12-04 21:31:02 +00:00
sync ( false ) ;
2001-12-11 20:47:02 +00:00
}
2003-04-25 16:00:03 +00:00
/// saves resources
2002-10-15 20:41:08 +00:00
void Fluxbox : : save_rc ( ) {
2004-06-07 11:46:05 +00:00
_FB_USES_NLS ;
2002-12-01 13:42:15 +00:00
XrmDatabase new_blackboxrc = 0 ;
2004-10-21 10:18:40 +00:00
2002-12-01 13:42:15 +00:00
char rc_string [ 1024 ] ;
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
string dbfile ( getRcFilename ( ) ) ;
2004-10-21 10:18:40 +00:00
2004-01-21 13:36:09 +00:00
if ( ! dbfile . empty ( ) ) {
2002-12-01 13:42:15 +00:00
m_resourcemanager . save ( dbfile . c_str ( ) , dbfile . c_str ( ) ) ;
m_screen_rm . save ( dbfile . c_str ( ) , dbfile . c_str ( ) ) ;
} else
2006-06-21 14:41:16 +00:00
cerr < < _FB_CONSOLETEXT ( Fluxbox , BadRCFile , " rc filename is invalid! " , " Bad settings file " ) < < endl ;
2004-10-21 10:18:40 +00:00
2003-04-25 16:00:03 +00:00
ScreenList : : iterator it = m_screen_list . begin ( ) ;
ScreenList : : iterator it_end = m_screen_list . end ( ) ;
2002-12-01 13:42:15 +00:00
//Save screen resources
for ( ; it ! = it_end ; + + it ) {
BScreen * screen = * it ;
2003-05-15 12:00:46 +00:00
int screen_number = screen - > screenNumber ( ) ;
2003-08-11 16:06:51 +00:00
2002-12-01 13:42:15 +00:00
// these are static, but may not be saved in the users resource file,
// writing these resources will allow the user to edit them at a later
// time... but loading the defaults before saving allows us to rewrite the
// users changes...
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
// write out the users workspace names
sprintf ( rc_string , " session.screen%d.workspaceNames: " , screen_number ) ;
string workspaces_string ( rc_string ) ;
2002-02-17 18:43:30 +00:00
2007-02-17 17:39:00 +00:00
const vector < string > names = screen - > getWorkspaceNames ( ) ;
for ( size_t i = 0 ; i < names . size ( ) ; i + + ) {
workspaces_string . append ( FbTk : : FbStringUtil : : FbStrToLocale ( names [ i ] ) ) ;
2002-12-01 13:42:15 +00:00
workspaces_string . append ( " , " ) ;
}
2002-01-21 02:04:23 +00:00
2002-12-01 13:42:15 +00:00
XrmPutLineResource ( & new_blackboxrc , workspaces_string . c_str ( ) ) ;
2004-10-21 10:18:40 +00:00
2002-12-01 13:42:15 +00:00
}
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
XrmDatabase old_blackboxrc = XrmGetFileDatabase ( dbfile . c_str ( ) ) ;
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
XrmMergeDatabases ( new_blackboxrc , & old_blackboxrc ) ; //merge database together
XrmPutFileDatabase ( old_blackboxrc , dbfile . c_str ( ) ) ;
XrmDestroyDatabase ( old_blackboxrc ) ;
2010-03-17 15:35:07 +00:00
fbdbg < < __FILE__ < < " ( " < < __LINE__ < < " ): ------------ SAVING DONE " < < endl ;
2001-12-11 20:47:02 +00:00
}
2003-04-25 16:00:03 +00:00
/// @return filename of resource file
2002-08-14 23:03:07 +00:00
string Fluxbox : : getRcFilename ( ) {
2008-06-20 03:48:26 +00:00
if ( m_rc_file . empty ( ) )
return getDefaultDataFilename ( m_RC_INIT_FILE ) ;
2003-04-25 16:00:03 +00:00
return m_rc_file ;
2001-12-11 20:47:02 +00:00
}
2003-04-25 16:00:03 +00:00
/// Provides default filename of data file
2008-06-20 03:48:26 +00:00
string Fluxbox : : getDefaultDataFilename ( const char * name ) const {
return ( getenv ( " HOME " ) + string ( " /. " ) + m_RC_PATH + string ( " / " ) + name ) ;
2002-05-29 06:22:31 +00:00
}
2003-04-25 16:00:03 +00:00
/// loads resources
2002-10-15 20:41:08 +00:00
void Fluxbox : : load_rc ( ) {
2004-06-07 11:46:05 +00:00
_FB_USES_NLS ;
2002-12-01 13:42:15 +00:00
//get resource filename
string dbfile ( getRcFilename ( ) ) ;
2004-01-21 13:36:09 +00:00
if ( ! dbfile . empty ( ) ) {
2002-12-01 13:42:15 +00:00
if ( ! m_resourcemanager . load ( dbfile . c_str ( ) ) ) {
2006-06-21 14:41:16 +00:00
cerr < < _FB_CONSOLETEXT ( Fluxbox , CantLoadRCFile , " Failed to load database " , " Failed trying to read rc file " ) < < " : " < < dbfile < < endl ;
cerr < < _FB_CONSOLETEXT ( Fluxbox , CantLoadRCFileTrying , " Retrying with " , " Retrying rc file loading with (the following file) " ) < < " : " < < DEFAULT_INITFILE < < endl ;
2002-12-01 13:42:15 +00:00
if ( ! m_resourcemanager . load ( DEFAULT_INITFILE ) )
2006-06-21 14:41:16 +00:00
cerr < < _FB_CONSOLETEXT ( Fluxbox , CantLoadRCFile , " Failed to load database " , " " ) < < " : " < < DEFAULT_INITFILE < < endl ;
2002-12-01 13:42:15 +00:00
}
} else {
if ( ! m_resourcemanager . load ( DEFAULT_INITFILE ) )
2006-06-21 14:41:16 +00:00
cerr < < _FB_CONSOLETEXT ( Fluxbox , CantLoadRCFile , " Failed to load database " , " " ) < < " : " < < DEFAULT_INITFILE < < endl ;
2002-12-01 13:42:15 +00:00
}
2004-10-21 10:18:40 +00:00
if ( m_rc_menufile - > empty ( ) )
2003-12-19 00:35:08 +00:00
m_rc_menufile . setDefaultValue ( ) ;
2004-09-12 14:56:20 +00:00
2007-01-06 19:03:33 +00:00
FbTk : : Transparent : : usePseudoTransparent ( * m_rc_pseudotrans ) ;
2004-10-21 10:18:40 +00:00
2004-01-21 13:36:09 +00:00
if ( ! m_rc_slitlistfile - > empty ( ) ) {
2002-12-01 13:42:15 +00:00
* m_rc_slitlistfile = StringUtil : : expandFilename ( * m_rc_slitlistfile ) ;
} else {
2008-06-20 03:48:26 +00:00
string filename = getDefaultDataFilename ( " slitlist " ) ;
2002-12-01 13:42:15 +00:00
m_rc_slitlistfile . setFromString ( filename . c_str ( ) ) ;
}
if ( * m_rc_colors_per_channel < 2 )
* m_rc_colors_per_channel = 2 ;
else if ( * m_rc_colors_per_channel > 6 )
* m_rc_colors_per_channel = 6 ;
2004-10-21 10:18:40 +00:00
if ( m_rc_stylefile - > empty ( ) )
2002-12-01 13:42:15 +00:00
* m_rc_stylefile = DEFAULTSTYLE ;
2002-01-18 01:23:54 +00:00
}
2003-04-15 12:22:52 +00:00
void Fluxbox : : load_rc ( BScreen & screen ) {
2002-12-01 13:42:15 +00:00
//get resource filename
2004-06-07 11:46:05 +00:00
_FB_USES_NLS ;
2002-12-01 13:42:15 +00:00
string dbfile ( getRcFilename ( ) ) ;
2004-10-21 10:18:40 +00:00
2002-12-01 13:42:15 +00:00
XrmDatabaseHelper database ;
2002-01-18 01:23:54 +00:00
2002-12-01 13:42:15 +00:00
database = XrmGetFileDatabase ( dbfile . c_str ( ) ) ;
if ( database = = 0 )
database = XrmGetFileDatabase ( DEFAULT_INITFILE ) ;
2004-10-21 10:18:40 +00:00
2002-12-01 13:42:15 +00:00
XrmValue value ;
char * value_type , name_lookup [ 1024 ] , class_lookup [ 1024 ] ;
2003-05-15 12:00:46 +00:00
int screen_number = screen . screenNumber ( ) ;
2002-12-01 13:42:15 +00:00
2003-04-15 12:22:52 +00:00
screen . removeWorkspaceNames ( ) ;
2004-10-21 10:18:40 +00:00
2002-12-01 13:42:15 +00:00
sprintf ( name_lookup , " session.screen%d.workspaceNames " , screen_number ) ;
sprintf ( class_lookup , " Session.Screen%d.WorkspaceNames " , screen_number ) ;
if ( XrmGetResource ( * database , name_lookup , class_lookup , & value_type ,
& value ) ) {
2005-07-04 18:18:32 +00:00
2005-04-27 09:52:30 +00:00
string values ( value . addr ) ;
BScreen : : WorkspaceNames names ;
2006-06-22 07:46:12 +00:00
2005-04-27 09:52:30 +00:00
StringUtil : : removeTrailingWhitespace ( values ) ;
StringUtil : : removeFirstWhitespace ( values ) ;
StringUtil : : stringtok < BScreen : : WorkspaceNames > ( names , values , " , " ) ;
BScreen : : WorkspaceNames : : iterator it ;
for ( it = names . begin ( ) ; it ! = names . end ( ) ; it + + ) {
if ( ! ( * it ) . empty ( ) & & ( * it ) ! = " " )
screen . addWorkspaceName ( ( * it ) . c_str ( ) ) ;
2002-12-01 13:42:15 +00:00
}
2005-11-16 22:08:05 +00:00
2002-12-01 13:42:15 +00:00
}
2004-01-21 13:36:09 +00:00
if ( ! dbfile . empty ( ) ) {
2003-08-22 21:38:58 +00:00
if ( ! m_screen_rm . load ( dbfile . c_str ( ) ) ) {
2006-06-21 14:41:16 +00:00
cerr < < _FB_CONSOLETEXT ( Fluxbox , CantLoadRCFile , " Failed to load database " , " Failed trying to read rc file " ) < < " : " < < dbfile < < endl ;
cerr < < _FB_CONSOLETEXT ( Fluxbox , CantLoadRCFileTrying , " Retrying with " , " Retrying rc file loading with (the following file) " ) < < " : " < < DEFAULT_INITFILE < < endl ;
2003-08-22 21:38:58 +00:00
if ( ! m_screen_rm . load ( DEFAULT_INITFILE ) )
2006-06-21 14:41:16 +00:00
cerr < < _FB_CONSOLETEXT ( Fluxbox , CantLoadRCFile , " Failed to load database " , " " ) < < " : " < < DEFAULT_INITFILE < < endl ;
2003-08-22 21:38:58 +00:00
}
} else {
if ( ! m_screen_rm . load ( DEFAULT_INITFILE ) )
2006-06-21 14:41:16 +00:00
cerr < < _FB_CONSOLETEXT ( Fluxbox , CantLoadRCFile , " Failed to load database " , " " ) < < " : " < < DEFAULT_INITFILE < < endl ;
2003-08-22 21:38:58 +00:00
}
2001-12-11 20:47:02 +00:00
}
2002-08-14 23:03:07 +00:00
void Fluxbox : : reconfigure ( ) {
2008-10-01 03:49:04 +00:00
setupConfigFiles ( ) ;
2007-07-07 23:11:04 +00:00
load_rc ( ) ;
2003-04-25 16:00:03 +00:00
m_reconfigure_wait = true ;
2003-12-19 13:37:28 +00:00
m_reconfig_timer . start ( ) ;
2001-12-11 20:47:02 +00:00
}
2002-08-14 23:03:07 +00:00
void Fluxbox : : real_reconfigure ( ) {
2001-12-11 20:47:02 +00:00
2007-01-06 19:03:33 +00:00
FbTk : : Transparent : : usePseudoTransparent ( * m_rc_pseudotrans ) ;
2004-03-23 09:19:57 +00:00
ScreenList : : iterator screen_it = m_screen_list . begin ( ) ;
2004-04-05 18:31:51 +00:00
ScreenList : : iterator screen_it_end = m_screen_list . end ( ) ;
2004-03-23 09:19:57 +00:00
for ( ; screen_it ! = screen_it_end ; + + screen_it )
load_rc ( * ( * screen_it ) ) ;
2003-08-24 11:19:45 +00:00
// reconfigure all screens
for_each ( m_screen_list . begin ( ) , m_screen_list . end ( ) , mem_fun ( & BScreen : : reconfigure ) ) ;
2003-05-13 00:20:49 +00:00
2002-12-01 13:42:15 +00:00
//reconfigure keys
2008-05-12 19:16:37 +00:00
m_key - > reconfigure ( ) ;
2001-12-11 20:47:02 +00:00
2006-04-23 14:51:04 +00:00
// and atomhandlers
for ( AtomHandlerContainerIt it = m_atomhandler . begin ( ) ;
it ! = m_atomhandler . end ( ) ;
it + + ) {
( * it ) . first - > reconfigure ( ) ;
}
2001-12-11 20:47:02 +00:00
}
2004-05-02 20:48:16 +00:00
BScreen * Fluxbox : : findScreen ( int id ) {
ScreenList : : iterator it = m_screen_list . begin ( ) ;
ScreenList : : iterator it_end = m_screen_list . end ( ) ;
for ( ; it ! = it_end ; + + it ) {
if ( ( * it ) - > screenNumber ( ) = = id )
break ;
}
if ( it = = m_screen_list . end ( ) )
return 0 ;
return * it ;
}
2001-12-11 20:47:02 +00:00
2003-08-11 16:06:51 +00:00
void Fluxbox : : timed_reconfigure ( ) {
2003-04-25 16:00:03 +00:00
if ( m_reconfigure_wait )
2002-12-01 13:42:15 +00:00
real_reconfigure ( ) ;
2001-12-11 20:47:02 +00:00
2008-05-11 15:54:18 +00:00
m_reconfigure_wait = false ;
2001-12-11 20:47:02 +00:00
}
2008-01-01 18:29:36 +00:00
void Fluxbox : : revertFocus ( ) {
bool revert = m_keyscreen & & ! m_showing_dialog ;
2007-03-10 18:08:37 +00:00
2008-01-01 18:29:36 +00:00
if ( revert ) {
// see if there are any more focus events in the queue
XEvent ev ;
2008-01-13 00:47:40 +00:00
while ( XCheckMaskEvent ( display ( ) , FocusChangeMask , & ev ) )
2008-01-01 18:29:36 +00:00
handleEvent ( & ev ) ;
2008-01-13 00:47:40 +00:00
if ( FocusControl : : focusedWindow ( ) | | FocusControl : : expectingFocus ( ) )
2008-01-01 18:29:36 +00:00
return ; // already handled
2007-03-10 18:08:37 +00:00
2008-01-01 18:29:36 +00:00
Window win ;
int blah ;
XGetInputFocus ( display ( ) , & win , & blah ) ;
// we only want to revert focus if it's left dangling, as some other
// application may have set the focus to an unmanaged window
2008-01-13 00:47:40 +00:00
if ( win ! = None & & win ! = PointerRoot & & ! searchWindow ( win ) & &
2008-01-01 18:29:36 +00:00
win ! = m_keyscreen - > rootWindow ( ) . window ( ) )
revert = false ;
}
2007-03-10 18:08:37 +00:00
2008-01-01 18:29:36 +00:00
if ( revert )
FocusControl : : revertFocus ( * m_keyscreen ) ;
else
FocusControl : : setFocusedWindow ( 0 ) ;
2006-07-23 09:51:54 +00:00
}
2006-02-18 20:19:22 +00:00
bool Fluxbox : : validateClient ( const WinClient * client ) const {
2006-06-22 07:46:12 +00:00
WinClientMap : : const_iterator it =
2006-02-18 20:19:22 +00:00
find_if ( m_window_search . begin ( ) ,
m_window_search . end ( ) ,
Compose ( bind2nd ( equal_to < WinClient * > ( ) , client ) ,
Select2nd < WinClientMap : : value_type > ( ) ) ) ;
return it ! = m_window_search . end ( ) ;
}
2003-06-25 06:02:53 +00:00
2006-06-18 21:23:24 +00:00
void Fluxbox : : updateFrameExtents ( FluxboxWindow & win ) {
AtomHandlerContainerIt it = m_atomhandler . begin ( ) ;
AtomHandlerContainerIt it_end = m_atomhandler . end ( ) ;
for ( ; it ! = it_end ; + + it ) {
( * it ) . first - > updateFrameExtents ( win ) ;
}
}
2008-09-18 20:27:16 +00:00
void Fluxbox : : workspaceCountChanged ( BScreen & screen ) {
for ( AtomHandlerContainerIt it = m_atomhandler . begin ( ) ;
it ! = m_atomhandler . end ( ) ; + + it ) {
if ( ( * it ) . first - > update ( ) )
( * it ) . first - > updateWorkspaceCount ( screen ) ;
}
}
2008-09-21 11:44:48 +00:00
void Fluxbox : : workspaceChanged ( BScreen & screen ) {
for ( AtomHandlerContainerIt it = m_atomhandler . begin ( ) ;
it ! = m_atomhandler . end ( ) ; + + it ) {
if ( ( * it ) . first - > update ( ) )
( * it ) . first - > updateCurrentWorkspace ( screen ) ;
}
}
2008-09-21 13:25:47 +00:00
void Fluxbox : : workspaceNamesChanged ( BScreen & screen ) {
for ( AtomHandlerContainerIt it = m_atomhandler . begin ( ) ;
it ! = m_atomhandler . end ( ) ; + + it ) {
if ( ( * it ) . first - > update ( ) )
( * it ) . first - > updateWorkspaceNames ( screen ) ;
}
}
2008-09-21 17:32:40 +00:00
void Fluxbox : : clientListChanged ( BScreen & screen ) {
for ( AtomHandlerContainerIt it = m_atomhandler . begin ( ) ;
it ! = m_atomhandler . end ( ) ; + + it ) {
if ( ( * it ) . first - > update ( ) )
( * it ) . first - > updateClientList ( screen ) ;
}
}
2008-09-28 08:46:49 +00:00
void Fluxbox : : focusedWindowChanged ( BScreen & screen ,
FluxboxWindow * win ,
WinClient * client ) {
for ( AtomHandlerContainerIt it = m_atomhandler . begin ( ) ;
it ! = m_atomhandler . end ( ) ; it + + ) {
( * it ) . first - > updateFocusedWindow ( screen , client ? client - > window ( ) : 0 ) ;
}
}
2008-09-28 14:00:48 +00:00
void Fluxbox : : workspaceAreaChanged ( BScreen & screen ) {
for ( AtomHandlerContainerIt it = m_atomhandler . begin ( ) ;
it ! = m_atomhandler . end ( ) ; + + it ) {
if ( ( * it ) . first - > update ( ) )
( * it ) . first - > updateWorkarea ( screen ) ;
}
}