2002-01-09 14:07:09 +00:00
// fluxbox.cc for Fluxbox Window Manager
2004-01-11 16:10:51 +00:00
// Copyright (c) 2001 - 2004 Henrik Kinnunen (fluxgen at users.sourceforge.net)
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-10-19 17:23:08 +00:00
// $Id: fluxbox.cc,v 1.261 2004/10/19 17:23:08 akir Exp $
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"
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"
2003-10-05 07:20:47 +00:00
# include "FbTk/KeyUtil.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"
# include "FbTk/SimpleCommand.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"
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
2002-01-08 00:29:12 +00:00
using namespace std ;
2002-08-14 00:01:10 +00:00
using namespace FbTk ;
2001-12-11 20:47:02 +00:00
2003-05-10 14:32:35 +00:00
static Window last_bad_window = None ;
2003-08-12 21:00:54 +00:00
namespace {
void copyFile ( const std : : string & from , const std : : string & to ) {
ifstream from_file ( from . c_str ( ) ) ;
ofstream to_file ( to . c_str ( ) ) ;
if ( ! to_file . good ( ) ) {
cerr < < " Can't write file: " < < to < < endl ;
} else if ( from_file . good ( ) ) {
to_file < < from_file . rdbuf ( ) ; //copy file
} else {
cerr < < " Can't copy from " < < from < < " to " < < to < < endl ;
}
}
2003-05-10 14:32:35 +00:00
2003-12-16 23:36:06 +00:00
} // end anonymous
2003-05-10 14:32:35 +00:00
static 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 {
// ignore bad window ones, they happen a lot
// 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 ;
}
2003-05-10 14:32:35 +00:00
# endif // !DEBUG
return False ;
}
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
2002-03-01 15:28:56 +00:00
//default values for titlebar left and right
//don't forget to change last value in m_rc_titlebar_* if you add more to these
2003-04-25 16:00:03 +00:00
Fluxbox : : Titlebar Fluxbox : : s_titlebar_left [ ] = { STICK } ;
Fluxbox : : Titlebar Fluxbox : : s_titlebar_right [ ] = { MINIMIZE , MAXIMIZE , CLOSE } ;
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 ( ) ) ,
2003-07-18 15:40:55 +00:00
m_resourcemanager ( rcfilename , true ) ,
// TODO: shouldn't need a separate one for screen
m_screen_rm ( m_resourcemanager ) ,
2002-12-01 13:42:15 +00:00
m_rc_tabs ( m_resourcemanager , true , " session.tabs " , " Session.Tabs " ) ,
2004-10-10 16:06:24 +00:00
m_rc_tabs_padding ( m_resourcemanager , 0 , " session.tabPadding " , " Session.TabPadding " ) ,
m_rc_focused_tab_min_width ( m_resourcemanager , 0 , " session.focusTabMinWidth " ,
" Session.FocusTabMinWidth " ) ,
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 " ) ,
2003-04-25 16:00:03 +00:00
m_rc_colors_per_channel ( m_resourcemanager , 4 ,
" 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 " ) ,
m_rc_update_delay_time ( m_resourcemanager , 0 , " session.updateDelayTime " , " Session.UpdateDelayTime " ) ,
2002-12-01 13:42:15 +00:00
m_rc_stylefile ( m_resourcemanager , " " , " session.styleFile " , " Session.StyleFile " ) ,
m_rc_menufile ( m_resourcemanager , DEFAULTMENU , " session.menuFile " , " Session.MenuFile " ) ,
m_rc_keyfile ( m_resourcemanager , DEFAULTKEYSFILE , " session.keyFile " , " Session.KeyFile " ) ,
m_rc_slitlistfile ( m_resourcemanager , " " , " session.slitlistFile " , " Session.SlitlistFile " ) ,
m_rc_groupfile ( m_resourcemanager , " " , " session.groupFile " , " Session.GroupFile " ) ,
2004-10-19 17:23:08 +00:00
m_rc_appsfile ( m_resourcemanager , " ~/.fluxbox/apps " , " session.appsFile " , " Session.AppsFile " ) ,
2003-04-25 16:00:03 +00:00
m_rc_titlebar_left ( m_resourcemanager ,
TitlebarList ( & s_titlebar_left [ 0 ] , & s_titlebar_left [ 1 ] ) ,
" session.titlebar.left " , " Session.Titlebar.Left " ) ,
m_rc_titlebar_right ( m_resourcemanager ,
TitlebarList ( & s_titlebar_right [ 0 ] , & s_titlebar_right [ 3 ] ) ,
" session.titlebar.right " , " Session.Titlebar.Right " ) ,
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 " ) ,
2003-12-31 00:35:21 +00:00
m_rc_use_mod1 ( m_resourcemanager , true , " session.useMod1 " , " Session.UseMod1 " ) ,
2003-12-30 20:56:41 +00:00
m_focused_window ( 0 ) , 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 ) ,
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 " ) {
2003-04-25 16:00:03 +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 )
2004-06-07 11:46:05 +00:00
throw string ( _FBTEXT ( 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 ) {
2004-06-07 11:46:05 +00:00
throw string ( _FBTEXT ( Fluxbox , NoDisplay ,
" 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
FbTk : : fontInit ( ) ;
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
2003-06-11 14:53:54 +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 ) ;
sigh . registerHandler ( SIGUSR1 , this ) ;
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 ) ;
2004-09-11 12:33:14 +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
int shape_err ;
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-08-11 16:06:51 +00:00
// setup theme manager to have our style file ready to be scanned
FbTk : : ThemeManager : : instance ( ) . load ( getStyleFilename ( ) ) ;
2003-07-18 15:40:55 +00:00
2003-04-25 16:00:03 +00:00
// setup atom handlers before we create any windows
2002-10-25 21:17:15 +00:00
# ifdef USE_GNOME
2004-04-18 21:16:06 +00:00
addAtomHandler ( new Gnome ( ) , " gnome " ) ; // for gnome 1 atom support
2002-10-25 21:17:15 +00:00
# endif //USE_GNOME
2003-04-25 16:00:03 +00:00
2002-10-25 21:17:15 +00:00
# ifdef USE_NEWWMSPEC
2004-04-18 21:16:06 +00:00
addAtomHandler ( new Ewmh ( ) , " ewmh " ) ; // for Extended window manager atom support
2002-10-25 21:17:15 +00:00
# endif // USE_NEWWMSPEC
2003-05-12 04:23:31 +00:00
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
2002-08-18 11:01:52 +00:00
2002-12-01 13:42:15 +00:00
grab ( ) ;
2002-02-26 22:42:23 +00:00
2002-12-01 13:42:15 +00:00
setupConfigFiles ( ) ;
2002-02-26 22:42:23 +00:00
2002-12-01 13:42:15 +00:00
if ( ! XSupportsLocale ( ) )
2004-06-07 11:46:05 +00:00
cerr < < _FBTEXT ( 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 )
2004-06-07 11:46:05 +00:00
cerr < < _FBTEXT ( 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-05-10 14:32:35 +00:00
// Allocate screens
for ( int i = 0 ; i < ScreenCount ( display ( ) ) ; i + + ) {
2002-12-01 13:42:15 +00:00
char scrname [ 128 ] , altscrname [ 128 ] ;
sprintf ( scrname , " session.screen%d " , i ) ;
sprintf ( altscrname , " session.Screen%d " , i ) ;
2004-01-21 13:36:09 +00:00
BScreen * screen = new BScreen ( m_screen_rm . lock ( ) ,
2003-05-12 04:28:05 +00:00
scrname , altscrname ,
i , getNumberOfLayers ( ) ) ;
2002-12-01 13:42:15 +00:00
if ( ! screen - > isScreenManaged ( ) ) {
delete screen ;
continue ;
}
2004-05-02 20:48:16 +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 ( ) ;
2003-06-12 14:32:08 +00:00
# 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
2003-05-12 04:28:05 +00:00
# ifdef HAVE_RANDR
2003-06-11 14:53:54 +00:00
// setup RANDR for this screens root window
// we need to determine if we should use old randr select input function or not
2003-05-12 11:14:47 +00:00
# ifdef X_RRScreenChangeSelectInput
// use old set randr event
XRRScreenChangeSelectInput ( disp , screen - > rootWindow ( ) . window ( ) , True ) ;
# else
2003-05-12 04:28:05 +00:00
XRRSelectInput ( disp , screen - > rootWindow ( ) . window ( ) ,
RRScreenChangeNotifyMask ) ;
2003-05-12 11:14:47 +00:00
# endif // X_RRScreenChangeSelectInput
2003-05-12 04:28:05 +00:00
# endif // HAVE_RANDR
2004-05-02 20:48:16 +00:00
2003-06-25 13:07:34 +00:00
# ifdef USE_TOOLBAR
2003-12-03 00:33:30 +00:00
m_toolbars . push_back ( new Toolbar ( * screen ,
2004-05-02 20:48:16 +00:00
* screen - > layerManager ( ) .
getLayer ( Fluxbox : : instance ( ) - > getNormalLayer ( ) ) ) ) ;
2003-06-25 13:07:34 +00:00
# endif // USE_TOOLBAR
2004-06-21 15:23:42 +00:00
// must do this after toolbar is created
screen - > initWindows ( ) ;
2003-08-11 16:06:51 +00:00
2002-12-01 13:42:15 +00:00
// attach screen signals to this
screen - > currentWorkspaceSig ( ) . attach ( this ) ;
screen - > workspaceCountSig ( ) . attach ( this ) ;
screen - > workspaceNamesSig ( ) . attach ( this ) ;
2004-01-19 18:33:05 +00:00
screen - > workspaceAreaSig ( ) . attach ( this ) ;
2002-12-01 13:42:15 +00:00
screen - > clientListSig ( ) . attach ( this ) ;
2003-10-28 02:17:03 +00:00
2002-12-01 13:42:15 +00:00
// initiate atomhandler for screen specific stuff
2004-04-18 21:16:06 +00:00
for ( AtomHandlerContainerIt it = m_atomhandler . begin ( ) ;
it ! = m_atomhandler . end ( ) ;
it + + ) {
( * it ) . first - > initForScreen ( * screen ) ;
2002-12-01 13:42:15 +00:00
}
2003-12-03 00:33:30 +00:00
2003-12-30 20:56:41 +00:00
revertFocus ( * screen ) ; // make sure focus style is correct
2004-04-19 22:48:19 +00:00
# ifdef SLIT
if ( screen - > slit ( ) )
screen - > slit ( ) - > show ( ) ;
# endif // SLIT
2003-08-11 16:06:51 +00:00
2004-07-14 23:39:29 +00:00
2003-12-03 00:33:30 +00:00
} // end init screens
2004-04-26 09:25:42 +00:00
XAllowEvents ( disp , ReplayPointer , CurrentTime ) ;
2003-12-03 00:33:30 +00:00
2003-06-30 15:05:26 +00:00
m_keyscreen = m_mousescreen = m_screen_list . front ( ) ;
2002-12-01 13:42:15 +00:00
2004-01-21 13:36:09 +00:00
if ( m_screen_list . empty ( ) ) {
2004-06-07 11:46:05 +00:00
throw string ( _FBTEXT ( Fluxbox , ErrorNoScreens ,
" Couldn't find screens to manage. \n Make sure you don't have another window manager running. " , " 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
2003-08-11 20:59:58 +00:00
// setup theme manager to have our style file ready to be scanned
2004-02-20 09:29:07 +00:00
FbTk : : ThemeManager : : instance ( ) . load ( FbTk : : StringUtil : : expandFilename ( getStyleFilename ( ) ) ) ;
2003-08-11 16:06:51 +00:00
2003-04-25 16:00:03 +00:00
XSynchronize ( disp , False ) ;
2004-09-11 12:33:14 +00:00
//XSynchronize(disp, True);
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
2003-05-13 11:43:44 +00:00
// Create keybindings handler and load keys file
2003-04-25 16:00:03 +00:00
m_key . reset ( new Keys ( 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 ( ) ;
2003-07-18 15:40:55 +00:00
# ifdef DEBUG
if ( m_resourcemanager . lockDepth ( ) ! = 0 )
cerr < < " --- resource manager lockdepth = " < < m_resourcemanager . lockDepth ( ) < < endl ;
# endif //DEBUG
2003-05-10 14:32:35 +00:00
m_starting = false ;
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-01-11 16:10:51 +00:00
2004-01-10 02:58:50 +00:00
while ( ! m_screen_list . empty ( ) ) {
delete m_screen_list . back ( ) ;
m_screen_list . pop_back ( ) ;
}
2003-12-03 00:33:30 +00:00
2003-05-13 00:20:49 +00:00
clearMenuFilenames ( ) ;
2001-12-11 20:47:02 +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
2003-06-08 00:13:41 +00:00
if ( last_bad_window ! = None & & e . xany . window = = last_bad_window & &
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
/**
setup the configutation files in
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 ) ) {
2002-02-26 22:42:23 +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 ) ) {
2004-06-07 11:46:05 +00:00
fprintf ( stderr , _FBTEXT ( Fluxbox , ErrorCreatingDirectory ,
" Can't create %s directory " , " Can't create a directory, one %s for directory name " ) , dirname . c_str ( ) ) ;
cerr < < endl ;
2002-12-01 13:42:15 +00:00
return ;
}
2002-02-26 22:42:23 +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 )
copyFile ( DEFAULTKEYSFILE , keys_file ) ;
2002-12-01 13:42:15 +00:00
2003-08-12 21:00:54 +00:00
// copy menu configuration
if ( create_menu )
copyFile ( DEFAULTMENU , menu_file ) ;
2002-12-01 13:42:15 +00:00
2003-08-12 21:00:54 +00:00
// copy init file
if ( create_init )
copyFile ( DEFAULT_INITFILE , init_file ) ;
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
2003-12-30 20:56:41 +00:00
// to mask all events to go to it
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 ( ) ;
}
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 ) ;
2003-12-21 22:42:31 +00:00
} else if ( e - > type = = PropertyNotify )
m_last_time = e - > xproperty . time ;
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-01-16 18:07:40 +00:00
2004-01-16 11:28:00 +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
BScreen * screen = 0 ;
ScreenList : : iterator it = m_screen_list . begin ( ) ;
ScreenList : : iterator it_end = m_screen_list . end ( ) ;
for ( ; it ! = it_end ; + + it ) {
if ( ( * it ) - > screenNumber ( ) = =
FbTk : : Menu : : focused ( ) - > fbwindow ( ) . screenNumber ( ) ) {
screen = ( * it ) ;
break ; // found the screen, no more search
2004-01-16 11:28:00 +00:00
}
}
2004-01-16 18:07:40 +00:00
2004-01-16 11:38:30 +00:00
if ( screen ! = 0 )
2004-01-16 18:07:40 +00:00
revertFocus ( * screen ) ;
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 ) ;
2002-02-06 17:12:09 +00:00
break ;
2003-04-25 16:00:03 +00:00
case ConfigureRequest : {
2003-07-28 15:06:36 +00:00
WinClient * winclient = ( WinClient * ) 0 ;
2003-04-25 16:00:03 +00:00
2003-07-28 15:06:36 +00:00
if ( ( winclient = searchWindow ( e - > xconfigurerequest . window ) ) ) {
2003-04-25 16:00:03 +00:00
// already handled in FluxboxWindow::handleEvent
} else {
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 ( ) ;
2002-12-01 13:42:15 +00:00
}
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-07-14 23:39:29 +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 ) ;
// 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 ) ;
if ( screen = = 0 ) {
2004-06-07 11:46:05 +00:00
cerr < < " Fluxbox " < < _FBTEXT ( 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 ) ;
2002-02-06 17:12:09 +00:00
break ;
2003-04-15 00:50:25 +00:00
case MappingNotify :
// Update stored modifier mapping
# ifdef DEBUG
cerr < < __FILE__ < < " ( " < < __FUNCTION__ < < " ): MappingNotify " < < endl ;
# endif // DEBUG
2003-10-05 07:20:47 +00:00
2003-10-13 19:31:04 +00:00
FbTk : : KeyUtil : : instance ( ) . init ( ) ; // reinitialise the key utils
2004-03-03 12:53:06 +00:00
// reconfigure keys (if the mapping changes, they don't otherwise update
m_key - > reconfigure ( StringUtil : : expandFilename ( * m_rc_keyfile ) . c_str ( ) ) ;
2003-10-05 07:20:47 +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 : {
2003-07-28 15:06:36 +00:00
WinClient * winclient = searchWindow ( e - > xdestroywindow . window ) ;
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 ;
2003-04-14 15:28:52 +00:00
2003-07-28 15:06:36 +00:00
if ( win & & win - > numClients ( ) = = 0 )
delete win ;
2002-12-01 13:42:15 +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 ;
2003-02-22 15:10:43 +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
// but some special cases like ewmh propertys needs to be checked
2004-04-18 21:16:06 +00:00
for ( AtomHandlerContainerIt it = m_atomhandler . begin ( ) ;
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
}
2002-02-06 17:12:09 +00:00
2003-04-25 16:00:03 +00:00
} break ;
2002-12-01 13:42:15 +00:00
case LeaveNotify :
2004-07-14 23:39:29 +00:00
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 ) ;
2003-08-11 16:06:51 +00:00
if ( winclient & & m_focused_window ! = winclient )
2003-07-28 15:06:36 +00:00
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
2004-03-03 12:29:31 +00:00
} else if ( winclient & & winclient = = m_focused_window & &
( winclient - > fbwindow ( ) = = 0
| | ! winclient - > fbwindow ( ) - > isMoving ( ) ) )
// we don't unfocus a moving window
2003-12-21 16:23:59 +00:00
setFocusedWindow ( 0 ) ;
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-07-14 23:39:29 +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 )
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
2003-12-31 00:35:21 +00:00
// strip num/caps/scroll-lock and
// 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
2003-12-19 00:35:08 +00:00
if ( screen - > getRootmenu ( ) . isVisible ( ) )
screen - > getRootmenu ( ) . hide ( ) ;
2004-09-12 14:01:41 +00:00
if ( screen - > getWorkspacemenu ( ) . isVisible ( ) )
screen - > getWorkspacemenu ( ) . 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 ( ) ;
2003-04-25 16:00:03 +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 ) {
screen - > nextWorkspace ( 1 ) ;
} else if ( screen - > isDesktopWheeling ( ) & & be . button = = 5 ) {
screen - > prevWorkspace ( 1 ) ;
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 ButtonRelease :
2003-12-21 16:23:59 +00:00
m_last_time = be . time ;
2003-04-14 15:28:52 +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 ) {
2003-07-28 15:06:36 +00:00
WinClient * winclient = 0 ;
2002-02-17 18:43:30 +00:00
2002-12-01 13:42:15 +00:00
BScreen * screen = searchScreen ( ue . event ) ;
2002-02-17 18:43:30 +00:00
2003-04-14 15:28:52 +00:00
if ( ue . event ! = ue . window & & ( screen ! = 0 | | ! ue . send_event ) )
2002-12-01 13:42:15 +00:00
return ;
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
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 ;
}
}
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 ;
2002-02-06 17:12:09 +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 & &
ce . data . l [ 0 ] < ( signed ) screen - > getCount ( ) )
screen - > changeWorkspaceID ( ce . data . l [ 0 ] ) ;
2002-02-06 17:12:09 +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 ] )
screen - > prevFocus ( ) ;
else
screen - > 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 ) ;
2003-08-15 13:57:18 +00:00
// note: we dont need screen nor winclient to be non-null,
// it's up to the atomhandler to check that
2004-04-18 21:16:06 +00:00
for ( AtomHandlerContainerIt it = m_atomhandler . begin ( ) ;
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 ) {
2003-06-30 15:05:26 +00:00
if ( keyScreen ( ) = = 0 | | mouseScreen ( ) = = 0 )
return ;
2003-04-25 16:00:03 +00:00
2003-06-30 15:05:26 +00:00
switch ( ke . type ) {
case KeyPress :
m_key - > doAction ( 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
2003-12-30 20:56:41 +00:00
ke . state & = ~ FbTk : : KeyUtil : : instance ( ) . keycodeToModmask ( ke . keycode ) ;
2003-04-25 16:00:03 +00:00
if ( ( m_watch_keyrelease & ke . state ) = = 0 ) {
2003-04-15 00:50:25 +00:00
2003-04-25 16:00:03 +00:00
m_watching_screen - > notifyReleasedKeys ( ke ) ;
XUngrabKeyboard ( FbTk : : App : : instance ( ) - > display ( ) , CurrentTime ) ;
2003-04-15 00:50:25 +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 ;
}
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
}
2002-02-06 17:12:09 +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
waitpid ( - 1 , 0 , WNOHANG | WUNTRACED ) ;
break ;
case SIGHUP :
load_rc ( ) ;
break ;
case SIGUSR1 :
reload_rc ( ) ;
break ;
case SIGUSR2 :
rereadMenu ( ) ;
break ;
case SIGSEGV :
abort ( ) ;
break ;
case SIGFPE :
case SIGINT :
case SIGTERM :
shutdown ( ) ;
break ;
default :
fprintf ( stderr ,
2004-06-07 11:46:05 +00:00
_FBTEXT ( BaseDisplay , SignalCaught , " %s: signal %d caught \n " , " signal catch debug message. Include %s for command and %d for signal number " ) ,
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 ;
fprintf ( stderr ,
2004-06-07 11:46:05 +00:00
_FBTEXT ( 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
2002-08-14 00:01:10 +00:00
2002-12-01 13:42:15 +00:00
fprintf ( stderr ,
2004-06-07 11:46:05 +00:00
_FBTEXT ( 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-04-18 21:16:06 +00:00
for ( AtomHandlerContainerIt it = m_atomhandler . begin ( ) ;
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-04-18 21:16:06 +00:00
for ( AtomHandlerContainerIt it = m_atomhandler . begin ( ) ;
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 ( ) ) {
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-05-11 13:36:12 +00:00
win . screen ( ) . addIcon ( & win ) ;
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 ( ) ) {
2003-04-14 15:28:52 +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-04-18 21:16:06 +00:00
for ( AtomHandlerContainerIt it = m_atomhandler . begin ( ) ;
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
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 - > updateFrameClose ( win ) ;
2003-03-03 21:51:13 +00:00
}
2003-04-14 15:28:52 +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 ) ;
2003-08-11 16:06:51 +00:00
if ( m_focused_window = = & win . winClient ( ) )
m_focused_window = 0 ;
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 ) ;
2003-04-14 15:28:52 +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
}
2002-09-07 20:25:39 +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-04-18 21:16:06 +00:00
for ( AtomHandlerContainerIt it = m_atomhandler . begin ( ) ;
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 ( ) ;
2003-08-12 00:26:42 +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!!!
if ( m_focused_window = = & client )
unfocusWindow ( client ) ;
2003-07-28 15:06:36 +00:00
2003-08-11 16:06:51 +00:00
// failed to revert focus?
if ( m_focused_window = = & client )
m_focused_window = 0 ;
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-04-18 21:16:06 +00:00
for ( AtomHandlerContainerIt it = m_atomhandler . begin ( ) ;
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-04-18 21:16:06 +00:00
for ( AtomHandlerContainerIt it = m_atomhandler . begin ( ) ;
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
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
2004-04-19 22:48:19 +00:00
AtomHandler * Fluxbox : : getAtomHandler ( const std : : string & name ) {
2004-04-18 21:16:06 +00:00
if ( name ! = " " ) {
for ( AtomHandlerContainerIt it = m_atomhandler . begin ( ) ;
it ! = m_atomhandler . end ( ) ; it + + ) {
if ( name = = ( * it ) . second )
return ( * it ) . first ;
}
2003-04-25 16:00:03 +00:00
}
2004-04-18 21:16:06 +00:00
return 0 ;
}
2004-04-19 22:48:19 +00:00
void Fluxbox : : addAtomHandler ( AtomHandler * atomh , const std : : 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 ( ) ;
it ! = m_atomhandler . end ( ) ;
+ + 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 ) {
std : : map < Window , WinClient * > : : 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
2003-07-28 15:06:36 +00:00
std : : map < Window , FluxboxWindow * > : : iterator git = m_window_search_group . find ( window ) ;
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-18 01:26:54 +00:00
for_each ( m_screen_list . begin ( ) ,
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 ;
2002-01-20 02:19:16 +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 ( ) ) ;
2002-01-20 02:19:16 +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
2004-06-07 11:46:05 +00:00
cerr < < _FBTEXT ( Fluxbox , BadRCFile , " rc filename is invalid! " , " Bad settings file " ) < < endl ;
2002-01-20 02:19:16 +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
2002-12-01 13:42:15 +00:00
for ( unsigned int workspace = 0 ; workspace < screen - > getCount ( ) ; workspace + + ) {
if ( screen - > getWorkspace ( workspace ) - > name ( ) . size ( ) ! = 0 )
workspaces_string . append ( screen - > getWorkspace ( workspace ) - > name ( ) ) ;
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 ( ) ) ;
2002-01-20 02:19:16 +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
2002-12-01 13:42:15 +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 ( ) {
2001-12-11 20:47:02 +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
2002-05-29 06:22:31 +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 ( ) ) ) {
2004-06-07 11:46:05 +00:00
cerr < < _FBTEXT ( Fluxbox , CantLoadRCFile , " Failed to load database " , " Failed trying to read rc file " ) < < " : " < < dbfile < < endl ;
cerr < < _FBTEXT ( 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 ) )
2004-06-07 11:46:05 +00:00
cerr < < _FBTEXT ( Fluxbox , CantLoadRCFile , " Failed to load database " , " " ) < < " : " < < DEFAULT_INITFILE < < endl ;
2002-12-01 13:42:15 +00:00
}
} else {
if ( ! m_resourcemanager . load ( DEFAULT_INITFILE ) )
2004-06-07 11:46:05 +00:00
cerr < < _FBTEXT ( Fluxbox , CantLoadRCFile , " Failed to load database " , " " ) < < " : " < < DEFAULT_INITFILE < < endl ;
2002-12-01 13:42:15 +00:00
}
2001-12-11 20:47:02 +00:00
2004-01-21 13:36:09 +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 ) ;
2002-05-29 06:22:31 +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-01-21 13:36:09 +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 ) ) {
2004-06-07 11:46:05 +00:00
cerr < < _FBTEXT ( Fluxbox , CantLoadGroupFile , " Failed to load groupfile " , " Couldn't load the groupfile " ) < < " : " < < * m_rc_groupfile < < endl ;
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 ( ) ) ;
2002-01-20 02:19:16 +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 ) ;
2002-01-18 01:23:54 +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 ( ) ;
2003-12-19 00:35:08 +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 ) ) {
2002-08-14 23:03:07 +00:00
# ifdef DEBUG
2003-04-15 12:22:52 +00:00
cerr < < __FILE__ < < " ( " < < __FUNCTION__ < < " ): Workspaces= " < <
screen . getNumberOfWorkspaces ( ) < < endl ;
2002-08-14 23:03:07 +00:00
# endif // DEBUG
2002-12-01 13:42:15 +00:00
char * search = StringUtil : : strdup ( value . addr ) ;
2002-01-18 01:23:54 +00:00
2002-12-01 13:42:15 +00:00
int i ;
2003-04-15 12:22:52 +00:00
for ( i = 0 ; i < screen . getNumberOfWorkspaces ( ) ; i + + ) {
2002-12-01 13:42:15 +00:00
char * nn ;
2002-01-18 01:23:54 +00:00
2002-12-01 13:42:15 +00:00
if ( ! i ) nn = strtok ( search , " , " ) ;
else nn = strtok ( 0 , " , " ) ;
2002-01-18 01:23:54 +00:00
2002-12-01 13:42:15 +00:00
if ( nn )
2003-04-15 12:22:52 +00:00
screen . addWorkspaceName ( nn ) ;
2002-12-01 13:42:15 +00:00
else break ;
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
}
delete [ ] search ;
}
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 ) {
std : : vector < std : : string > paths ;
StringUtil : : stringtok ( paths , value . addr , " , " ) ;
for ( unsigned int i = 0 ; i < paths . size ( ) ; + + i )
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 ( ) ) ) {
2004-06-07 11:46:05 +00:00
cerr < < _FBTEXT ( Fluxbox , CantLoadRCFile , " Failed to load database " , " Failed trying to read rc file " ) < < " : " < < dbfile < < endl ;
cerr < < _FBTEXT ( 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 ) )
2004-06-07 11:46:05 +00:00
cerr < < _FBTEXT ( 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 ) )
2004-06-07 11:46:05 +00:00
cerr < < _FBTEXT ( 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
}
2003-04-15 12:22:52 +00:00
void Fluxbox : : loadRootCommand ( BScreen & screen ) {
2002-01-11 09:26:33 +00:00
2002-12-01 13:42:15 +00:00
string dbfile ( getRcFilename ( ) ) ;
2002-12-02 23:49:56 +00:00
XrmDatabaseHelper database ( dbfile . c_str ( ) ) ;
if ( ! * database )
2002-12-01 13:42:15 +00:00
database = XrmGetFileDatabase ( DEFAULT_INITFILE ) ;
XrmValue value ;
char * value_type , name_lookup [ 1024 ] , class_lookup [ 1024 ] ;
2003-05-15 12:00:46 +00:00
sprintf ( name_lookup , " session.screen%d.rootCommand " , screen . screenNumber ( ) ) ;
sprintf ( class_lookup , " Session.Screen%d.RootCommand " , screen . screenNumber ( ) ) ;
2002-12-02 23:49:56 +00:00
if ( XrmGetResource ( * database , name_lookup , class_lookup , & value_type ,
2002-12-01 13:42:15 +00:00
& value ) ) {
2003-04-15 12:22:52 +00:00
screen . saveRootCommand ( value . addr = = 0 ? " " : value . addr ) ;
2002-12-01 13:42:15 +00:00
} else
2003-04-15 12:22:52 +00:00
screen . saveRootCommand ( " " ) ;
2002-01-10 12:51:21 +00:00
}
2002-01-11 09:26:33 +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
2002-12-01 13:42:15 +00:00
XrmDatabase new_blackboxrc = ( XrmDatabase ) 0 ;
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
string dbfile ( getRcFilename ( ) ) ;
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 ) ;
XrmPutFileDatabase ( old_blackboxrc , dbfile . c_str ( ) ) ;
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
if ( old_blackboxrc )
XrmDestroyDatabase ( old_blackboxrc ) ;
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
}
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 {
std : : list < MenuTimestamp * > : : const_iterator it = m_menu_timestamps . begin ( ) ;
std : : list < MenuTimestamp * > : : const_iterator it_end = m_menu_timestamps . end ( ) ;
for ( ; it ! = it_end ; + + it ) {
2002-12-01 13:42:15 +00:00
struct stat buf ;
2003-04-25 16:00:03 +00:00
if ( ! stat ( ( * it ) - > filename . c_str ( ) , & buf ) ) {
2002-12-01 13:42:15 +00:00
if ( ( * it ) - > timestamp ! = buf . st_ctime )
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 ;
}
void Fluxbox : : checkMenu ( ) {
if ( menuTimestampsChanged ( ) )
rereadMenu ( ) ;
2001-12-11 20:47:02 +00:00
}
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
2002-10-15 20:41:08 +00:00
void Fluxbox : : rereadMenu ( ) {
2003-04-25 16:00:03 +00:00
m_reread_menu_wait = true ;
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 ( ) {
2003-04-25 16:00:03 +00:00
std : : list < MenuTimestamp * > : : iterator it = m_menu_timestamps . begin ( ) ;
std : : list < MenuTimestamp * > : : iterator it_end = m_menu_timestamps . end ( ) ;
for ( ; it ! = it_end ; + + it )
delete * it ;
2002-12-01 13:42:15 +00:00
2003-04-25 16:00:03 +00:00
m_menu_timestamps . erase ( m_menu_timestamps . begin ( ) , m_menu_timestamps . end ( ) ) ;
2003-08-24 11:19:45 +00:00
for_each ( m_screen_list . begin ( ) , m_screen_list . end ( ) , mem_fun ( & BScreen : : rereadMenu ) ) ;
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
2003-04-25 16:00:03 +00:00
std : : list < MenuTimestamp * > : : iterator it = m_menu_timestamps . begin ( ) ;
std : : 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 ) {
found = true ;
break ;
}
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 ) {
struct stat buf ;
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
if ( ! stat ( filename , & buf ) ) {
MenuTimestamp * ts = new MenuTimestamp ;
2001-12-11 20:47:02 +00:00
2003-04-25 16:00:03 +00:00
ts - > filename = filename ;
2002-12-01 13:42:15 +00:00
ts - > timestamp = buf . st_ctime ;
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 ( ) {
std : : list < MenuTimestamp * > : : iterator it = m_menu_timestamps . begin ( ) ;
std : : list < MenuTimestamp * > : : iterator it_end = m_menu_timestamps . end ( ) ;
for ( ; it ! = it_end ; + + it )
delete * it ;
m_menu_timestamps . erase ( m_menu_timestamps . begin ( ) , m_menu_timestamps . end ( ) ) ;
}
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
}
2002-07-13 14:04:46 +00:00
// set focused window
2003-07-28 15:06:36 +00:00
void Fluxbox : : setFocusedWindow ( WinClient * client ) {
2003-04-29 12:39:45 +00:00
// already focused
2003-07-28 15:06:36 +00:00
if ( m_focused_window = = client ) {
2003-05-11 15:24:09 +00:00
# ifdef DEBUG
cerr < < " Focused window already win " < < endl ;
# endif // DEBUG
return ;
}
# ifdef DEBUG
2003-07-28 15:06:36 +00:00
cerr < < " Setting Focused window = " < < client < < endl ;
2004-07-14 23:39:29 +00:00
if ( client ! = 0 & & client - > fbwindow ( ) ! = 0 )
cerr < < " title: " < < client - > fbwindow ( ) - > title ( ) < < endl ;
2003-05-11 15:24:09 +00:00
cerr < < " Current Focused window = " < < m_focused_window < < endl ;
cerr < < " ------------------ " < < endl ;
# endif // DEBUG
2002-12-01 13:42:15 +00:00
BScreen * old_screen = 0 , * screen = 0 ;
2003-07-28 15:06:36 +00:00
WinClient * old_client = 0 ;
2003-12-16 23:36:06 +00:00
Workspace * old_wkspc = 0 ;
2003-09-12 22:55:33 +00:00
2003-04-25 16:00:03 +00:00
if ( m_focused_window ! = 0 ) {
2003-05-10 14:32:35 +00:00
// check if m_focused_window is valid
bool found = false ;
2003-07-28 15:06:36 +00:00
std : : map < Window , WinClient * > : : iterator it = m_window_search . begin ( ) ;
std : : map < Window , WinClient * > : : iterator it_end = m_window_search . end ( ) ;
2003-05-10 14:32:35 +00:00
for ( ; it ! = it_end ; + + it ) {
if ( it - > second = = m_focused_window ) {
// we found it, end loop
found = true ;
break ;
}
}
2003-04-15 00:50:25 +00:00
2003-05-10 14:32:35 +00:00
if ( ! found ) {
m_focused_window = 0 ;
} else {
2003-07-28 15:06:36 +00:00
old_client = m_focused_window ;
old_screen = & old_client - > screen ( ) ;
2001-12-11 20:47:02 +00:00
2003-07-28 15:06:36 +00:00
if ( old_client - > fbwindow ( ) ) {
FluxboxWindow * old_win = old_client - > fbwindow ( ) ;
old_wkspc = old_screen - > getWorkspace ( old_win - > workspaceNumber ( ) ) ;
2003-05-10 14:32:35 +00:00
2003-07-28 15:06:36 +00:00
if ( ! client | | client - > fbwindow ( ) ! = old_win )
old_win - > setFocusFlag ( false ) ;
}
2003-05-10 14:32:35 +00:00
}
2002-12-01 13:42:15 +00:00
}
2003-07-28 15:06:36 +00:00
if ( client & & client - > fbwindow ( ) & & ! client - > fbwindow ( ) - > isIconic ( ) ) {
FluxboxWindow * win = client - > fbwindow ( ) ;
2002-12-01 13:42:15 +00:00
// make sure we have a valid win pointer with a valid screen
ScreenList : : iterator winscreen =
2003-04-25 16:00:03 +00:00
std : : find ( m_screen_list . begin ( ) , m_screen_list . end ( ) ,
2003-07-28 15:06:36 +00:00
& client - > screen ( ) ) ;
2003-04-25 16:00:03 +00:00
if ( winscreen = = m_screen_list . end ( ) ) {
m_focused_window = 0 ; // the window pointer wasn't valid, mark no window focused
2002-12-01 13:42:15 +00:00
} else {
screen = * winscreen ;
2003-07-28 15:06:36 +00:00
m_focused_window = client ; // update focused window
win - > setCurrentClient ( * client , false ) ; // don't setinputfocus
2003-04-25 16:00:03 +00:00
win - > setFocusFlag ( true ) ; // set focus flag
2002-12-01 13:42:15 +00:00
}
2003-09-12 22:55:33 +00:00
2002-12-01 13:42:15 +00:00
} else
2003-04-25 16:00:03 +00:00
m_focused_window = 0 ;
2002-12-01 13:42:15 +00:00
2003-06-25 06:02:53 +00:00
2003-09-12 22:55:33 +00:00
2004-01-19 18:33:05 +00:00
if ( screen ! = 0 ) {
2002-12-01 13:42:15 +00:00
screen - > updateNetizenWindowFocus ( ) ;
2004-04-18 21:16:06 +00:00
for ( AtomHandlerContainerIt it = m_atomhandler . begin ( ) ;
it ! = m_atomhandler . end ( ) ; it + + ) {
( * it ) . first - > updateFocusedWindow ( * screen , ( m_focused_window ?
2004-06-13 11:01:47 +00:00
m_focused_window - > window ( ) :
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-04-18 21:16:06 +00:00
for ( AtomHandlerContainerIt it = m_atomhandler . begin ( ) ;
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-04 23:38:06 +00:00
/**
* This function is called whenever we aren ' t quite sure what
* focus is meant to be , it ' ll make things right ; - )
* last_focused is set to something if we want to make use of the
* previously focused window ( it must NOT be set focused now , it
* is probably dying ) .
2003-10-05 02:31:23 +00:00
*
* ignore_event means that it ignores the given event until
* it gets a focusIn
2003-05-04 23:38:06 +00:00
*/
2003-12-30 20:56:41 +00:00
void Fluxbox : : revertFocus ( BScreen & screen ) {
2003-05-04 23:38:06 +00:00
// Relevant resources:
// resource.focus_last = whether we focus last focused when changing workspace
2003-12-19 00:35:08 +00:00
// BScreen::FocusModel = sloppy, click, whatever
2003-12-30 20:56:41 +00:00
WinClient * next_focus = screen . getLastFocusedWindow ( screen . currentWorkspaceID ( ) ) ;
2003-05-04 23:38:06 +00:00
2003-05-11 23:44:09 +00:00
// if setting focus fails, or isn't possible, fallback correctly
if ( ! ( next_focus & & next_focus - > fbwindow ( ) & &
2003-12-30 20:56:41 +00:00
next_focus - > fbwindow ( ) - > setCurrentClient ( * next_focus , true ) ) ) {
2003-05-11 15:24:09 +00:00
setFocusedWindow ( 0 ) ; // so we don't get dangling m_focused_window pointer
switch ( screen . getFocusModel ( ) ) {
2003-12-19 00:35:08 +00:00
case BScreen : : SLOPPYFOCUS :
case BScreen : : SEMISLOPPYFOCUS :
2003-05-04 23:38:06 +00:00
XSetInputFocus ( FbTk : : App : : instance ( ) - > display ( ) ,
PointerRoot , None , CurrentTime ) ;
break ;
2003-12-19 00:35:08 +00:00
case BScreen : : CLICKTOFOCUS :
screen . rootWindow ( ) . setInputFocus ( RevertToPointerRoot , CurrentTime ) ;
2003-05-04 23:38:06 +00:00
break ;
}
}
}
2004-03-21 09:00:25 +00:00
/*
* Like revertFocus , but specifically related to this window ( transients etc )
* if full_revert , we fallback to a full revertFocus if we can ' t find anything
* local to the client .
* If unfocus_frame is true , we won ' t focus anything in the same frame
* as the client .
*
* So , we first prefer to choose a transient parent , then the last
* client in this window , and if no luck ( or unfocus_frame ) , then
* we just use the normal revertFocus on the screen .
*
* assumption : client has focus
*/
void Fluxbox : : unfocusWindow ( WinClient & client , bool full_revert , bool unfocus_frame ) {
// go up the transient tree looking for a focusable window
FluxboxWindow * fbwin = client . fbwindow ( ) ;
if ( fbwin = = 0 )
unfocus_frame = false ;
WinClient * trans_parent = client . transientFor ( ) ;
while ( trans_parent ) {
if ( trans_parent - > fbwindow ( ) & & // can't focus if no fbwin
( ! unfocus_frame | | trans_parent - > fbwindow ( ) ! = fbwin ) & & // can't be this window
trans_parent - > fbwindow ( ) - > isVisible ( ) & &
trans_parent - > fbwindow ( ) - > setCurrentClient ( * trans_parent , m_focused_window = = & client ) ) {
return ;
}
trans_parent = trans_parent - > transientFor ( ) ;
}
if ( fbwin = = 0 )
return ; // nothing more we can do
BScreen & screen = fbwin - > screen ( ) ;
if ( ! unfocus_frame ) {
WinClient * last_focus = screen . getLastFocusedWindow ( * fbwin , & client ) ;
if ( last_focus ! = 0 & &
fbwin - > setCurrentClient ( * last_focus , m_focused_window = = & client ) ) {
return ;
}
}
if ( full_revert & & m_focused_window = = & client )
revertFocus ( screen ) ;
}
2003-05-04 23:38:06 +00:00
2003-05-10 14:32:35 +00:00
void Fluxbox : : watchKeyRelease ( BScreen & screen , unsigned int mods ) {
2003-04-27 04:56:18 +00:00
if ( mods = = 0 ) {
cerr < < " WARNING: attempt to grab without modifiers! " < < endl ;
return ;
}
2003-05-10 14:32:35 +00:00
m_watching_screen = & screen ;
2003-04-25 16:00:03 +00:00
m_watch_keyrelease = mods ;
XGrabKeyboard ( FbTk : : App : : instance ( ) - > display ( ) ,
2003-05-10 23:07:42 +00:00
screen . rootWindow ( ) . window ( ) , True ,
2003-04-15 00:50:25 +00:00
GrabModeAsync , GrabModeAsync , CurrentTime ) ;
}