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.
2004-11-19 11:37:27 +00:00
// $Id$
2002-01-09 14:07:09 +00:00
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"
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"
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 SLIT
# include "Slit.hh"
# endif // SLIT
# 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
2003-06-25 13:07:34 +00:00
# ifdef USE_TOOLBAR
# include "Toolbar.hh"
2003-12-03 00:33:30 +00:00
# else
class Toolbar { } ;
2003-06-25 13:07:34 +00:00
# endif // USE_TOOLBAR
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
2003-05-11 22:19:17 +00:00
# ifdef TIME_WITH_SYS_TIME
2002-10-25 21:17:15 +00:00
# include <sys/time.h>
# include <time.h>
2001-12-11 20:47:02 +00:00
# else // !TIME_WITH_SYS_TIME
2003-05-11 22:19:17 +00:00
# ifdef HAVE_SYS_TIME_H
2002-10-25 21:17:15 +00:00
# include <sys/time.h>
# else // !HAVE_SYS_TIME_H
# include <time.h>
# endif // HAVE_SYS_TIME_H
2001-12-11 20:47:02 +00:00
# endif // TIME_WITH_SYS_TIME
2002-08-14 00:01:10 +00:00
# include <sys/wait.h>
2001-12-11 20:47:02 +00:00
# include <iostream>
# include <string>
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 ;
# ifdef DEBUG
using std : : hex ;
using std : : dec ;
# endif // DEBUG
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
2003-04-25 16:00:03 +00:00
Fluxbox : : Fluxbox ( int argc , char * * argv , const char * dpy_name , const char * rcfilename )
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-02-02 16:32:41 +00:00
m_rc_numlayers ( m_resourcemanager , 13 , " session.numLayers " , " Session.NumLayers " ) ,
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 " ) ,
2005-11-16 22:48:35 +00:00
m_rc_styleoverlayfile ( m_resourcemanager , " ~/.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 " ) ,
2005-01-12 06:16:03 +00:00
m_rc_slitlistfile ( m_resourcemanager , " ~/.fluxbox/slitlist " , " session.slitlistFile " , " Session.SlitlistFile " ) ,
m_rc_groupfile ( m_resourcemanager , " ~/.fluxbox/groups " , " session.groupFile " , " Session.GroupFile " ) ,
2004-10-19 17:23:08 +00:00
m_rc_appsfile ( m_resourcemanager , " ~/.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-06-22 07:46:12 +00:00
m_rc_mod_key ( m_resourcemanager , " Mod1 " , " session.modKey " , " Session.ModKey " ) ,
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_watching_screen ( 0 ) , m_watch_keyrelease ( 0 ) ,
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-23 09:51:54 +00:00
m_revert_screen ( 0 ) ,
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 ) ,
2003-05-11 22:19:17 +00:00
m_RC_PATH ( " 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 ) ;
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".
FbTk : : RefCount < FbTk : : Command > reconfig_cmd ( new FbTk : : SimpleCommand < Fluxbox > ( * this , & Fluxbox : : timed_reconfigure ) ) ;
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
// set a timer to revert focus on FocusOut, in case no FocusIn arrives
FbTk : : RefCount < FbTk : : Command > revert_cmd ( new FbTk : : SimpleCommand < Fluxbox > ( * this , & Fluxbox : : revert_focus ) ) ;
m_revert_timer . setCommand ( revert_cmd ) ;
m_revert_timer . setTimeout ( to ) ;
m_revert_timer . fireOnce ( true ) ;
2005-04-26 01:41:55 +00:00
// 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 ( ) ;
2003-04-25 16:00:03 +00:00
// setup atom handlers before we create any windows
2003-04-26 05:42:36 +00:00
# ifdef REMEMBER
2004-04-18 21:16:06 +00:00
addAtomHandler ( new Remember ( ) , " remember " ) ; // for remembering window attribs
2003-04-26 05:42:36 +00:00
# endif // REMEMBER
2004-11-20 18:43:55 +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
2002-08-18 11:01:52 +00:00
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
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 ;
2005-03-16 22:51:54 +00:00
exit ( 1 ) ;
}
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
2005-03-16 22:51:54 +00:00
// init all "screens"
2006-04-02 21:37:44 +00:00
for ( size_t s = 0 ; s < screens . size ( ) ; s + + )
2006-03-20 11:31:24 +00:00
initScreen ( screens [ s ] ) ;
2006-06-22 07:46:12 +00:00
2004-04-26 09:25:42 +00:00
XAllowEvents ( disp , ReplayPointer , CurrentTime ) ;
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
2005-03-16 22:51:54 +00:00
m_keyscreen = m_mousescreen = m_screen_list . front ( ) ;
2005-11-16 22:08:05 +00:00
2003-08-11 20:59:58 +00:00
// setup theme manager to have our style file ready to be scanned
2005-11-16 22:08:05 +00:00
FbTk : : ThemeManager : : instance ( ) . load ( getStyleFilename ( ) , getStyleOverlayFilename ( ) ) ;
2003-08-11 16:06:51 +00:00
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
m_reconfigure_wait = m_reread_menu_wait = false ;
2004-09-11 12:33:14 +00:00
2004-10-21 10:18:40 +00:00
// Create keybindings handler and load keys file
2006-04-12 15:51:37 +00:00
m_key . reset ( new Keys ) ;
m_key - > load ( StringUtil : : expandFilename ( * m_rc_keyfile ) . c_str ( ) ) ;
2001-12-11 20:47:02 +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
2003-07-18 15:40:55 +00:00
# ifdef DEBUG
2004-10-21 10:18:40 +00:00
if ( m_resourcemanager . lockDepth ( ) ! = 0 )
2003-07-18 15:40:55 +00:00
cerr < < " --- resource manager lockdepth = " < < m_resourcemanager . lockDepth ( ) < < endl ;
# endif //DEBUG
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
# ifdef USE_TOOLBAR
// finally, show toolbar
Toolbars : : iterator toolbar_it = m_toolbars . begin ( ) ;
Toolbars : : iterator toolbar_it_end = m_toolbars . end ( ) ;
for ( ; toolbar_it ! = toolbar_it_end ; + + toolbar_it )
( * toolbar_it ) - > updateVisibleState ( ) ;
# endif // USE_TOOLBAR
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
2003-12-03 00:33:30 +00:00
// destroy toolbars
while ( ! m_toolbars . empty ( ) ) {
delete m_toolbars . back ( ) ;
m_toolbars . pop_back ( ) ;
}
2002-12-01 13:42:15 +00:00
// destroy atomhandlers
2004-04-18 21:16:06 +00:00
for ( AtomHandlerContainerIt it = m_atomhandler . begin ( ) ;
it ! = m_atomhandler . end ( ) ;
it + + ) {
delete ( * it ) . first ;
2002-12-01 13:42:15 +00:00
}
2004-11-20 18:12:51 +00:00
m_atomhandler . clear ( ) ;
2003-12-03 00:33:30 +00:00
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 ( ) ;
}
2004-10-21 10:18:40 +00:00
clearMenuFilenames ( ) ;
2001-12-11 20:47:02 +00:00
}
2005-03-16 22:51:54 +00:00
int Fluxbox : : initScreen ( int scrnr ) {
2006-06-22 07:46:12 +00:00
2005-03-16 22:51:54 +00:00
Display * disp = display ( ) ;
char scrname [ 128 ] , altscrname [ 128 ] ;
sprintf ( scrname , " session.screen%d " , scrnr ) ;
sprintf ( altscrname , " session.Screen%d " , scrnr ) ;
BScreen * screen = new BScreen ( m_screen_rm . lock ( ) ,
scrname , altscrname ,
scrnr , getNumberOfLayers ( ) ) ;
// already handled
if ( ! screen - > isScreenManaged ( ) ) {
delete screen ;
return 0 ;
}
2006-06-22 07:46:12 +00:00
2005-03-16 22:51:54 +00:00
// add to our list
m_screen_list . push_back ( screen ) ;
// now we can create menus (which needs this screen to be in screen_list)
screen - > initMenus ( ) ;
# ifdef HAVE_GETPID
pid_t bpid = getpid ( ) ;
screen - > rootWindow ( ) . changeProperty ( getFluxboxPidAtom ( ) , XA_CARDINAL ,
sizeof ( pid_t ) * 8 , PropModeReplace ,
( unsigned char * ) & bpid , 1 ) ;
# endif // HAVE_GETPID
# ifdef HAVE_RANDR
// setup RANDR for this screens root window
// we need to determine if we should use old randr select input function or not
# ifdef X_RRScreenChangeSelectInput
// use old set randr event
XRRScreenChangeSelectInput ( disp , screen - > rootWindow ( ) . window ( ) , True ) ;
# else
XRRSelectInput ( disp , screen - > rootWindow ( ) . window ( ) ,
RRScreenChangeNotifyMask ) ;
# endif // X_RRScreenChangeSelectInput
# endif // HAVE_RANDR
# ifdef USE_TOOLBAR
m_toolbars . push_back ( new Toolbar ( * screen ,
* screen - > layerManager ( ) .
2006-02-20 21:04:35 +00:00
getLayer ( : : Layer : : NORMAL ) ) ) ;
2005-03-16 22:51:54 +00:00
# endif // USE_TOOLBAR
// must do this after toolbar is created
screen - > initWindows ( ) ;
// attach screen signals to this
screen - > currentWorkspaceSig ( ) . attach ( this ) ;
screen - > workspaceCountSig ( ) . attach ( this ) ;
screen - > workspaceNamesSig ( ) . attach ( this ) ;
screen - > workspaceAreaSig ( ) . attach ( this ) ;
screen - > clientListSig ( ) . attach ( this ) ;
// 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
# ifdef SLIT
if ( screen - > slit ( ) )
screen - > slit ( ) - > show ( ) ;
# endif // SLIT
return 1 ;
}
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
2003-05-10 14:32:35 +00:00
# ifdef DEBUG
2003-05-13 11:43:44 +00:00
cerr < < " Fluxbox::eventLoop(): removing bad window from event queue " < < endl ;
2003-05-10 14:32:35 +00:00
# endif // DEBUG
} 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 ( ) {
2003-04-25 16:00:03 +00:00
bool create_init = false , create_keys = false , create_menu = false ;
2002-12-01 13:42:15 +00:00
2003-08-12 21:00:54 +00:00
string dirname = getenv ( " HOME " ) + string ( " /. " ) + string ( m_RC_PATH ) + " / " ;
2003-04-25 16:00:03 +00:00
string init_file , keys_file , menu_file , slitlist_file ;
2003-05-11 22:19:17 +00:00
init_file = dirname + m_RC_INIT_FILE ;
keys_file = dirname + " keys " ;
menu_file = dirname + " menu " ;
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 ;
2002-12-01 13:42:15 +00:00
} else {
2002-10-15 20:41:08 +00:00
# ifdef DEBUG
2002-12-01 13:42:15 +00:00
cerr < < __FILE__ < < " ( " < < __LINE__ < < " ): Creating dir: " < < dirname . c_str ( ) < < endl ;
2002-10-15 20:41:08 +00:00
# endif // DEBUG
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
2003-04-25 16:00:03 +00:00
create_init = create_keys = create_menu = 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
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
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 ) {
FbTk : : FbPixmap : : rootwinPropertyNotify ( screen - > screenNumber ( ) , e - > xproperty . atom ) ;
}
}
2003-12-21 22:42:31 +00:00
2004-01-16 11:28:00 +00:00
// we need to check focus out for menus before
// we call FbTk eventhandler
// so we can get FbTk::Menu::focused() before it sets to 0
2004-10-21 10:18:40 +00:00
if ( e - > type = = FocusOut & &
2004-01-16 18:07:40 +00:00
e - > xfocus . mode ! = NotifyGrab & &
e - > xfocus . detail ! = NotifyPointer & &
e - > xfocus . detail ! = NotifyInferior & &
2004-01-16 11:28:00 +00:00
FbTk : : Menu : : focused ( ) ! = 0 & &
FbTk : : Menu : : focused ( ) - > window ( ) = = e - > xfocus . window ) {
2004-01-16 18:07:40 +00:00
2004-01-16 11:38:30 +00:00
// find screen num
ScreenList : : iterator it = m_screen_list . begin ( ) ;
ScreenList : : iterator it_end = m_screen_list . end ( ) ;
for ( ; it ! = it_end ; + + it ) {
2004-10-21 10:18:40 +00:00
if ( ( * it ) - > screenNumber ( ) = =
2004-01-16 11:38:30 +00:00
FbTk : : Menu : : focused ( ) - > fbwindow ( ) . screenNumber ( ) ) {
2006-07-23 13:30:46 +00:00
FocusControl : : revertFocus ( * * it ) ;
2004-01-16 11:38:30 +00:00
break ; // found the screen, no more search
2004-01-16 11:28:00 +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 :
handleButtonEvent ( e - > xbutton ) ;
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
2002-08-16 11:09:25 +00:00
# ifdef DEBUG
2003-01-05 22:41:21 +00:00
cerr < < " MapRequest for 0x " < < hex < < e - > xmaprequest . window < < dec < < endl ;
2004-10-21 10:18:40 +00:00
2002-08-04 15:00:50 +00:00
# endif // DEBUG
2002-12-02 23:49:56 +00:00
2003-07-28 15:06:36 +00:00
WinClient * winclient = searchWindow ( e - > xmaprequest . window ) ;
FluxboxWindow * win = 0 ;
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
win = screen - > createWindow ( e - > xmaprequest . window ) ;
2003-05-11 15:24:09 +00:00
2003-07-28 15:06:36 +00:00
} else {
win = winclient - > fbwindow ( ) ;
2003-01-05 22:41:21 +00:00
}
2003-07-28 15:06:36 +00:00
2003-04-25 16:00:03 +00:00
// we don't handle MapRequest in FluxboxWindow::handleEvent
2003-04-16 14:43:06 +00:00
if ( win )
2003-04-16 10:49:59 +00:00
win - > mapRequestEvent ( e - > xmaprequest ) ;
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
# ifdef DEBUG
cerr < < __FILE__ < < " ( " < < __FUNCTION__ < < " ): MappingNotify " < < endl ;
2004-10-21 10:18:40 +00:00
# endif // DEBUG
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
m_key - > reconfigure ( StringUtil : : expandFilename ( * m_rc_keyfile ) . c_str ( ) ) ;
}
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 ) ;
2003-07-28 15:06:36 +00:00
delete winclient ;
2004-10-21 10:18:40 +00:00
2003-07-28 15:06:36 +00:00
if ( win & & win - > numClients ( ) = = 0 )
delete win ;
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 :
handleKeyEvent ( e - > xkey ) ;
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 | |
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 ;
2003-07-28 15:06:36 +00:00
WinClient * winclient = searchWindow ( e - > xfocus . window ) ;
2006-02-18 20:19:22 +00:00
if ( winclient & & FocusControl : : focusedWindow ( ) ! = winclient )
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 ) ;
if ( winclient = = 0 & & FbTk : : Menu : : focused ( ) = = 0 ) {
2003-07-01 20:29:44 +00:00
# ifdef DEBUG
cerr < < __FILE__ < < " ( " < < __FUNCTION__ < < " ) Focus out is not a FluxboxWindow !! " < < endl ;
# endif // DEBUG
2006-02-18 20:19:22 +00:00
} else if ( winclient & & winclient = = FocusControl : : focusedWindow ( ) & &
2004-10-21 10:18:40 +00:00
( winclient - > fbwindow ( ) = = 0
2006-07-23 09:51:54 +00:00
| | ! winclient - > fbwindow ( ) - > isMoving ( ) ) ) {
2004-03-03 12:29:31 +00:00
// we don't unfocus a moving window
2006-02-18 20:19:22 +00:00
FocusControl : : setFocusedWindow ( 0 ) ;
2006-07-23 09:51:54 +00:00
m_revert_screen = & winclient - > screen ( ) ;
m_revert_timer . start ( ) ;
}
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 ) {
// 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-06 17:12:09 +00:00
void Fluxbox : : handleButtonEvent ( XButtonEvent & be ) {
2003-06-30 15:05:26 +00:00
2002-12-01 13:42:15 +00:00
switch ( be . type ) {
2003-04-25 16:00:03 +00:00
case ButtonPress : {
m_last_time = be . time ;
2003-04-14 15:28:52 +00:00
2003-04-25 16:00:03 +00:00
BScreen * screen = searchScreen ( be . window ) ;
if ( screen = = 0 )
break ; // end case
2002-02-06 17:12:09 +00:00
2004-01-11 16:10:51 +00:00
screen - > hideMenus ( ) ;
2003-12-03 00:49:20 +00:00
2004-10-21 10:18:40 +00:00
// strip num/caps/scroll-lock and
2003-12-31 00:35:21 +00:00
// see if we're using any other modifier,
// if we're we shouldn't show the root menu
// this could happen if we're resizing aterm for instance
if ( FbTk : : KeyUtil : : instance ( ) . cleanMods ( be . state ) ! = 0 )
return ;
2003-04-25 16:00:03 +00:00
if ( be . button = = 1 ) {
if ( ! screen - > isRootColormapInstalled ( ) )
2003-05-15 23:30:07 +00:00
screen - > imageControl ( ) . installRootColormap ( ) ;
2004-09-12 14:01:41 +00:00
// hide menus
2005-07-04 18:18:32 +00:00
if ( screen - > rootMenu ( ) . isVisible ( ) )
screen - > rootMenu ( ) . hide ( ) ;
if ( screen - > workspaceMenu ( ) . isVisible ( ) )
screen - > workspaceMenu ( ) . hide ( ) ;
2003-06-11 14:53:54 +00:00
2003-04-25 16:00:03 +00:00
} else if ( be . button = = 2 ) {
2004-09-11 20:29:29 +00:00
FbCommands : : ShowWorkspaceMenuCmd cmd ;
cmd . execute ( ) ;
2004-10-21 10:18:40 +00:00
} else if ( be . button = = 3 ) {
2004-09-11 20:29:29 +00:00
FbCommands : : ShowRootMenuCmd cmd ;
cmd . execute ( ) ;
2003-04-25 16:00:03 +00:00
} else if ( screen - > isDesktopWheeling ( ) & & be . button = = 4 ) {
2006-04-16 12:03:31 +00:00
if ( screen - > isReverseWheeling ( ) ) {
screen - > prevWorkspace ( 1 ) ;
} else {
screen - > nextWorkspace ( 1 ) ;
}
2003-04-25 16:00:03 +00:00
} else if ( screen - > isDesktopWheeling ( ) & & be . button = = 5 ) {
2006-04-16 12:03:31 +00:00
if ( screen - > isReverseWheeling ( ) ) {
screen - > nextWorkspace ( 1 ) ;
} else {
screen - > prevWorkspace ( 1 ) ;
}
2002-12-01 13:42:15 +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 ButtonRelease :
2003-12-21 16:23:59 +00:00
m_last_time = be . time ;
2004-10-21 10:18:40 +00:00
break ;
2002-12-01 13:42:15 +00:00
default :
2003-04-25 16:00:03 +00:00
break ;
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
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
}
WinClient * winclient = 0 ;
2003-04-15 08:54:40 +00:00
2003-07-28 15:06:36 +00:00
if ( ( winclient = searchWindow ( ue . window ) ) ! = 0 ) {
2003-04-14 15:28:52 +00:00
2003-07-28 15:06:36 +00:00
if ( winclient ! = 0 ) {
FluxboxWindow * win = winclient - > fbwindow ( ) ;
2003-04-15 08:54:40 +00:00
2003-07-28 15:06:36 +00:00
if ( ! win ) {
delete winclient ;
return ;
}
// this should delete client and adjust m_focused_window if necessary
2004-10-21 10:18:40 +00:00
win - > unmapNotifyEvent ( ue ) ;
2002-12-01 13:42:15 +00:00
2003-07-28 15:06:36 +00:00
winclient = 0 ; // it's invalid now when win destroyed the client
2003-04-14 15:28:52 +00:00
2003-07-28 15:06:36 +00:00
// finally destroy window if empty
2003-04-14 15:28:52 +00:00
if ( win - > numClients ( ) = = 0 ) {
delete win ;
win = 0 ;
}
2004-10-21 10:18:40 +00:00
}
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 ) ;
2002-12-01 13:42:15 +00:00
cerr < < __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 ( ) ;
2003-04-15 12:22:52 +00:00
} else if ( ce . message_type = = m_fbatoms - > getFluxboxChangeWorkspaceAtom ( ) ) {
2002-12-01 13:42:15 +00:00
BScreen * screen = searchScreen ( ce . window ) ;
if ( screen & & ce . data . l [ 0 ] > = 0 & &
2005-07-04 18:18:32 +00:00
ce . data . l [ 0 ] < ( signed ) screen - > numberOfWorkspaces ( ) )
2002-12-01 13:42:15 +00:00
screen - > changeWorkspaceID ( ce . data . l [ 0 ] ) ;
2004-10-21 10:18:40 +00:00
2003-04-15 12:22:52 +00:00
} else if ( ce . message_type = = m_fbatoms - > getFluxboxChangeWindowFocusAtom ( ) ) {
2003-07-28 15:06:36 +00:00
WinClient * winclient = searchWindow ( ce . window ) ;
if ( winclient ) {
FluxboxWindow * win = winclient - > fbwindow ( ) ;
if ( win & & win - > isVisible ( ) )
win - > setCurrentClient ( * winclient , true ) ;
}
2003-04-15 12:22:52 +00:00
} else if ( ce . message_type = = m_fbatoms - > getFluxboxCycleWindowFocusAtom ( ) ) {
2002-12-01 13:42:15 +00:00
BScreen * screen = searchScreen ( ce . window ) ;
if ( screen ) {
if ( ! ce . data . l [ 0 ] )
2006-02-18 11:39:38 +00:00
screen - > focusControl ( ) . prevFocus ( ) ;
2002-12-01 13:42:15 +00:00
else
2006-02-18 11:39:38 +00:00
screen - > focusControl ( ) . nextFocus ( ) ;
2003-07-28 15:06:36 +00:00
}
2003-04-15 12:22:52 +00:00
} else if ( ce . message_type = = m_fbatoms - > getFluxboxChangeAttributesAtom ( ) ) {
2003-07-28 15:06:36 +00:00
WinClient * winclient = searchWindow ( ce . window ) ;
FluxboxWindow * win = 0 ;
if ( winclient & & ( win = winclient - > fbwindow ( ) ) & & winclient - > validateClient ( ) ) {
2003-05-10 14:32:35 +00:00
FluxboxWindow : : BlackboxHints net ;
2002-12-01 13:42:15 +00:00
net . flags = ce . data . l [ 0 ] ;
net . attrib = ce . data . l [ 1 ] ;
net . workspace = ce . data . l [ 2 ] ;
net . stack = ce . data . l [ 3 ] ;
net . decoration = static_cast < int > ( ce . data . l [ 4 ] ) ;
2003-01-05 22:41:21 +00:00
win - > changeBlackboxHints ( net ) ;
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
/**
Handles KeyRelease and KeyPress events
*/
2002-02-06 17:12:09 +00:00
void Fluxbox : : handleKeyEvent ( XKeyEvent & ke ) {
2004-10-21 10:18:40 +00:00
2003-06-30 15:05:26 +00:00
if ( keyScreen ( ) = = 0 | | mouseScreen ( ) = = 0 )
return ;
2003-04-25 16:00:03 +00:00
2006-12-17 22:21:23 +00:00
BScreen * old_watching_screen = m_watching_screen ;
2003-06-30 15:05:26 +00:00
switch ( ke . type ) {
case KeyPress :
2006-12-17 22:21:23 +00:00
// see if we need to keep watching for key releases
m_watching_screen = 0 ;
2006-12-19 18:08:33 +00:00
if ( ! m_key - > doAction ( ke ) ) // could still be cycling
2006-12-17 22:21:23 +00:00
m_watching_screen = old_watching_screen ;
2006-12-19 18:08:33 +00:00
else if ( old_watching_screen & &
m_watching_screen ! = old_watching_screen )
old_watching_screen - > notifyReleasedKeys ( ke ) ;
2004-09-12 14:01:41 +00:00
break ;
2003-04-25 16:00:03 +00:00
case KeyRelease : {
// we ignore most key releases unless we need to use
// a release to stop something (e.g. window cycling).
// we notify if _all_ of the watched modifiers are released
if ( m_watching_screen & & m_watch_keyrelease ) {
// mask the mod of the released key out
// won't mask anything if it isn't a mod
2005-05-06 09:22:53 +00:00
unsigned int state = FbTk : : KeyUtil : : instance ( ) . isolateModifierMask ( ke . state ) ;
state & = ~ FbTk : : KeyUtil : : instance ( ) . keycodeToModmask ( ke . keycode ) ;
2006-06-22 07:46:12 +00:00
2005-05-06 09:22:53 +00:00
if ( ( m_watch_keyrelease & state ) = = 0 ) {
2004-10-21 10:18:40 +00:00
2003-04-25 16:00:03 +00:00
m_watching_screen - > notifyReleasedKeys ( ke ) ;
XUngrabKeyboard ( FbTk : : App : : instance ( ) - > display ( ) , CurrentTime ) ;
2004-10-21 10:18:40 +00:00
2003-04-25 16:00:03 +00:00
// once they are released, we drop the watch
m_watching_screen = 0 ;
m_watch_keyrelease = 0 ;
2003-04-15 00:50:25 +00:00
}
2003-04-25 16:00:03 +00:00
}
2003-04-15 00:50:25 +00:00
2003-04-25 16:00:03 +00:00
break ;
2004-10-21 10:18:40 +00:00
}
2002-12-01 13:42:15 +00:00
default :
2003-04-14 15:28:52 +00:00
break ;
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 :
2005-02-02 15:22:58 +00:00
reload_rc ( ) ;
2002-12-01 13:42:15 +00:00
break ;
case SIGSEGV :
abort ( ) ;
break ;
case SIGFPE :
case SIGINT :
case SIGTERM :
shutdown ( ) ;
break ;
default :
fprintf ( stderr ,
2006-06-21 14:41:16 +00:00
_FB_CONSOLETEXT ( BaseDisplay , SignalCaught , " %s: signal %d caught \n " , " signal catch debug message. Include %s for command 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
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 ) ;
FluxboxWindow & win = winsub - > win ( ) ;
if ( ( & ( win . hintSig ( ) ) ) = = changedsub ) { // hint signal
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 ) {
if ( ( * it ) . first - > update ( ) )
( * it ) . first - > updateHints ( win ) ;
2002-12-01 13:42:15 +00:00
}
} else if ( ( & ( win . stateSig ( ) ) ) = = changedsub ) { // state signal
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 ) {
if ( ( * it ) . first - > update ( ) )
( * it ) . first - > updateState ( win ) ;
2002-12-01 13:42:15 +00:00
}
2003-04-14 15:28:52 +00:00
// if window changed to iconic state
// add to icon list
if ( win . isIconic ( ) ) {
2005-06-02 01:38:03 +00:00
win . screen ( ) . addIcon ( & win ) ;
2003-05-15 11:17:29 +00:00
Workspace * space = win . screen ( ) . getWorkspace ( win . workspaceNumber ( ) ) ;
2003-04-14 15:28:52 +00:00
if ( space ! = 0 )
2004-03-21 09:00:25 +00:00
space - > removeWindow ( & win , true ) ;
2003-04-14 15:28:52 +00:00
}
if ( win . isStuck ( ) ) {
// if we're sticky then reassociate window
// to all workspaces
2003-05-11 13:36:12 +00:00
BScreen & scr = win . screen ( ) ;
2003-05-15 12:00:46 +00:00
if ( scr . currentWorkspaceID ( ) ! = win . workspaceNumber ( ) ) {
2004-10-21 10:18:40 +00:00
scr . reassociateWindow ( & win ,
2003-05-15 12:00:46 +00:00
scr . currentWorkspaceID ( ) ,
2003-04-14 15:28:52 +00:00
true ) ;
}
}
2003-02-02 16:32:41 +00:00
} else if ( ( & ( win . layerSig ( ) ) ) = = changedsub ) { // layer signal
2003-04-14 15:28:52 +00:00
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 ) {
if ( ( * it ) . first - > update ( ) )
( * it ) . first - > updateLayer ( win ) ;
2003-02-02 16:32:41 +00:00
}
2003-03-03 21:51:13 +00:00
} else if ( ( & ( win . dieSig ( ) ) ) = = changedsub ) { // window death signal
2006-06-22 07:46:12 +00:00
2004-10-21 10:18:40 +00:00
for ( AtomHandlerContainerIt it = m_atomhandler . begin ( ) ;
2004-11-20 18:12:51 +00:00
it ! = m_atomhandler . end ( ) ; + + it ) {
2004-04-18 21:16:06 +00:00
if ( ( * it ) . first - > update ( ) )
( * it ) . first - > updateFrameClose ( win ) ;
2003-03-03 21:51:13 +00:00
}
2004-11-20 18:12:51 +00:00
2004-10-21 10:18:40 +00:00
// make sure each workspace get this
2003-05-11 13:36:12 +00:00
BScreen & scr = win . screen ( ) ;
2003-04-15 00:50:25 +00:00
scr . removeWindow ( & win ) ;
2006-06-29 18:01:33 +00:00
if ( FocusControl : : focusedFbWindow ( ) = = & win )
FocusControl : : setFocusedFbWindow ( 0 ) ;
2003-08-11 16:06:51 +00:00
2002-12-01 13:42:15 +00:00
} else if ( ( & ( win . workspaceSig ( ) ) ) = = changedsub ) { // workspace signal
2004-04-18 21:16:06 +00:00
for ( AtomHandlerContainerIt it = m_atomhandler . begin ( ) ;
it ! = m_atomhandler . end ( ) ; + + it ) {
if ( ( * it ) . first - > update ( ) )
( * it ) . first - > updateWorkspace ( win ) ;
2004-10-21 10:18:40 +00:00
}
2002-12-01 13:42:15 +00:00
} else {
2002-09-08 19:31:27 +00:00
# ifdef DEBUG
2002-12-01 13:42:15 +00:00
cerr < < __FILE__ < < " ( " < < __LINE__ < < " ): WINDOW uncought signal from " < < & win < < endl ;
2002-09-07 20:25:39 +00:00
# endif // DEBUG
2002-12-01 13:42:15 +00:00
}
2004-10-21 10:18:40 +00:00
2002-12-01 13:42:15 +00:00
} else if ( typeid ( * changedsub ) = = typeid ( BScreen : : ScreenSubject ) ) {
BScreen : : ScreenSubject * subj = dynamic_cast < BScreen : : ScreenSubject * > ( changedsub ) ;
BScreen & screen = subj - > screen ( ) ;
if ( ( & ( screen . workspaceCountSig ( ) ) ) = = changedsub ) {
2004-04-18 21:16:06 +00:00
for ( AtomHandlerContainerIt it = m_atomhandler . begin ( ) ;
it ! = m_atomhandler . end ( ) ; + + it ) {
if ( ( * it ) . first - > update ( ) )
( * it ) . first - > updateWorkspaceCount ( screen ) ;
2002-12-01 13:42:15 +00:00
}
} else if ( ( & ( screen . workspaceNamesSig ( ) ) ) = = changedsub ) {
2004-04-18 21:16:06 +00:00
for ( AtomHandlerContainerIt it = m_atomhandler . begin ( ) ;
it ! = m_atomhandler . end ( ) ; + + it ) {
if ( ( * it ) . first - > update ( ) )
( * it ) . first - > updateWorkspaceNames ( screen ) ;
2002-12-01 13:42:15 +00:00
}
} else if ( ( & ( screen . currentWorkspaceSig ( ) ) ) = = changedsub ) {
2004-04-18 21:16:06 +00:00
for ( AtomHandlerContainerIt it = m_atomhandler . begin ( ) ;
it ! = m_atomhandler . end ( ) ; + + it ) {
if ( ( * it ) . first - > update ( ) )
( * it ) . first - > updateCurrentWorkspace ( screen ) ;
2002-12-01 13:42:15 +00:00
}
2004-01-19 18:33:05 +00:00
} else if ( ( & ( screen . workspaceAreaSig ( ) ) ) = = changedsub ) {
2004-04-18 21:16:06 +00:00
for ( AtomHandlerContainerIt it = m_atomhandler . begin ( ) ;
it ! = m_atomhandler . end ( ) ; + + it ) {
if ( ( * it ) . first - > update ( ) )
( * it ) . first - > updateWorkarea ( screen ) ;
2004-01-19 18:33:05 +00:00
}
2002-12-01 13:42:15 +00:00
} else if ( ( & ( screen . clientListSig ( ) ) ) = = changedsub ) {
2004-04-18 21:16:06 +00:00
for ( AtomHandlerContainerIt it = m_atomhandler . begin ( ) ;
it ! = m_atomhandler . end ( ) ; + + it ) {
if ( ( * it ) . first - > update ( ) )
( * it ) . first - > updateClientList ( screen ) ;
2002-12-01 13:42:15 +00:00
}
}
2003-04-14 15:28:52 +00:00
} else if ( typeid ( * changedsub ) = = typeid ( WinClient : : WinClientSubj ) ) {
2003-08-11 16:06:51 +00:00
2003-04-14 15:28:52 +00:00
WinClient : : WinClientSubj * subj = dynamic_cast < WinClient : : WinClientSubj * > ( changedsub ) ;
WinClient & client = subj - > winClient ( ) ;
2003-07-04 14:06:20 +00:00
// TODO: don't assume it is diesig (need to fix as soon as another signal appears)
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 ) {
if ( ( * it ) . first - > update ( ) )
( * it ) . first - > updateClientClose ( client ) ;
2003-07-04 14:06:20 +00:00
}
2003-07-28 15:06:36 +00:00
2003-05-14 12:10:54 +00:00
BScreen & screen = client . screen ( ) ;
2004-10-21 10:18:40 +00:00
2003-05-14 12:10:54 +00:00
screen . removeClient ( client ) ;
2003-08-12 01:04:16 +00:00
// finaly send notify signal
screen . updateNetizenWindowDel ( client . window ( ) ) ;
2003-04-14 15:28:52 +00:00
2004-03-21 09:00:25 +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
// This is where we revert focus on window close
// NOWHERE ELSE!!!
2006-07-20 07:15:59 +00:00
if ( FocusControl : : focusedWindow ( ) = = & client ) {
2006-02-18 20:19:22 +00:00
FocusControl : : unfocusWindow ( client ) ;
2006-07-20 07:15:59 +00:00
// make sure nothing else uses this window before focus reverts
2006-02-18 20:19:22 +00:00
FocusControl : : setFocusedWindow ( 0 ) ;
2006-07-23 09:51:54 +00:00
m_revert_screen = & screen ;
m_revert_timer . start ( ) ;
}
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 ) {
2004-04-18 21:16:06 +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 ) {
m_group_search . insert ( pair < 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
2005-07-04 18:18:32 +00:00
for ( unsigned int workspace = 0 ; workspace < screen - > numberOfWorkspaces ( ) ; workspace + + ) {
2002-12-01 13:42:15 +00:00
if ( screen - > getWorkspace ( workspace ) - > name ( ) . size ( ) ! = 0 )
2006-05-07 10:08:25 +00:00
workspaces_string . append ( FbTk : : FbStringUtil : : FbStrToLocale ( screen - > getWorkspace ( workspace ) - > name ( ) ) ) ;
2002-12-01 13:42:15 +00:00
else
workspaces_string . append ( " Null " ) ;
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 ) ;
2002-08-13 21:19:00 +00:00
# ifdef DEBUG
2004-10-21 10:18:40 +00:00
cerr < < __FILE__ < < " ( " < < __LINE__ < < " ): ------------ SAVING DONE " < < endl ;
2002-08-13 21:19:00 +00:00
# endif // DEBUG
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 ( ) {
2004-10-21 10:18:40 +00:00
2004-01-21 13:36:09 +00:00
if ( m_rc_file . empty ( ) ) { // set default filename
2003-05-11 22:19:17 +00:00
string defaultfile ( getenv ( " HOME " ) + string ( " /. " ) + m_RC_PATH + string ( " / " ) + m_RC_INIT_FILE ) ;
2002-12-01 13:42:15 +00:00
return defaultfile ;
}
2002-01-11 09:26:33 +00:00
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
2006-10-30 19:31:15 +00:00
void Fluxbox : : getDefaultDataFilename ( char * name , string & filename ) {
2003-05-11 22:19:17 +00:00
filename = string ( 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
if ( FbTk : : Transparent : : haveComposite ( ) )
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 {
string filename ;
getDefaultDataFilename ( " slitlist " , filename ) ;
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-08-14 23:03:07 +00:00
2002-12-01 13:42:15 +00:00
if ( ! Workspace : : loadGroups ( * m_rc_groupfile ) ) {
2005-01-12 06:16:03 +00:00
# ifdef DEBUG
2006-06-21 14:41:16 +00:00
cerr < < _FB_CONSOLETEXT ( Fluxbox , CantLoadGroupFile , " Failed to load groupfile " , " Couldn't load the groupfile " ) < < " : " < < * m_rc_groupfile < < endl ;
2005-01-12 06:16:03 +00:00
# endif // DEBUG
2002-12-01 13:42:15 +00:00
}
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
}
2003-08-22 21:38:58 +00:00
FbTk : : Image : : removeAllSearchPaths ( ) ;
sprintf ( name_lookup , " session.screen%d.imageSearchPath " , screen_number ) ;
sprintf ( class_lookup , " Session.Screen%d.imageSearchPath " , screen_number ) ;
if ( XrmGetResource ( * database , name_lookup , class_lookup , & value_type ,
& value ) & & value . addr ) {
2006-10-30 19:31:15 +00:00
vector < string > paths ;
2003-08-22 21:38:58 +00:00
StringUtil : : stringtok ( paths , value . addr , " , " ) ;
2006-04-02 21:37:44 +00:00
for ( size_t i = 0 ; i < paths . size ( ) ; + + i )
2003-08-22 21:38:58 +00:00
FbTk : : Image : : addSearchPath ( paths [ i ] ) ;
}
2004-09-11 12:33:14 +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 : : reload_rc ( ) {
2002-12-01 13:42:15 +00:00
load_rc ( ) ;
reconfigure ( ) ;
2001-12-11 20:47:02 +00:00
}
2002-08-14 23:03:07 +00:00
void Fluxbox : : reconfigure ( ) {
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
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
2003-04-25 16:00:03 +00:00
m_key - > reconfigure ( StringUtil : : expandFilename ( * m_rc_keyfile ) . c_str ( ) ) ;
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-05-13 00:20:49 +00:00
bool Fluxbox : : menuTimestampsChanged ( ) const {
2006-10-30 19:31:15 +00:00
list < MenuTimestamp * > : : const_iterator it = m_menu_timestamps . begin ( ) ;
list < MenuTimestamp * > : : const_iterator it_end = m_menu_timestamps . end ( ) ;
2003-05-13 00:20:49 +00:00
for ( ; it ! = it_end ; + + it ) {
2006-06-22 07:46:12 +00:00
2004-12-18 01:29:22 +00:00
time_t timestamp = FbTk : : FileUtil : : getLastStatusChangeTimestamp ( ( * it ) - > filename . c_str ( ) ) ;
2002-12-01 13:42:15 +00:00
2004-12-18 01:29:22 +00:00
if ( timestamp > = 0 ) {
if ( timestamp ! = ( * it ) - > timestamp )
2003-05-13 00:20:49 +00:00
return true ;
2002-12-01 13:42:15 +00:00
} else
2003-05-13 00:20:49 +00:00
return true ;
2002-12-01 13:42:15 +00:00
}
2003-05-13 00:20:49 +00:00
// no timestamp changed
return false ;
}
2004-01-11 16:10:51 +00:00
void Fluxbox : : hideExtraMenus ( BScreen & screen ) {
# ifdef USE_TOOLBAR
// hide toolbar that matches screen
for ( size_t toolbar = 0 ; toolbar < m_toolbars . size ( ) ; + + toolbar ) {
if ( & ( m_toolbars [ toolbar ] - > screen ( ) ) = = & screen )
m_toolbars [ toolbar ] - > menu ( ) . hide ( ) ;
}
# endif // USE_TOOLBAR
}
2001-12-11 20:47:02 +00:00
2004-11-24 12:26:12 +00:00
void Fluxbox : : rereadMenu ( bool show_after_reread ) {
2003-04-25 16:00:03 +00:00
m_reread_menu_wait = true ;
2004-11-24 12:26:12 +00:00
m_show_menu_after_reread = show_after_reread ;
2003-12-19 13:37:28 +00:00
m_reconfig_timer . start ( ) ;
2001-12-11 20:47:02 +00:00
}
2002-10-15 20:41:08 +00:00
void Fluxbox : : real_rereadMenu ( ) {
2006-06-22 07:46:12 +00:00
2004-12-18 01:29:22 +00:00
clearMenuFilenames ( ) ;
2006-06-22 07:46:12 +00:00
for_each ( m_screen_list . begin ( ) ,
m_screen_list . end ( ) ,
2004-12-18 01:29:22 +00:00
mem_fun ( & BScreen : : rereadMenu ) ) ;
2004-11-24 12:26:12 +00:00
if ( m_show_menu_after_reread ) {
FbCommands : : ShowRootMenuCmd showcmd ;
showcmd . execute ( ) ;
m_show_menu_after_reread = false ;
}
2001-12-11 20:47:02 +00:00
}
void Fluxbox : : saveMenuFilename ( const char * filename ) {
2003-04-25 16:00:03 +00:00
if ( filename = = 0 )
return ;
bool found = false ;
2001-12-11 20:47:02 +00:00
2006-10-30 19:31:15 +00:00
list < MenuTimestamp * > : : iterator it = m_menu_timestamps . begin ( ) ;
list < MenuTimestamp * > : : iterator it_end = m_menu_timestamps . end ( ) ;
2002-12-01 13:42:15 +00:00
for ( ; it ! = it_end ; + + it ) {
2003-04-25 16:00:03 +00:00
if ( ( * it ) - > filename = = filename ) {
2004-10-21 10:18:40 +00:00
found = true ;
break ;
2003-04-25 16:00:03 +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
if ( ! found ) {
2004-12-18 01:29:22 +00:00
time_t timestamp = FbTk : : FileUtil : : getLastStatusChangeTimestamp ( filename ) ;
2001-12-11 20:47:02 +00:00
2004-12-18 01:29:22 +00:00
if ( timestamp > = 0 ) {
2002-12-01 13:42:15 +00:00
MenuTimestamp * ts = new MenuTimestamp ;
2001-12-11 20:47:02 +00:00
2003-04-25 16:00:03 +00:00
ts - > filename = filename ;
2004-12-18 01:29:22 +00:00
ts - > timestamp = timestamp ;
2001-12-11 20:47:02 +00:00
2003-04-25 16:00:03 +00:00
m_menu_timestamps . push_back ( ts ) ;
2002-12-01 13:42:15 +00:00
}
}
2001-12-11 20:47:02 +00:00
}
2003-05-13 00:20:49 +00:00
void Fluxbox : : clearMenuFilenames ( ) {
2004-12-18 01:29:22 +00:00
while ( ! m_menu_timestamps . empty ( ) ) {
delete m_menu_timestamps . back ( ) ;
m_menu_timestamps . pop_back ( ) ;
}
2003-05-13 00:20:49 +00:00
}
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
2003-04-25 16:00:03 +00:00
if ( m_reread_menu_wait )
2002-12-01 13:42:15 +00:00
real_rereadMenu ( ) ;
2001-12-11 20:47:02 +00:00
2003-04-25 16:00:03 +00:00
m_reconfigure_wait = m_reread_menu_wait = false ;
2001-12-11 20:47:02 +00:00
}
2006-07-23 09:51:54 +00:00
void Fluxbox : : revert_focus ( ) {
2006-07-23 13:30:46 +00:00
if ( m_revert_screen & & ! FocusControl : : focusedWindow ( ) & &
2006-07-25 21:54:58 +00:00
! FbTk : : Menu : : focused ( ) & & ! m_showing_dialog )
2006-07-23 09:51:54 +00:00
FocusControl : : revertFocus ( * m_revert_screen ) ;
}
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-02-18 20:19:22 +00:00
void Fluxbox : : updateFocusedWindow ( BScreen * screen , BScreen * old_screen ) {
2004-01-19 18:33:05 +00:00
if ( screen ! = 0 ) {
2002-12-01 13:42:15 +00:00
screen - > updateNetizenWindowFocus ( ) ;
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 + + ) {
2006-02-18 20:19:22 +00:00
( * it ) . first - > updateFocusedWindow ( * screen , ( FocusControl : : focusedWindow ( ) ?
FocusControl : : focusedWindow ( ) - > window ( ) :
2004-06-13 11:01:47 +00:00
0 ) ) ;
2004-01-19 18:33:05 +00:00
}
}
2002-12-01 13:42:15 +00:00
2004-01-19 18:33:05 +00:00
if ( old_screen & & old_screen ! = screen ) {
2002-12-01 13:42:15 +00:00
old_screen - > updateNetizenWindowFocus ( ) ;
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 - > updateFocusedWindow ( * old_screen , 0 ) ;
2004-01-19 18:33:05 +00:00
}
2001-12-11 20:47:02 +00:00
}
2003-04-15 00:50:25 +00:00
2003-05-10 14:32:35 +00:00
void Fluxbox : : watchKeyRelease ( BScreen & screen , unsigned int mods ) {
2006-06-22 07:46:12 +00:00
2003-04-27 04:56:18 +00:00
if ( mods = = 0 ) {
cerr < < " WARNING: attempt to grab without modifiers! " < < endl ;
return ;
}
2006-07-14 06:00:37 +00:00
if ( m_watching_screen )
m_watching_screen - > focusControl ( ) . stopCyclingFocus ( ) ;
2003-05-10 14:32:35 +00:00
m_watching_screen = & screen ;
2005-05-06 09:22:53 +00:00
// just make sure we are saving the mods with any other flags (xkb)
m_watch_keyrelease = FbTk : : KeyUtil : : instance ( ) . isolateModifierMask ( mods ) ;
2003-04-25 16:00:03 +00:00
XGrabKeyboard ( FbTk : : App : : instance ( ) - > display ( ) ,
2004-10-21 10:18:40 +00:00
screen . rootWindow ( ) . window ( ) , True ,
2003-04-15 00:50:25 +00:00
GrabModeAsync , GrabModeAsync , CurrentTime ) ;
}
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 ) ;
}
}
2006-06-22 07:46:12 +00:00
unsigned int Fluxbox : : getModKey ( ) const {
if ( ! ( m_rc_mod_key - > c_str ( ) ) )
return 0 ;
else
return FbTk : : KeyUtil : : instance ( ) . getModifier ( m_rc_mod_key - > c_str ( ) ) ;
}
void Fluxbox : : setModKey ( const char * modkeyname ) {
if ( ! modkeyname )
return ;
unsigned int modkey = FbTk : : KeyUtil : : instance ( ) . getModifier ( modkeyname ) ;
if ( modkey > 0 ) {
m_rc_mod_key = modkeyname ;
}
}