2002-01-09 14:11:20 +00:00
// Screen.cc for Fluxbox Window Manager
2005-01-24 18:34:57 +00:00
// Copyright (c) 2001 - 2005 Henrik Kinnunen (fluxgen at fluxbox dot org)
2002-01-09 14:11:20 +00:00
//
2001-12-11 20:47:02 +00:00
// Screen.cc for Blackbox - an X11 Window manager
2002-12-13 20:19:05 +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,
2002-05-08 10:14:51 +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-17 01:21:50 +00:00
// $Id$
2002-10-25 20:58:14 +00:00
# include "Screen.hh"
# include "fluxbox.hh"
# include "Window.hh"
# include "Workspace.hh"
2002-11-17 11:29:06 +00:00
# include "Netizen.hh"
2004-05-02 21:12:22 +00:00
// themes
2003-04-25 11:05:11 +00:00
# include "FbWinFrameTheme.hh"
2003-01-07 02:06:06 +00:00
# include "MenuTheme.hh"
2003-04-25 11:05:11 +00:00
# include "RootTheme.hh"
2003-04-28 22:43:26 +00:00
# include "WinButtonTheme.hh"
2004-05-02 21:12:22 +00:00
# include "SlitTheme.hh"
// menu items
2003-01-12 17:59:20 +00:00
# include "BoolMenuItem.hh"
2003-02-17 12:35:59 +00:00
# include "IntResMenuItem.hh"
2004-05-02 21:12:22 +00:00
# include "FocusModelMenuItem.hh"
// menus
2003-02-18 15:11:12 +00:00
# include "FbMenu.hh"
# include "LayerMenu.hh"
2004-05-02 21:12:22 +00:00
# include "MenuCreator.hh"
2003-04-14 15:01:55 +00:00
# include "WinClient.hh"
2003-05-15 11:17:29 +00:00
# include "FbWinFrame.hh"
2003-06-18 13:42:21 +00:00
# include "Strut.hh"
2003-06-30 15:31:54 +00:00
# include "CommandParser.hh"
2004-04-19 22:44:42 +00:00
# include "AtomHandler.hh"
2004-09-11 13:33:07 +00:00
# include "HeadArea.hh"
2002-01-09 14:11:20 +00:00
2004-05-02 21:12:22 +00:00
2004-06-07 11:46:05 +00:00
# include "FbTk/I18n.hh"
2003-12-19 00:34:23 +00:00
# include "FbTk/Subject.hh"
2004-05-02 21:12:22 +00:00
# include "FbTk/FbWindow.hh"
2003-12-19 00:34:23 +00:00
# include "FbTk/SimpleCommand.hh"
# include "FbTk/MultLayers.hh"
# include "FbTk/XLayerItem.hh"
# include "FbTk/MacroCommand.hh"
# include "FbTk/StringUtil.hh"
# include "FbTk/ImageControl.hh"
2004-04-19 22:44:42 +00:00
# include "FbTk/EventManager.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"
2003-12-19 00:34:23 +00:00
2002-03-18 20:20:09 +00:00
//use GNU extensions
2001-12-11 20:47:02 +00:00
# ifndef _GNU_SOURCE
# define _GNU_SOURCE
# endif // _GNU_SOURCE
2002-10-13 22:30:18 +00:00
# ifdef HAVE_CONFIG_H
# include "config.h"
2001-12-11 20:47:02 +00:00
# endif // HAVE_CONFIG_H
2002-10-13 22:30:18 +00:00
# ifdef SLIT
2001-12-11 20:47:02 +00:00
# include "Slit.hh"
2004-04-19 22:44:42 +00:00
# include "SlitClient.hh"
2003-10-28 17:39:59 +00:00
# else
// fill it in
class Slit { } ;
2001-12-11 20:47:02 +00:00
# endif // SLIT
2002-02-04 07:01:06 +00:00
# ifdef STDC_HEADERS
2002-10-25 20:58:14 +00:00
# include <sys/types.h>
2001-12-11 20:47:02 +00:00
# endif // STDC_HEADERS
2002-02-04 07:01:06 +00:00
# ifdef HAVE_CTYPE_H
2002-10-25 20:58:14 +00:00
# include <ctype.h>
2001-12-11 20:47:02 +00:00
# endif // HAVE_CTYPE_H
2002-02-04 07:01:06 +00:00
# ifdef HAVE_UNISTD_H
2002-10-25 20:58:14 +00:00
# include <sys/types.h>
# include <unistd.h>
2001-12-11 20:47:02 +00:00
# endif // HAVE_UNISTD_H
2002-02-04 07:01:06 +00:00
# ifdef HAVE_STDARG_H
2002-10-25 20:58:14 +00:00
# include <stdarg.h>
2001-12-11 20:47:02 +00:00
# endif // HAVE_STDARG_H
2002-11-27 21:55:36 +00:00
# ifdef TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>
# else // !TIME_WITH_SYS_TIME
# ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
# else // !HAVE_SYS_TIME_H
# include <time.h>
# endif // HAVE_SYS_TIME_H
# endif // TIME_WITH_SYS_TIME
2002-01-27 12:45:32 +00:00
# include <X11/Xatom.h>
# include <X11/keysym.h>
2003-06-12 15:24:37 +00:00
# include <X11/cursorfont.h>
2002-01-27 12:45:32 +00:00
2003-05-19 14:26:30 +00:00
# ifdef XINERAMA
extern " C " {
# include <X11/extensions/Xinerama.h>
}
# endif // XINERAMA
2001-12-11 20:47:02 +00:00
# include <iostream>
2002-01-20 02:17:23 +00:00
# include <memory>
2002-02-08 13:35:20 +00:00
# include <algorithm>
2003-04-14 15:01:55 +00:00
# include <functional>
2004-05-02 21:12:22 +00:00
# include <stack>
2002-01-20 02:17:23 +00:00
2001-12-11 20:47:02 +00:00
using namespace std ;
2002-04-04 14:28:54 +00:00
static bool running = true ;
2002-10-25 20:58:14 +00:00
namespace {
2001-12-11 20:47:02 +00:00
2002-10-25 20:58:14 +00:00
int anotherWMRunning ( Display * display , XErrorEvent * ) {
2004-06-07 11:46:05 +00:00
_FB_USES_NLS ;
cerr < < _FBTEXT ( Screen , AnotherWMRunning ,
" BScreen::BScreen: an error occured while querying the X server. \n "
" another window manager already running on display " ,
" Message when another WM is found already active on all screens " )
< < DisplayString ( display ) < < endl ;
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
running = false ;
2001-12-11 20:47:02 +00:00
2003-05-17 11:05:33 +00:00
return - 1 ;
2001-12-11 20:47:02 +00:00
}
2003-02-16 16:45:23 +00:00
2003-01-09 17:41:02 +00:00
2004-05-02 21:12:22 +00:00
} // end anonymous namespace
2002-01-20 02:17:23 +00:00
2003-01-12 23:56:49 +00:00
2003-05-18 22:01:14 +00:00
BScreen : : ScreenResource : : ScreenResource ( FbTk : : ResourceManager & rm ,
2003-02-15 02:03:09 +00:00
const std : : string & scrname ,
const std : : string & altscrname ) :
2002-12-01 13:42:15 +00:00
image_dither ( rm , false , scrname + " .imageDither " , altscrname + " .ImageDither " ) ,
2003-12-19 00:34:23 +00:00
opaque_move ( rm , false , scrname + " .opaqueMove " , altscrname + " .OpaqueMove " ) ,
2002-12-01 13:42:15 +00:00
full_max ( rm , true , scrname + " .fullMaximization " , altscrname + " .FullMaximization " ) ,
2003-04-15 12:22:52 +00:00
sloppy_window_grouping ( rm , true ,
scrname + " .sloppywindowgrouping " , altscrname + " .SloppyWindowGrouping " ) ,
2002-12-01 13:42:15 +00:00
workspace_warping ( rm , true , scrname + " .workspacewarping " , altscrname + " .WorkspaceWarping " ) ,
desktop_wheeling ( rm , true , scrname + " .desktopwheeling " , altscrname + " .DesktopWheeling " ) ,
show_window_pos ( rm , true , scrname + " .showwindowposition " , altscrname + " .ShowWindowPosition " ) ,
focus_last ( rm , true , scrname + " .focusLastWindow " , altscrname + " .FocusLastWindow " ) ,
focus_new ( rm , true , scrname + " .focusNewWindows " , altscrname + " .FocusNewWindows " ) ,
antialias ( rm , false , scrname + " .antialias " , altscrname + " .Antialias " ) ,
2003-02-22 16:09:44 +00:00
auto_raise ( rm , false , scrname + " .autoRaise " , altscrname + " .AutoRaise " ) ,
2003-04-16 00:38:06 +00:00
click_raises ( rm , true , scrname + " .clickRaises " , altscrname + " .ClickRaises " ) ,
2004-03-30 13:48:38 +00:00
decorate_transient ( rm , false , scrname + " .decorateTransient " , altscrname + " .DecorateTransient " ) ,
2002-12-01 13:42:15 +00:00
rootcommand ( rm , " " , scrname + " .rootCommand " , altscrname + " .RootCommand " ) ,
2004-10-18 01:24:24 +00:00
resize_model ( rm , BOTTOMRESIZE , scrname + " .resizeMode " , altscrname + " .ResizeMode " ) ,
2004-05-02 21:12:22 +00:00
windowmenufile ( rm , " " , scrname + " .windowMenu " , altscrname + " .WindowMenu " ) ,
2003-12-19 00:34:23 +00:00
focus_model ( rm , CLICKTOFOCUS , scrname + " .focusModel " , altscrname + " .FocusModel " ) ,
2004-10-16 22:18:56 +00:00
follow_model ( rm , IGNORE_OTHER_WORKSPACES , scrname + " .followModel " , altscrname + " .followModel " ) ,
2002-12-01 13:42:15 +00:00
workspaces ( rm , 1 , scrname + " .workspaces " , altscrname + " .Workspaces " ) ,
edge_snap_threshold ( rm , 0 , scrname + " .edgeSnapThreshold " , altscrname + " .EdgeSnapThreshold " ) ,
2004-09-12 14:56:20 +00:00
focused_alpha ( rm , 255 , scrname + " .window.focus.alpha " , altscrname + " .Window.Focus.Alpha " ) ,
unfocused_alpha ( rm , 255 , scrname + " .window.unfocus.alpha " , altscrname + " .Window.Unfocus.Alpha " ) ,
menu_alpha ( rm , 255 , scrname + " .menu.alpha " , altscrname + " .Menu.Alpha " ) ,
2003-12-12 18:18:49 +00:00
menu_delay ( rm , 0 , scrname + " .menuDelay " , altscrname + " .MenuDelay " ) ,
menu_delay_close ( rm , 0 , scrname + " .menuDelayClose " , altscrname + " .MenuDelayClose " ) ,
2003-12-19 00:34:23 +00:00
menu_mode ( rm , FbTk : : MenuTheme : : DELAY_OPEN , scrname + " .menuMode " , altscrname + " .MenuMode " ) ,
placement_policy ( rm , ROWSMARTPLACEMENT , scrname + " .windowPlacement " , altscrname + " .WindowPlacement " ) ,
row_direction ( rm , LEFTRIGHT , scrname + " .rowPlacementDirection " , altscrname + " .RowPlacementDirection " ) ,
2004-03-22 21:01:42 +00:00
col_direction ( rm , TOPBOTTOM , scrname + " .colPlacementDirection " , altscrname + " .ColPlacementDirection " ) ,
gc_line_width ( rm , 1 , scrname + " .overlay.lineWidth " , altscrname + " .Overlay.LineWidth " ) ,
gc_line_style ( rm ,
FbTk : : GContext : : LINESOLID ,
scrname + " .overlay.lineStyle " ,
altscrname + " .Overlay.LineStyle " ) ,
gc_join_style ( rm ,
FbTk : : GContext : : JOINMITER ,
scrname + " .overlay.joinStyle " ,
altscrname + " .Overlay.JoinStyle " ) ,
gc_cap_style ( rm ,
FbTk : : GContext : : CAPNOTLAST ,
scrname + " .overlay.capStyle " ,
altscrname + " .overlay.CapStyle " ) {
2002-01-20 02:17:23 +00:00
2003-12-19 00:34:23 +00:00
}
2002-01-20 02:17:23 +00:00
2003-05-18 22:01:14 +00:00
BScreen : : BScreen ( FbTk : : ResourceManager & rm ,
2002-12-01 13:42:15 +00:00
const string & screenname , const string & altscreenname ,
2003-04-28 00:38:42 +00:00
int scrn , int num_layers ) :
m_clientlist_sig ( * this ) , // client signal
2003-09-08 16:37:27 +00:00
m_iconlist_sig ( * this ) , // icon list signal
2003-04-28 00:38:42 +00:00
m_workspacecount_sig ( * this ) , // workspace count signal
m_workspacenames_sig ( * this ) , // workspace names signal
2004-01-19 18:29:43 +00:00
m_workspace_area_sig ( * this ) , // workspace area signal
2003-04-28 00:38:42 +00:00
m_currentworkspace_sig ( * this ) , // current workspace signal
2003-07-01 12:39:09 +00:00
m_reconfigure_sig ( * this ) , // reconfigure signal
2003-08-24 13:07:01 +00:00
m_resize_sig ( * this ) ,
2003-04-28 00:38:42 +00:00
m_layermanager ( num_layers ) ,
cycling_focus ( false ) ,
cycling_last ( 0 ) ,
m_windowtheme ( new FbWinFrameTheme ( scrn ) ) ,
2003-04-28 22:43:26 +00:00
// the order of windowtheme and winbutton theme is important
// because winbutton need to rescale the pixmaps in winbutton theme
// after fbwinframe have resized them
2003-08-22 15:03:28 +00:00
m_winbutton_theme ( new WinButtonTheme ( scrn , * m_windowtheme ) ) ,
2003-07-10 11:29:45 +00:00
m_menutheme ( new MenuTheme ( scrn ) ) ,
2003-04-28 00:38:42 +00:00
m_root_theme ( new
RootTheme ( scrn ,
* resource . rootcommand ) ) ,
2003-05-10 22:59:32 +00:00
m_root_window ( scrn ) ,
2004-09-16 10:10:37 +00:00
m_geom_window ( m_root_window ,
0 , 0 , 10 , 10 ,
false , // override redirect
true ) , // save under
m_pos_window ( m_root_window ,
0 , 0 , 10 , 10 ,
false , // override redirect
true ) , // save under
2003-04-28 22:43:26 +00:00
resource ( rm , screenname , altscreenname ) ,
2003-06-20 01:30:08 +00:00
m_name ( screenname ) ,
m_altname ( altscreenname ) ,
m_resource_manager ( rm ) ,
2003-08-12 12:21:42 +00:00
m_xinerama_headinfo ( 0 ) ,
m_shutdown ( false ) {
2003-04-28 00:38:42 +00:00
2003-12-29 01:23:04 +00:00
2004-09-09 14:29:10 +00:00
Fluxbox * fluxbox = Fluxbox : : instance ( ) ;
Display * disp = fluxbox - > display ( ) ;
2001-12-11 20:47:02 +00:00
2003-05-19 15:32:47 +00:00
initXinerama ( ) ;
2003-05-19 14:26:30 +00:00
2003-06-20 01:48:06 +00:00
// setup error handler to catch "screen already managed by other wm"
2002-12-01 13:42:15 +00:00
XErrorHandler old = XSetErrorHandler ( ( XErrorHandler ) anotherWMRunning ) ;
2003-06-12 15:24:37 +00:00
rootWindow ( ) . setEventMask ( ColormapChangeMask | EnterWindowMask | PropertyChangeMask |
SubstructureRedirectMask | KeyPressMask | KeyReleaseMask |
ButtonPressMask | ButtonReleaseMask | SubstructureNotifyMask ) ;
2003-05-12 04:28:46 +00:00
2004-09-09 14:29:10 +00:00
fluxbox - > sync ( false ) ;
2003-06-12 15:24:37 +00:00
2002-12-01 13:42:15 +00:00
XSetErrorHandler ( ( XErrorHandler ) old ) ;
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
managed = running ;
if ( ! managed )
return ;
2004-09-11 13:33:07 +00:00
// TODO fluxgen: check if this is the right place
m_head_areas = new HeadArea [ numHeads ( ) ? numHeads ( ) : 1 ] ;
2001-12-11 20:47:02 +00:00
2004-06-07 11:46:05 +00:00
_FB_USES_NLS ;
2001-12-11 20:47:02 +00:00
2004-06-07 11:46:05 +00:00
fprintf ( stderr , _FBTEXT ( Screen , ManagingScreen ,
" BScreen::BScreen: managing screen %d "
" using visual 0x%lx, depth %d \n " ,
" informational message saying screen number (%d), visual (%lx), and colour depth (%d) " ) ,
2003-05-15 12:00:46 +00:00
screenNumber ( ) , XVisualIDFromVisual ( rootWindow ( ) . visual ( ) ) ,
2003-05-10 22:59:32 +00:00
rootWindow ( ) . depth ( ) ) ;
2002-12-01 13:42:15 +00:00
2003-04-15 00:50:25 +00:00
cycling_window = focused_list . end ( ) ;
2003-06-12 15:24:37 +00:00
rootWindow ( ) . setCursor ( XCreateFontCursor ( disp , XC_left_ptr ) ) ;
2001-12-11 20:47:02 +00:00
2003-10-31 10:37:09 +00:00
// load this screens resources
fluxbox - > load_rc ( * this ) ;
2003-06-20 01:48:06 +00:00
// setup image cache engine
2003-05-15 23:30:07 +00:00
m_image_control . reset ( new FbTk : : ImageControl ( scrn , true , fluxbox - > colorsPerChannel ( ) ,
2003-06-12 15:24:37 +00:00
fluxbox - > getCacheLife ( ) , fluxbox - > getCacheMax ( ) ) ) ;
2003-05-15 23:30:07 +00:00
imageControl ( ) . installRootColormap ( ) ;
2002-12-01 13:42:15 +00:00
root_colormap_installed = true ;
2001-12-11 20:47:02 +00:00
2004-09-12 14:56:20 +00:00
m_windowtheme - > setFocusedAlpha ( * resource . focused_alpha ) ;
m_windowtheme - > setUnfocusedAlpha ( * resource . unfocused_alpha ) ;
2003-07-19 03:59:56 +00:00
m_menutheme - > setAlpha ( * resource . menu_alpha ) ;
2003-12-12 18:18:49 +00:00
m_menutheme - > setMenuMode ( * resource . menu_mode ) ;
2003-12-18 15:27:21 +00:00
// clamp values
if ( * resource . menu_delay > 5000 )
* resource . menu_delay = 5000 ;
if ( * resource . menu_delay < 0 )
* resource . menu_delay = 0 ;
if ( * resource . menu_delay_close > 5000 )
* resource . menu_delay_close = 5000 ;
if ( * resource . menu_delay_close < 0 )
* resource . menu_delay_close = 0 ;
2003-12-12 18:18:49 +00:00
m_menutheme - > setDelayOpen ( * resource . menu_delay ) ;
m_menutheme - > setDelayClose ( * resource . menu_delay_close ) ;
2003-04-25 11:05:11 +00:00
2003-05-15 23:30:07 +00:00
imageControl ( ) . setDither ( * resource . image_dither ) ;
2002-01-11 10:21:44 +00:00
2003-06-25 05:47:23 +00:00
// setup windowtheme for antialias
2003-05-07 11:36:43 +00:00
// before we load the theme
2003-06-20 01:48:06 +00:00
2003-04-25 11:05:11 +00:00
winFrameTheme ( ) . font ( ) . setAntialias ( * resource . antialias ) ;
2003-12-18 18:03:23 +00:00
menuTheme ( ) . titleFont ( ) . setAntialias ( * resource . antialias ) ;
menuTheme ( ) . frameFont ( ) . setAntialias ( * resource . antialias ) ;
2003-02-17 12:35:59 +00:00
2003-06-20 01:48:06 +00:00
2003-08-25 13:15:53 +00:00
winFrameTheme ( ) . reconfigSig ( ) . attach ( this ) ; // for geom window
2004-09-16 10:10:37 +00:00
2002-12-01 13:42:15 +00:00
geom_visible = false ;
2003-06-12 15:24:37 +00:00
geom_pixmap = 0 ;
2004-01-16 11:47:07 +00:00
pos_visible = false ;
pos_pixmap = 0 ;
2004-09-16 10:10:37 +00:00
renderGeomWindow ( ) ;
2004-01-16 11:47:07 +00:00
renderPosWindow ( ) ;
2003-06-20 01:48:06 +00:00
// setup workspaces and workspace menu
2005-04-27 09:52:30 +00:00
int nr_ws = * resource . workspaces ;
addWorkspace ( ) ; // at least one
for ( int i = 1 ; i < nr_ws ; + + i ) {
addWorkspace ( ) ;
2002-12-01 13:42:15 +00:00
}
2003-05-19 22:45:51 +00:00
m_current_workspace = m_workspaces_list . front ( ) ;
2001-12-11 20:47:02 +00:00
2003-06-25 05:47:23 +00:00
//!! TODO: we shouldn't do this more than once, but since slit handles their
2003-06-23 13:31:47 +00:00
// own resources we must do this.
fluxbox - > load_rc ( * this ) ;
2004-06-07 11:46:05 +00:00
m_configmenu . reset ( createMenu ( _FBTEXT ( Menu , Configuration , " Configuration " , " Title of configuration menu " ) ) ) ;
2003-01-12 17:59:20 +00:00
setupConfigmenu ( * m_configmenu . get ( ) ) ;
2003-04-18 12:51:14 +00:00
m_configmenu - > setInternalMenu ( ) ;
2003-01-12 17:59:20 +00:00
2002-12-01 13:42:15 +00:00
// start with workspace 0
changeWorkspaceID ( 0 ) ;
updateNetizenWorkspaceCount ( ) ;
2003-12-31 00:38:40 +00:00
// we need to load win frame theme before we create any fluxbox window
// and after we've load the resources
// else we get some bad handle/grip height/width
2004-01-02 13:29:01 +00:00
// FbTk::ThemeManager::instance().loadTheme(*m_windowtheme.get());
//!! TODO: For some strange reason we must load everything,
// else the focus label doesn't get updated
// So we lock root theme temporary so it doesn't uses RootTheme::reconfigTheme
// This must be fixed in the future.
m_root_theme - > lock ( true ) ;
2005-03-16 22:44:48 +00:00
FbTk : : ThemeManager : : instance ( ) . load ( fluxbox - > getStyleFilename ( ) ,
m_root_theme - > screenNum ( ) ) ;
2004-01-02 13:29:01 +00:00
m_root_theme - > lock ( false ) ;
2004-03-22 21:01:42 +00:00
m_root_theme - > setLineAttributes ( * resource . gc_line_width ,
* resource . gc_line_style ,
* resource . gc_cap_style ,
* resource . gc_join_style ) ;
2003-12-31 00:38:40 +00:00
2004-06-07 21:22:42 +00:00
# ifdef SLIT
2004-09-09 14:29:10 +00:00
m_slit . reset ( new Slit ( * this , * layerManager ( ) . getLayer ( fluxbox - > getDesktopLayer ( ) ) ,
fluxbox - > getSlitlistFilename ( ) . c_str ( ) ) ) ;
2004-06-07 21:22:42 +00:00
# endif // SLIT
2004-04-19 22:44:42 +00:00
rm . unlock ( ) ;
XFlush ( disp ) ;
}
template < typename A >
void destroyAndClearList ( A & a ) {
typedef typename A : : iterator iterator ;
iterator it = a . begin ( ) ;
iterator it_end = a . end ( ) ;
for ( ; it ! = it_end ; + + it )
delete ( * it ) ;
a . clear ( ) ;
}
BScreen : : ~ BScreen ( ) {
2004-09-05 01:11:41 +00:00
2004-04-19 22:44:42 +00:00
if ( ! managed )
return ;
2004-09-06 13:17:56 +00:00
if ( m_rootmenu . get ( ) ! = 0 )
m_rootmenu - > removeAll ( ) ;
2004-09-05 01:11:41 +00:00
// Since workspacemenu holds client list menus (from workspace)
// we need to destroy it before we destroy workspaces
m_workspacemenu . reset ( 0 ) ;
2004-04-19 22:44:42 +00:00
if ( geom_pixmap ! = None )
imageControl ( ) . removeImage ( geom_pixmap ) ;
if ( pos_pixmap ! = None )
imageControl ( ) . removeImage ( pos_pixmap ) ;
removeWorkspaceNames ( ) ;
destroyAndClearList ( m_workspaces_list ) ;
destroyAndClearList ( m_netizen_list ) ;
2004-11-20 18:12:51 +00:00
//why not destroyAndClearList(m_icon_list); ?
//problem with that: a delete FluxboxWindow* calls m_diesig.notify()
//which leads to screen.removeWindow() which leads to removeIcon(win)
//which would modify the m_icon_list anyways...
Icons tmp ;
tmp = m_icon_list ;
while ( ! tmp . empty ( ) ) {
removeWindow ( tmp . back ( ) ) ;
tmp . back ( ) - > restore ( true ) ;
delete ( tmp . back ( ) ) ;
tmp . pop_back ( ) ;
}
2004-04-19 22:44:42 +00:00
if ( hasXinerama ( ) & & m_xinerama_headinfo ) {
delete [ ] m_xinerama_headinfo ;
}
2004-09-11 13:33:07 +00:00
2004-11-20 18:12:51 +00:00
// slit must be destroyed before headAreas (Struts)
m_slit . reset ( 0 ) ;
2004-09-11 13:33:07 +00:00
// TODO fluxgen: check if this is the right place
delete [ ] m_head_areas ;
2004-04-19 22:44:42 +00:00
}
void BScreen : : initWindows ( ) {
2002-12-01 13:42:15 +00:00
unsigned int nchild ;
Window r , p , * children ;
2004-04-19 22:44:42 +00:00
Display * disp = FbTk : : App : : instance ( ) - > display ( ) ;
2003-05-10 22:59:32 +00:00
XQueryTree ( disp , rootWindow ( ) . window ( ) , & r , & p , & children , & nchild ) ;
2001-12-11 20:47:02 +00:00
2004-07-14 12:13:29 +00:00
Fluxbox * fluxbox = Fluxbox : : instance ( ) ;
2002-12-01 13:42:15 +00:00
// preen the window list of all icon windows... for better dockapp support
2004-09-09 14:29:10 +00:00
for ( unsigned int i = 0 ; i < nchild ; i + + ) {
2004-11-22 19:40:34 +00:00
2004-07-14 18:28:05 +00:00
if ( children [ i ] = = None )
2004-07-14 12:13:29 +00:00
continue ;
2002-12-01 13:42:15 +00:00
2004-04-19 22:44:42 +00:00
XWMHints * wmhints = XGetWMHints ( disp , children [ i ] ) ;
2002-12-01 13:42:15 +00:00
if ( wmhints ) {
if ( ( wmhints - > flags & IconWindowHint ) & &
( wmhints - > icon_window ! = children [ i ] ) )
2004-09-09 14:29:10 +00:00
for ( unsigned int j = 0 ; j < nchild ; j + + ) {
2002-12-01 13:42:15 +00:00
if ( children [ j ] = = wmhints - > icon_window ) {
2004-07-14 18:28:05 +00:00
# ifdef DEBUG
cerr < < " BScreen::initWindows(): children[j] = 0x " < < hex < < children [ j ] < < dec < < endl ;
cerr < < " BScreen::initWindows(): = icon_window " < < endl ;
# endif // DEBUG
2002-12-01 13:42:15 +00:00
children [ j ] = None ;
break ;
}
}
XFree ( wmhints ) ;
}
2004-07-14 12:13:29 +00:00
2002-12-01 13:42:15 +00:00
}
// manage shown windows
2004-07-14 18:28:05 +00:00
// complexity: O(n^2) if we have lots of transients to transient_for
// but usually O(n)
2004-11-22 19:40:34 +00:00
Window transient_for = 0 ;
2004-09-09 14:29:10 +00:00
for ( unsigned int i = 0 ; i < nchild ; + + i ) {
2004-07-14 18:28:05 +00:00
if ( children [ i ] = = None )
continue ;
else if ( ! fluxbox - > validateWindow ( children [ i ] ) ) {
# ifdef DEBUG
cerr < < " BScreen::initWindows(): not valid window = " < < hex < < children [ i ] < < dec < < endl ;
# endif // DEBUG
children [ i ] = None ;
continue ;
2004-07-14 12:13:29 +00:00
}
2002-12-01 13:42:15 +00:00
2004-07-14 18:28:05 +00:00
// if we have a transient_for window and it isn't created yet...
// postpone creation of this window and find transient_for window
2004-11-22 19:40:34 +00:00
// in the list and swap place with it so we can create transient_for window
2004-07-14 18:28:05 +00:00
// first
if ( XGetTransientForHint ( disp , children [ i ] , & transient_for ) & &
fluxbox - > searchWindow ( transient_for ) = = 0 ) {
// search forward for transient_for
// and swap place with it so it gets created first
2004-09-09 14:29:10 +00:00
unsigned int j = i + 1 ;
2004-07-14 18:28:05 +00:00
for ( ; j < nchild ; + + j ) {
2004-11-22 19:40:34 +00:00
if ( children [ j ] = = transient_for ) {
2004-07-14 18:28:05 +00:00
swap ( children [ i ] , children [ j ] ) ;
break ;
}
}
// reevaluate window
if ( ! fluxbox - > validateWindow ( children [ i ] ) )
continue ;
2004-11-22 19:40:34 +00:00
2004-07-14 12:13:29 +00:00
# ifdef DEBUG
2004-07-14 18:28:05 +00:00
cerr < < " BScreen::initWindows(): j = " < < j < < " i = " < < i < < " nchild = " < < nchild < < endl ;
2004-07-14 12:13:29 +00:00
# endif // DEBUG
2004-11-22 19:40:34 +00:00
2004-07-14 18:28:05 +00:00
# ifdef DEBUG
if ( j < nchild )
cerr < < " BScreen::initWindows(): postpone creation of 0x " < < hex < < children [ j ] < < dec < < endl ;
else
cerr < < " BScreen::initWindows(): postpone creation of 0x " < < hex < < children [ i ] < < dec < < endl ;
cerr < < " BScreen::initWindows(): transient_for = 0x " < < hex < < transient_for < < dec < < endl ;
# endif // DEBUG
}
2004-07-14 12:13:29 +00:00
2004-11-22 19:40:34 +00:00
2004-07-14 18:28:05 +00:00
XWindowAttributes attrib ;
if ( XGetWindowAttributes ( disp , children [ i ] ,
& attrib ) ) {
if ( attrib . override_redirect ) {
children [ i ] = None ; // we dont need this anymore, since we already created a window for it
continue ;
}
2004-07-14 12:13:29 +00:00
2004-07-14 18:28:05 +00:00
if ( attrib . map_state ! = IsUnmapped ) {
FluxboxWindow * win = createWindow ( children [ i ] ) ;
2003-01-05 22:26:56 +00:00
2004-07-14 18:28:05 +00:00
if ( win ) {
XMapRequestEvent mre ;
mre . window = children [ i ] ;
win - > mapRequestEvent ( mre ) ;
2002-12-01 13:42:15 +00:00
}
}
}
2004-07-14 18:28:05 +00:00
children [ i ] = None ; // we dont need this anymore, since we already created a window for it
2002-12-01 13:42:15 +00:00
}
2004-07-14 18:28:05 +00:00
2002-12-01 13:42:15 +00:00
XFree ( children ) ;
2003-08-11 16:27:23 +00:00
2001-12-11 20:47:02 +00:00
}
2003-05-15 12:00:46 +00:00
unsigned int BScreen : : currentWorkspaceID ( ) const {
2003-05-19 22:45:51 +00:00
return m_current_workspace - > workspaceID ( ) ;
2003-04-25 11:05:11 +00:00
}
2003-04-25 11:56:13 +00:00
2004-09-11 13:33:07 +00:00
const Strut * BScreen : : availableWorkspaceArea ( int head ) const {
return m_head_areas [ head ? head - 1 : 0 ] . availableWorkspaceArea ( ) ;
}
2003-05-20 11:03:11 +00:00
unsigned int BScreen : : maxLeft ( int head ) const {
2004-09-11 13:33:07 +00:00
2003-06-30 18:04:48 +00:00
// we ignore strut if we're doing full maximization
2003-05-20 11:03:11 +00:00
if ( hasXinerama ( ) )
2003-06-30 18:04:48 +00:00
return doFullMax ( ) ? getHeadX ( head ) :
2004-09-11 13:33:07 +00:00
getHeadX ( head ) + availableWorkspaceArea ( head ) - > left ( ) ;
2003-06-30 18:04:48 +00:00
else
2004-09-11 13:33:07 +00:00
return doFullMax ( ) ? 0 : availableWorkspaceArea ( head ) - > left ( ) ;
2003-01-05 22:26:56 +00:00
}
2003-05-20 11:03:11 +00:00
unsigned int BScreen : : maxRight ( int head ) const {
2003-06-30 18:04:48 +00:00
// we ignore strut if we're doing full maximization
2003-05-20 11:03:11 +00:00
if ( hasXinerama ( ) )
2003-06-30 18:04:48 +00:00
return doFullMax ( ) ? getHeadX ( head ) + getHeadWidth ( head ) :
2004-09-11 13:33:07 +00:00
getHeadX ( head ) + getHeadWidth ( head ) - availableWorkspaceArea ( head ) - > right ( ) ;
2003-06-30 18:04:48 +00:00
else
2004-09-11 13:33:07 +00:00
return doFullMax ( ) ? width ( ) : width ( ) - availableWorkspaceArea ( head ) - > right ( ) ;
2003-01-05 22:26:56 +00:00
}
2003-05-20 11:03:11 +00:00
unsigned int BScreen : : maxTop ( int head ) const {
2003-06-30 18:04:48 +00:00
// we ignore strut if we're doing full maximization
2004-11-22 19:40:34 +00:00
2003-05-20 11:03:11 +00:00
if ( hasXinerama ( ) )
2004-09-11 13:33:07 +00:00
return doFullMax ( ) ? getHeadY ( head ) : getHeadY ( head ) + availableWorkspaceArea ( head ) - > top ( ) ;
2003-06-30 18:04:48 +00:00
else
2004-09-11 13:33:07 +00:00
return doFullMax ( ) ? 0 : availableWorkspaceArea ( head ) - > top ( ) ;
2003-01-05 22:26:56 +00:00
}
2003-05-19 22:45:51 +00:00
2003-05-20 11:03:11 +00:00
unsigned int BScreen : : maxBottom ( int head ) const {
2003-06-30 18:04:48 +00:00
// we ignore strut if we're doing full maximization
2003-05-20 11:03:11 +00:00
if ( hasXinerama ( ) )
2003-06-30 18:04:48 +00:00
return doFullMax ( ) ? getHeadY ( head ) + getHeadHeight ( head ) :
2004-09-11 13:33:07 +00:00
getHeadY ( head ) + getHeadHeight ( head ) - availableWorkspaceArea ( head ) - > bottom ( ) ;
2003-06-30 18:04:48 +00:00
else
2004-09-11 13:33:07 +00:00
return doFullMax ( ) ? height ( ) : height ( ) - availableWorkspaceArea ( head ) - > bottom ( ) ;
2003-01-05 22:26:56 +00:00
}
2003-08-25 13:15:53 +00:00
void BScreen : : update ( FbTk : : Subject * subj ) {
// for now we're only listening to the theme sig, so no object check
// if another signal is added later, will need to differentiate here
renderGeomWindow ( ) ;
2004-01-16 11:47:07 +00:00
renderPosWindow ( ) ;
2003-08-25 13:15:53 +00:00
}
2003-12-10 23:08:06 +00:00
FbTk : : Menu * BScreen : : createMenu ( const std : : string & label ) {
2003-12-18 18:03:23 +00:00
FbTk : : Menu * menu = new FbMenu ( menuTheme ( ) ,
2003-12-10 23:08:06 +00:00
imageControl ( ) ,
* layerManager ( ) . getLayer ( Fluxbox : : instance ( ) - > getMenuLayer ( ) ) ) ;
if ( ! label . empty ( ) )
menu - > setLabel ( label . c_str ( ) ) ;
return menu ;
}
2004-01-11 16:06:22 +00:00
void BScreen : : hideMenus ( ) {
// hide extra menus
Fluxbox : : instance ( ) - > hideExtraMenus ( * this ) ;
# ifdef SLIT
// hide slit menu
if ( slit ( ) )
slit ( ) - > menu ( ) . hide ( ) ;
# endif // SLIT
// hide icon menus
if ( getIconList ( ) . size ( ) ) {
Icons : : iterator it = getIconList ( ) . begin ( ) ;
const Icons : : iterator it_end = getIconList ( ) . end ( ) ;
for ( ; it ! = it_end ; + + it )
( * it ) - > menu ( ) . hide ( ) ;
}
// hide all client menus
2004-04-12 23:05:10 +00:00
hideWindowMenus ( ) ;
}
void BScreen : : hideWindowMenus ( const FluxboxWindow * except ) {
2004-01-11 16:06:22 +00:00
Workspaces : : iterator w_it = getWorkspacesList ( ) . begin ( ) ;
const Workspaces : : iterator w_it_end = getWorkspacesList ( ) . end ( ) ;
for ( ; w_it ! = w_it_end ; + + w_it ) {
if ( ( * w_it ) - > windowList ( ) . size ( ) ) {
Workspace : : Windows : : iterator win_it = ( * w_it ) - > windowList ( ) . begin ( ) ;
const Workspace : : Windows : : iterator win_it_end = ( * w_it ) - > windowList ( ) . end ( ) ;
for ( ; win_it ! = win_it_end ; + + win_it ) {
2004-04-12 23:05:10 +00:00
if ( * win_it ! = except )
2004-09-05 01:11:41 +00:00
( * win_it ) - > menu ( ) . hide ( ) ;
2004-01-11 16:06:22 +00:00
}
}
}
2004-04-12 23:05:10 +00:00
}
2004-01-11 16:06:22 +00:00
2002-08-02 12:58:37 +00:00
void BScreen : : reconfigure ( ) {
2005-04-27 09:52:30 +00:00
2004-09-12 14:56:20 +00:00
m_windowtheme - > setFocusedAlpha ( * resource . focused_alpha ) ;
m_windowtheme - > setUnfocusedAlpha ( * resource . unfocused_alpha ) ;
2003-07-19 03:59:56 +00:00
m_menutheme - > setAlpha ( * resource . menu_alpha ) ;
2003-12-12 18:18:49 +00:00
m_menutheme - > setMenuMode ( * resource . menu_mode ) ;
2003-12-18 15:27:21 +00:00
// clamp values
if ( * resource . menu_delay > 5000 )
* resource . menu_delay = 5000 ;
if ( * resource . menu_delay < 0 )
* resource . menu_delay = 0 ;
if ( * resource . menu_delay_close > 5000 )
* resource . menu_delay_close = 5000 ;
if ( * resource . menu_delay_close < 0 )
* resource . menu_delay_close = 0 ;
2004-03-23 09:21:29 +00:00
m_root_theme - > setLineAttributes ( * resource . gc_line_width ,
* resource . gc_line_style ,
* resource . gc_cap_style ,
* resource . gc_join_style ) ;
2003-12-12 18:18:49 +00:00
m_menutheme - > setDelayOpen ( * resource . menu_delay ) ;
m_menutheme - > setDelayClose ( * resource . menu_delay_close ) ;
2003-02-17 12:35:59 +00:00
// setup windowtheme, toolbartheme for antialias
2003-04-25 11:05:11 +00:00
winFrameTheme ( ) . font ( ) . setAntialias ( * resource . antialias ) ;
2003-02-17 12:35:59 +00:00
m_menutheme - > titleFont ( ) . setAntialias ( * resource . antialias ) ;
m_menutheme - > frameFont ( ) . setAntialias ( * resource . antialias ) ;
2003-04-28 22:43:26 +00:00
2003-06-12 15:24:37 +00:00
renderGeomWindow ( ) ;
2004-01-16 11:47:07 +00:00
renderPosWindow ( ) ;
2002-12-01 13:42:15 +00:00
2005-04-27 09:52:30 +00:00
// realize the number of workspaces from the init-file
const int nr_ws = * resource . workspaces ;
if ( nr_ws > m_workspaces_list . size ( ) ) {
while ( nr_ws ! = m_workspaces_list . size ( ) ) {
addWorkspace ( ) ;
}
} else if ( nr_ws < m_workspaces_list . size ( ) ) {
while ( nr_ws ! = m_workspaces_list . size ( ) ) {
removeLastWorkspace ( ) ;
}
}
2002-12-01 13:42:15 +00:00
//reconfigure menus
2004-05-02 21:12:22 +00:00
m_workspacemenu - > reconfigure ( ) ;
2003-01-12 17:59:20 +00:00
m_configmenu - > reconfigure ( ) ;
2003-05-13 00:23:05 +00:00
// We need to check to see if the timestamps
// changed before we actually can restore the menus
// in the same way, since we can't really say if
// any submenu is in the same place as before if the
// menu changed.
// if timestamp changed then no restoring
bool restore_menus = ! Fluxbox : : instance ( ) - > menuTimestampsChanged ( ) ;
// destroy old timestamps
Fluxbox : : instance ( ) - > clearMenuFilenames ( ) ;
// save submenu index so we can restore them afterwards
vector < int > remember_sub ;
if ( restore_menus ) {
FbTk : : Menu * menu = m_rootmenu . get ( ) ;
while ( menu ) {
int r = menu - > currentSubmenu ( ) ;
if ( r < 0 ) break ;
remember_sub . push_back ( r ) ;
menu = menu - > find ( r ) - > submenu ( ) ;
}
}
2003-07-01 12:39:09 +00:00
rereadMenu ( ) ;
2003-02-16 16:45:23 +00:00
2003-05-13 00:23:05 +00:00
if ( restore_menus ) {
// restore submenus, no timestamp changed
FbTk : : Menu * menu = m_rootmenu . get ( ) ;
for ( int i = 0 ; i < ( int ) remember_sub . size ( ) ; i + + ) {
int sub = remember_sub [ i ] ;
if ( ! menu | | sub < 0 )
break ;
FbTk : : MenuItem * item = menu - > find ( sub ) ;
if ( item ! = 0 ) {
menu - > drawSubmenu ( sub ) ;
menu = item - > submenu ( ) ;
} else
menu = 0 ;
}
}
2001-12-11 20:47:02 +00:00
2003-08-04 12:57:23 +00:00
// reconfigure workspaces
2003-05-19 22:45:51 +00:00
for_each ( m_workspaces_list . begin ( ) ,
m_workspaces_list . end ( ) ,
2003-04-14 15:01:55 +00:00
mem_fun ( & Workspace : : reconfigure ) ) ;
2002-12-01 13:42:15 +00:00
2003-08-04 12:57:23 +00:00
// reconfigure Icons
2003-05-19 22:45:51 +00:00
for_each ( m_icon_list . begin ( ) ,
m_icon_list . end ( ) ,
2003-04-14 15:01:55 +00:00
mem_fun ( & FluxboxWindow : : reconfigure ) ) ;
2002-12-01 13:42:15 +00:00
2003-08-11 16:27:23 +00:00
imageControl ( ) . cleanCache ( ) ;
2003-07-01 12:39:09 +00:00
// notify objects that the screen is reconfigured
m_reconfigure_sig . notify ( ) ;
2004-03-23 09:21:29 +00:00
2001-12-11 20:47:02 +00:00
}
2002-08-02 12:58:37 +00:00
void BScreen : : rereadMenu ( ) {
2002-12-01 13:42:15 +00:00
initMenu ( ) ;
2002-12-13 20:19:05 +00:00
m_rootmenu - > reconfigure ( ) ;
2001-12-11 20:47:02 +00:00
}
2002-08-02 12:58:37 +00:00
void BScreen : : removeWorkspaceNames ( ) {
2003-08-24 11:19:45 +00:00
m_workspace_names . clear ( ) ;
2001-12-11 20:47:02 +00:00
}
2002-08-02 12:58:37 +00:00
void BScreen : : updateWorkspaceNamesAtom ( ) {
2002-12-01 13:42:15 +00:00
m_workspacenames_sig . notify ( ) ;
2001-12-11 20:47:02 +00:00
}
void BScreen : : addIcon ( FluxboxWindow * w ) {
2004-05-02 21:12:22 +00:00
if ( w = = 0 )
return ;
2001-12-11 20:47:02 +00:00
2004-09-05 01:11:41 +00:00
// make sure we have a unique list
if ( find ( getIconList ( ) . begin ( ) , getIconList ( ) . end ( ) , w ) ! = getIconList ( ) . end ( ) )
return ;
2003-05-19 22:45:51 +00:00
m_icon_list . push_back ( w ) ;
2004-09-05 01:11:41 +00:00
2004-05-02 21:12:22 +00:00
// notify listeners
2003-09-08 16:37:27 +00:00
m_iconlist_sig . notify ( ) ;
2001-12-11 20:47:02 +00:00
}
void BScreen : : removeIcon ( FluxboxWindow * w ) {
2004-05-02 21:12:22 +00:00
if ( w = = 0 )
2002-12-01 13:42:15 +00:00
return ;
2004-11-20 18:12:51 +00:00
2004-09-05 01:11:41 +00:00
Icons : : iterator erase_it = remove_if ( getIconList ( ) . begin ( ) ,
getIconList ( ) . end ( ) ,
2003-04-14 15:01:55 +00:00
bind2nd ( equal_to < FluxboxWindow * > ( ) , w ) ) ;
2004-09-05 01:11:41 +00:00
// no need to send iconlist signal if we didn't
// change the iconlist
if ( erase_it ! = m_icon_list . end ( ) ) {
getIconList ( ) . erase ( erase_it ) ;
m_iconlist_sig . notify ( ) ;
}
2003-07-28 18:28:03 +00:00
}
2002-09-08 19:45:59 +00:00
void BScreen : : removeWindow ( FluxboxWindow * win ) {
2004-09-05 01:11:41 +00:00
# ifdef DEBUG
cerr < < " BScreen::removeWindow( " < < win < < " ) " < < endl ;
# endif // DEBUG
// extra precaution, if for some reason, the
// icon list should be out of sync
removeIcon ( win ) ;
// remove from workspace
Workspace * space = getWorkspace ( win - > workspaceNumber ( ) ) ;
if ( space ! = 0 )
space - > removeWindow ( win , false ) ;
2002-09-08 19:45:59 +00:00
}
2001-12-11 20:47:02 +00:00
2003-04-15 00:50:25 +00:00
void BScreen : : removeClient ( WinClient & client ) {
2003-07-28 18:28:03 +00:00
2003-10-02 16:14:41 +00:00
WinClient * cyc = 0 ;
if ( cycling_window ! = focused_list . end ( ) )
cyc = * cycling_window ;
2003-04-15 00:50:25 +00:00
focused_list . remove ( & client ) ;
if ( cyc = = & client ) {
cycling_window = focused_list . end ( ) ;
2003-05-07 16:21:26 +00:00
}
2003-08-12 00:27:57 +00:00
2003-09-24 14:26:01 +00:00
if ( cycling_last = = & client )
cycling_last = 0 ;
2003-08-12 01:04:16 +00:00
for_each ( getWorkspacesList ( ) . begin ( ) , getWorkspacesList ( ) . end ( ) ,
mem_fun ( & Workspace : : updateClientmenu ) ) ;
2003-05-14 12:08:19 +00:00
2005-05-02 12:10:01 +00:00
using namespace FbTk ;
2003-06-23 14:16:05 +00:00
// remove any grouping this is expecting
2005-05-02 12:10:01 +00:00
Groupables : : iterator erase_it = find_if ( m_expecting_groups . begin ( ) ,
m_expecting_groups . end ( ) ,
Compose ( bind2nd ( equal_to < WinClient * > ( ) , & client ) ,
Select2nd < Groupables : : value_type > ( ) ) ) ;
if ( erase_it ! = m_expecting_groups . end ( ) )
m_expecting_groups . erase ( erase_it ) ;
2003-07-28 18:28:03 +00:00
// the client could be on icon menu so we update it
2004-05-02 21:12:22 +00:00
//!! TODO: check this with the new icon menu
// updateIconMenu();
2003-08-12 01:04:16 +00:00
2003-04-15 00:50:25 +00:00
}
2002-10-15 10:54:40 +00:00
void BScreen : : setAntialias ( bool value ) {
2002-12-01 13:42:15 +00:00
if ( * resource . antialias = = value )
return ;
resource . antialias = value ;
reconfigure ( ) ;
2002-10-15 10:54:40 +00:00
}
2001-12-11 20:47:02 +00:00
2002-08-02 12:58:37 +00:00
int BScreen : : addWorkspace ( ) {
2005-04-27 09:52:30 +00:00
bool save_name = getNameOfWorkspace ( m_workspaces_list . size ( ) ) ! = " " ? false : true ;
2003-06-12 15:24:37 +00:00
Workspace * wkspc = new Workspace ( * this , m_layermanager ,
2005-04-27 09:52:30 +00:00
getNameOfWorkspace ( m_workspaces_list . size ( ) ) ,
2003-06-12 15:24:37 +00:00
m_workspaces_list . size ( ) ) ;
2003-05-19 22:45:51 +00:00
m_workspaces_list . push_back ( wkspc ) ;
2005-04-27 09:52:30 +00:00
if ( save_name )
addWorkspaceName ( wkspc - > name ( ) . c_str ( ) ) ; //update names
2003-05-19 22:45:51 +00:00
saveWorkspaces ( m_workspaces_list . size ( ) ) ;
2003-03-03 21:51:13 +00:00
2002-12-01 13:42:15 +00:00
updateNetizenWorkspaceCount ( ) ;
2001-12-11 20:47:02 +00:00
2003-05-19 22:45:51 +00:00
return m_workspaces_list . size ( ) ;
2001-12-11 20:47:02 +00:00
}
2002-10-23 17:32:30 +00:00
/// removes last workspace
/// @return number of desktops left
2002-08-02 12:58:37 +00:00
int BScreen : : removeLastWorkspace ( ) {
2003-05-19 22:45:51 +00:00
if ( m_workspaces_list . size ( ) < = 1 )
2002-12-01 13:42:15 +00:00
return 0 ;
2003-05-19 22:45:51 +00:00
Workspace * wkspc = m_workspaces_list . back ( ) ;
2001-12-11 20:47:02 +00:00
2003-05-19 22:45:51 +00:00
if ( m_current_workspace - > workspaceID ( ) = = wkspc - > workspaceID ( ) )
changeWorkspaceID ( m_current_workspace - > workspaceID ( ) - 1 ) ;
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
wkspc - > removeAll ( ) ;
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
//remove last workspace
2003-05-19 22:45:51 +00:00
m_workspaces_list . pop_back ( ) ;
2004-12-30 14:33:38 +00:00
2002-12-01 13:42:15 +00:00
updateNetizenWorkspaceCount ( ) ;
2003-05-19 22:45:51 +00:00
saveWorkspaces ( m_workspaces_list . size ( ) ) ;
2004-12-30 14:33:38 +00:00
// must be deleted after we send notify!!
// so we dont get bad pointers somewhere
// while processing the notify signal
delete wkspc ;
2001-12-11 20:47:02 +00:00
2003-05-19 22:45:51 +00:00
return m_workspaces_list . size ( ) ;
2001-12-11 20:47:02 +00:00
}
2002-03-23 15:14:45 +00:00
void BScreen : : changeWorkspaceID ( unsigned int id ) {
2003-09-14 10:13:54 +00:00
2003-05-19 22:45:51 +00:00
if ( ! m_current_workspace | | id > = m_workspaces_list . size ( ) | |
id = = m_current_workspace - > workspaceID ( ) )
2002-12-01 13:42:15 +00:00
return ;
2003-05-11 11:47:19 +00:00
2004-11-30 22:19:35 +00:00
FbTk : : App : : instance ( ) - > sync ( false ) ;
2003-10-05 02:31:23 +00:00
2003-07-28 15:06:36 +00:00
WinClient * focused_client = Fluxbox : : instance ( ) - > getFocusedWindow ( ) ;
FluxboxWindow * focused = 0 ;
if ( focused_client )
focused = focused_client - > fbwindow ( ) ;
2003-05-11 11:47:19 +00:00
if ( focused & & focused - > isMoving ( ) ) {
if ( doOpaqueMove ( ) )
reassociateWindow ( focused , id , true ) ;
// don't reassociate if not opaque moving
focused - > pauseMoving ( ) ;
}
2002-08-30 14:03:31 +00:00
2003-05-11 11:47:19 +00:00
// reassociate all windows that are stuck to the new workspace
2003-05-15 12:00:46 +00:00
Workspace * wksp = currentWorkspace ( ) ;
2003-05-11 17:14:41 +00:00
Workspace : : Windows wins = wksp - > windowList ( ) ;
2003-05-11 11:47:19 +00:00
Workspace : : Windows : : iterator it = wins . begin ( ) ;
for ( ; it ! = wins . end ( ) ; + + it ) {
if ( ( * it ) - > isStuck ( ) ) {
reassociateWindow ( * it , id , true ) ;
2002-12-01 13:42:15 +00:00
}
2003-05-11 11:47:19 +00:00
}
2002-09-12 14:55:11 +00:00
2004-05-13 01:48:18 +00:00
currentWorkspace ( ) - > hideAll ( false ) ;
2001-12-11 20:47:02 +00:00
2003-05-11 11:47:19 +00:00
// set new workspace
2003-05-19 22:45:51 +00:00
m_current_workspace = getWorkspace ( id ) ;
2001-12-11 20:47:02 +00:00
2003-09-14 10:13:54 +00:00
// This is a little tricks to reduce flicker
// this way we can set focus pixmap on frame before we show it
// and using ExposeEvent to redraw without flicker
2004-01-19 18:29:43 +00:00
/*
WinClient * win = getLastFocusedWindow ( currentWorkspaceID ( ) ) ;
if ( win & & win - > fbwindow ( ) )
win - > fbwindow ( ) - > setFocusFlag ( true ) ;
2003-12-18 15:27:21 +00:00
*/
2001-12-11 20:47:02 +00:00
2003-05-19 22:45:51 +00:00
currentWorkspace ( ) - > showAll ( ) ;
2001-12-11 20:47:02 +00:00
2003-09-14 10:13:54 +00:00
if ( focused & & ( focused - > isStuck ( ) | | focused - > isMoving ( ) ) )
2003-05-11 11:47:19 +00:00
focused - > setInputFocus ( ) ;
2003-09-14 10:13:54 +00:00
else
2003-05-11 15:26:34 +00:00
Fluxbox : : instance ( ) - > revertFocus ( * this ) ;
2002-08-30 14:03:31 +00:00
2003-09-14 10:13:54 +00:00
if ( focused & & focused - > isMoving ( ) )
2003-05-11 11:47:19 +00:00
focused - > resumeMoving ( ) ;
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
updateNetizenCurrentWorkspace ( ) ;
2004-01-19 18:29:43 +00:00
FbTk : : App : : instance ( ) - > sync ( false ) ;
2003-09-14 10:13:54 +00:00
2001-12-11 20:47:02 +00:00
}
2002-02-26 22:25:53 +00:00
2002-07-23 13:47:05 +00:00
void BScreen : : sendToWorkspace ( unsigned int id , FluxboxWindow * win , bool changeWS ) {
2003-12-18 15:27:21 +00:00
if ( ! m_current_workspace | | id > = m_workspaces_list . size ( ) )
2002-12-01 13:42:15 +00:00
return ;
2002-02-26 22:25:53 +00:00
2003-07-28 15:06:36 +00:00
if ( ! win ) {
WinClient * client = Fluxbox : : instance ( ) - > getFocusedWindow ( ) ;
if ( client )
win = client - > fbwindow ( ) ;
}
2002-07-23 13:47:05 +00:00
2002-02-26 22:25:53 +00:00
2004-11-30 22:19:35 +00:00
FbTk : : App : : instance ( ) - > sync ( false ) ;
2002-02-26 22:25:53 +00:00
2003-12-04 00:08:55 +00:00
if ( win & & & win - > screen ( ) = = this & &
( ! win - > isStuck ( ) ) ) {
2003-12-18 15:27:21 +00:00
// if iconified, deiconify it before we send it somewhere
if ( win - > isIconic ( ) )
2003-12-04 00:08:55 +00:00
win - > deiconify ( ) ;
2002-09-10 10:59:57 +00:00
2003-12-18 15:27:21 +00:00
// if the window isn't on current workspace, hide it
2003-12-04 00:08:55 +00:00
if ( id ! = currentWorkspace ( ) - > workspaceID ( ) )
2004-05-13 01:48:18 +00:00
win - > withdraw ( true ) ;
2003-12-04 00:08:55 +00:00
reassociateWindow ( win , id , true ) ;
2003-12-18 15:27:21 +00:00
// if the window is on current workspace, show it.
2003-12-04 00:08:55 +00:00
if ( id = = currentWorkspace ( ) - > workspaceID ( ) )
win - > deiconify ( false , false ) ;
2002-02-26 22:25:53 +00:00
2003-12-04 00:08:55 +00:00
// change workspace ?
if ( changeWS & & id ! = currentWorkspace ( ) - > workspaceID ( ) ) {
changeWorkspaceID ( id ) ;
win - > setInputFocus ( ) ;
2002-12-01 13:42:15 +00:00
}
2002-10-11 10:22:06 +00:00
2002-12-01 13:42:15 +00:00
}
2003-12-04 00:08:55 +00:00
2002-02-26 22:25:53 +00:00
}
2001-12-11 20:47:02 +00:00
2003-05-11 17:14:41 +00:00
void BScreen : : addNetizen ( Window win ) {
Netizen * net = new Netizen ( * this , win ) ;
2003-05-19 22:45:51 +00:00
m_netizen_list . push_back ( net ) ;
2001-12-11 20:47:02 +00:00
2003-05-11 17:14:41 +00:00
net - > sendWorkspaceCount ( ) ;
net - > sendCurrentWorkspace ( ) ;
2001-12-11 20:47:02 +00:00
2003-05-11 17:14:41 +00:00
// send all windows to netizen
2003-05-19 22:45:51 +00:00
Workspaces : : iterator it = m_workspaces_list . begin ( ) ;
Workspaces : : iterator it_end = m_workspaces_list . end ( ) ;
2002-12-01 13:42:15 +00:00
for ( ; it ! = it_end ; + + it ) {
2003-05-11 17:14:41 +00:00
Workspace : : Windows : : iterator win_it = ( * it ) - > windowList ( ) . begin ( ) ;
Workspace : : Windows : : iterator win_it_end = ( * it ) - > windowList ( ) . end ( ) ;
for ( ; win_it ! = win_it_end ; + + win_it ) {
2003-05-15 11:17:29 +00:00
net - > sendWindowAdd ( ( * win_it ) - > clientWindow ( ) ,
2003-08-24 11:19:45 +00:00
( * it ) - > workspaceID ( ) ) ;
2002-12-01 13:42:15 +00:00
}
}
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
Window f = ( ( Fluxbox : : instance ( ) - > getFocusedWindow ( ) ) ?
2003-07-28 15:06:36 +00:00
Fluxbox : : instance ( ) - > getFocusedWindow ( ) - > window ( ) : None ) ;
2003-05-11 17:14:41 +00:00
net - > sendWindowFocus ( f ) ;
2001-12-11 20:47:02 +00:00
}
void BScreen : : removeNetizen ( Window w ) {
2003-05-19 22:45:51 +00:00
Netizens : : iterator it = m_netizen_list . begin ( ) ;
Netizens : : iterator it_end = m_netizen_list . end ( ) ;
2002-12-01 13:42:15 +00:00
for ( ; it ! = it_end ; + + it ) {
2003-05-10 18:15:23 +00:00
if ( ( * it ) - > window ( ) = = w ) {
2002-12-01 13:42:15 +00:00
Netizen * n = * it ;
delete n ;
2003-05-19 22:45:51 +00:00
m_netizen_list . erase ( it ) ;
2002-12-01 13:42:15 +00:00
break ;
}
}
2001-12-11 20:47:02 +00:00
}
2002-08-02 12:58:37 +00:00
void BScreen : : updateNetizenCurrentWorkspace ( ) {
2002-12-01 13:42:15 +00:00
m_currentworkspace_sig . notify ( ) ;
2003-05-19 22:45:51 +00:00
for_each ( m_netizen_list . begin ( ) ,
m_netizen_list . end ( ) ,
2003-04-14 15:01:55 +00:00
mem_fun ( & Netizen : : sendCurrentWorkspace ) ) ;
2001-12-11 20:47:02 +00:00
}
2002-08-02 12:58:37 +00:00
void BScreen : : updateNetizenWorkspaceCount ( ) {
2003-05-19 22:45:51 +00:00
for_each ( m_netizen_list . begin ( ) ,
m_netizen_list . end ( ) ,
2003-04-14 15:01:55 +00:00
mem_fun ( & Netizen : : sendWorkspaceCount ) ) ;
2002-12-01 13:42:15 +00:00
m_workspacecount_sig . notify ( ) ;
2001-12-11 20:47:02 +00:00
}
2002-08-02 12:58:37 +00:00
void BScreen : : updateNetizenWindowFocus ( ) {
2002-12-01 13:42:15 +00:00
Window f = ( ( Fluxbox : : instance ( ) - > getFocusedWindow ( ) ) ?
2003-07-28 15:06:36 +00:00
Fluxbox : : instance ( ) - > getFocusedWindow ( ) - > window ( ) : None ) ;
2003-08-24 11:19:45 +00:00
for_each ( m_netizen_list . begin ( ) ,
m_netizen_list . end ( ) ,
bind2nd ( mem_fun ( & Netizen : : sendWindowFocus ) , f ) ) ;
2001-12-11 20:47:02 +00:00
}
void BScreen : : updateNetizenWindowAdd ( Window w , unsigned long p ) {
2003-05-19 22:45:51 +00:00
Netizens : : iterator it = m_netizen_list . begin ( ) ;
Netizens : : iterator it_end = m_netizen_list . end ( ) ;
2002-12-01 13:42:15 +00:00
for ( ; it ! = it_end ; + + it ) {
( * it ) - > sendWindowAdd ( w , p ) ;
}
2002-02-20 22:41:13 +00:00
2001-12-11 20:47:02 +00:00
}
void BScreen : : updateNetizenWindowDel ( Window w ) {
2003-08-24 11:19:45 +00:00
for_each ( m_netizen_list . begin ( ) ,
m_netizen_list . end ( ) ,
bind2nd ( mem_fun ( & Netizen : : sendWindowDel ) , w ) ) ;
2002-09-07 20:22:08 +00:00
2002-12-01 13:42:15 +00:00
m_clientlist_sig . notify ( ) ;
2001-12-11 20:47:02 +00:00
}
void BScreen : : updateNetizenWindowRaise ( Window w ) {
2003-08-24 11:19:45 +00:00
for_each ( m_netizen_list . begin ( ) ,
m_netizen_list . end ( ) ,
bind2nd ( mem_fun ( & Netizen : : sendWindowRaise ) , w ) ) ;
2001-12-11 20:47:02 +00:00
}
void BScreen : : updateNetizenWindowLower ( Window w ) {
2003-08-24 11:19:45 +00:00
for_each ( m_netizen_list . begin ( ) ,
m_netizen_list . end ( ) ,
bind2nd ( mem_fun ( & Netizen : : sendWindowLower ) , w ) ) ;
2001-12-11 20:47:02 +00:00
}
2003-06-24 14:57:54 +00:00
void BScreen : : updateNetizenConfigNotify ( XEvent & e ) {
2003-05-19 22:45:51 +00:00
Netizens : : iterator it = m_netizen_list . begin ( ) ;
Netizens : : iterator it_end = m_netizen_list . end ( ) ;
2003-08-24 11:19:45 +00:00
for ( ; it ! = it_end ; + + it )
2002-12-01 13:42:15 +00:00
( * it ) - > sendConfigNotify ( e ) ;
2001-12-11 20:47:02 +00:00
}
2004-04-19 22:44:42 +00:00
bool BScreen : : isKdeDockapp ( Window client ) const {
//Check and see if client is KDE dock applet.
//If so add to Slit
bool iskdedockapp = false ;
Atom ajunk ;
int ijunk ;
unsigned long * data = 0 , uljunk ;
Display * disp = FbTk : : App : : instance ( ) - > display ( ) ;
// Check if KDE v2.x dock applet
if ( XGetWindowProperty ( disp , client ,
XInternAtom ( FbTk : : App : : instance ( ) - > display ( ) ,
" _KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR " , False ) ,
0l , 1l , False ,
XA_WINDOW , & ajunk , & ijunk , & uljunk ,
& uljunk , ( unsigned char * * ) & data ) = = Success ) {
if ( data )
iskdedockapp = true ;
XFree ( ( void * ) data ) ;
data = 0 ;
}
2003-07-28 20:11:55 +00:00
2004-04-19 22:44:42 +00:00
// Check if KDE v1.x dock applet
if ( ! iskdedockapp ) {
Atom kwm1 = XInternAtom ( FbTk : : App : : instance ( ) - > display ( ) ,
" KWM_DOCKWINDOW " , False ) ;
2003-07-28 20:11:55 +00:00
if ( XGetWindowProperty ( disp , client ,
2004-04-19 22:44:42 +00:00
kwm1 , 0l , 1l , False ,
kwm1 , & ajunk , & ijunk , & uljunk ,
& uljunk , ( unsigned char * * ) & data ) = = Success & & data ) {
iskdedockapp = ( data & & data [ 0 ] ! = 0 ) ;
2003-07-28 20:11:55 +00:00
XFree ( ( void * ) data ) ;
data = 0 ;
}
2004-04-19 22:44:42 +00:00
}
2003-07-28 20:11:55 +00:00
2004-04-19 22:44:42 +00:00
return iskdedockapp ;
}
bool BScreen : : addKdeDockapp ( Window client ) {
XSelectInput ( FbTk : : App : : instance ( ) - > display ( ) , client , StructureNotifyMask ) ;
char intbuff [ 16 ] ;
sprintf ( intbuff , " %d " , screenNumber ( ) ) ;
std : : string atom_name ( " _NET_SYSTEM_TRAY_S " ) ;
atom_name + = intbuff ; // append number
2004-05-02 21:12:22 +00:00
// find the right atomhandler that has the name: _NET_SYSTEM_TRAY_S<num>
2004-04-19 22:44:42 +00:00
AtomHandler * handler = Fluxbox : : instance ( ) - > getAtomHandler ( atom_name ) ;
FbTk : : EventHandler * evh = 0 ;
FbTk : : EventManager * evm = FbTk : : EventManager : : instance ( ) ;
if ( handler = = 0 ) {
# ifdef SLIT
if ( slit ( ) ! = 0 )
slit ( ) - > addClient ( client ) ;
else
# endif // SLIT
return false ;
} else {
2004-05-02 21:12:22 +00:00
// this handler is a special case
// so we call setupClient in it
2004-04-19 22:44:42 +00:00
WinClient winclient ( client , * this ) ;
handler - > setupClient ( winclient ) ;
// we need to save old handler and re-add it later
evh = evm - > find ( client ) ;
}
if ( evh ! = 0 ) // re-add handler
evm - > add ( * evh , client ) ;
return true ;
}
FluxboxWindow * BScreen : : createWindow ( Window client ) {
FbTk : : App : : instance ( ) - > sync ( false ) ;
2003-07-28 20:11:55 +00:00
2005-04-29 02:52:36 +00:00
if ( isKdeDockapp ( client ) & & addKdeDockapp ( client ) ) {
return 0 ; // dont create a FluxboxWindow for this one
2004-04-19 22:44:42 +00:00
}
2003-07-28 20:11:55 +00:00
2003-06-23 14:16:05 +00:00
WinClient * winclient = new WinClient ( client , * this ) ;
2003-06-27 15:05:19 +00:00
if ( winclient - > initial_state = = WithdrawnState ) {
delete winclient ;
2003-01-05 22:26:56 +00:00
# ifdef SLIT
2004-04-19 22:44:42 +00:00
if ( slit ( ) )
slit ( ) - > addClient ( client ) ;
2003-06-24 14:57:54 +00:00
# endif // SLIT
2003-05-17 11:05:33 +00:00
return 0 ;
}
2003-01-05 22:26:56 +00:00
2003-07-04 01:03:41 +00:00
bool new_win = false ;
2003-06-23 14:16:05 +00:00
// check if it should be grouped with something else
FluxboxWindow * win ;
if ( ( win = findGroupLeft ( * winclient ) ) ! = 0 ) {
win - > attachClient ( * winclient ) ;
2003-07-04 01:03:41 +00:00
Fluxbox : : instance ( ) - > attachSignals ( * winclient ) ;
2003-01-05 22:26:56 +00:00
} else {
2003-06-23 14:16:05 +00:00
2003-07-04 01:03:41 +00:00
Fluxbox : : instance ( ) - > attachSignals ( * winclient ) ;
if ( winclient - > fbwindow ( ) ) // may have been set in an atomhandler
win = winclient - > fbwindow ( ) ;
else {
2003-12-18 18:03:23 +00:00
win = new FluxboxWindow ( * winclient ,
2003-07-10 11:29:45 +00:00
winFrameTheme ( ) ,
2003-07-04 01:03:41 +00:00
* layerManager ( ) . getLayer ( Fluxbox : : instance ( ) - > getNormalLayer ( ) ) ) ;
new_win = true ;
if ( ! win - > isManaged ( ) ) {
delete win ;
return 0 ;
}
}
}
// always put on end of focused list, if it gets focused it'll get pushed up
// there is only the one win client at this stage
if ( doFocusNew ( ) )
focused_list . push_front ( & win - > winClient ( ) ) ;
else
focused_list . push_back ( & win - > winClient ( ) ) ;
2005-01-05 01:56:19 +00:00
2003-06-23 14:16:05 +00:00
// we also need to check if another window expects this window to the left
// and if so, then join it.
FluxboxWindow * otherwin = 0 ;
// TODO: does this do the right stuff focus-wise?
2003-07-04 01:03:41 +00:00
if ( ( otherwin = findGroupRight ( * winclient ) ) & & otherwin ! = win ) {
2003-06-23 14:16:05 +00:00
win - > attachClient ( otherwin - > winClient ( ) ) ;
2003-07-04 01:03:41 +00:00
}
2003-06-23 14:16:05 +00:00
2004-01-19 18:29:43 +00:00
m_clientlist_sig . notify ( ) ;
2003-12-04 21:31:02 +00:00
FbTk : : App : : instance ( ) - > sync ( false ) ;
2003-01-05 22:26:56 +00:00
return win ;
}
2004-04-19 22:44:42 +00:00
2003-04-14 15:01:55 +00:00
FluxboxWindow * BScreen : : createWindow ( WinClient & client ) {
2005-01-04 10:51:38 +00:00
if ( isKdeDockapp ( client . window ( ) ) & & addKdeDockapp ( client . window ( ) ) ) {
return 0 ;
}
2003-12-18 18:03:23 +00:00
FluxboxWindow * win = new FluxboxWindow ( client ,
2003-07-10 11:29:45 +00:00
winFrameTheme ( ) ,
2003-04-14 15:01:55 +00:00
* layerManager ( ) . getLayer ( Fluxbox : : instance ( ) - > getNormalLayer ( ) ) ) ;
2004-04-19 22:44:42 +00:00
2003-04-14 15:01:55 +00:00
# ifdef SLIT
2005-01-05 01:56:19 +00:00
if ( win - > initialState ( ) = = WithdrawnState & & slit ( ) ! = 0 ) {
slit ( ) - > addClient ( win - > clientWindow ( ) ) ;
}
2003-04-14 15:01:55 +00:00
# endif // SLIT
2004-04-19 22:44:42 +00:00
2003-04-14 15:01:55 +00:00
if ( ! win - > isManaged ( ) ) {
delete win ;
return 0 ;
}
2003-12-14 01:09:00 +00:00
2004-01-19 18:29:43 +00:00
m_clientlist_sig . notify ( ) ;
2003-04-14 15:01:55 +00:00
return win ;
}
2004-09-11 13:33:07 +00:00
Strut * BScreen : : requestStrut ( int head , int left , int right , int top , int bottom ) {
if ( head > numHeads ( ) & & head ! = 1 ) {
// head does not exist (if head == 1, then numHeads() == 0,
// which means no xinerama, but there's a head after all
head = numHeads ( ) ;
}
2003-06-18 13:42:21 +00:00
2004-09-11 13:33:07 +00:00
int begin = head - 1 ;
int end = head ;
2003-06-18 13:42:21 +00:00
2004-09-11 13:33:07 +00:00
if ( head = = 0 ) { // all heads (or no xinerama)
begin = 0 ;
end = ( numHeads ( ) ? numHeads ( ) : 1 ) ;
2003-06-18 13:42:21 +00:00
}
2004-09-11 13:33:07 +00:00
Strut * next = 0 ;
for ( int i = begin ; i ! = end ; i + + ) {
next = m_head_areas [ i ] . requestStrut ( i + 1 , left , right , top , bottom , next ) ;
}
return next ;
}
void BScreen : : clearStrut ( Strut * str ) {
if ( str - > next ( ) )
clearStrut ( str - > next ( ) ) ;
int head = str - > head ( ) ? str - > head ( ) - 1 : 0 ;
m_head_areas [ head ] . clearStrut ( str ) ;
// str is invalid now
}
2003-06-18 13:42:21 +00:00
void BScreen : : updateAvailableWorkspaceArea ( ) {
2004-09-11 13:33:07 +00:00
size_t n = ( numHeads ( ) ? numHeads ( ) : 1 ) ;
bool updated = false ;
2003-06-18 13:42:21 +00:00
2004-09-11 13:33:07 +00:00
for ( size_t i = 0 ; i < n ; i + + ) {
updated = m_head_areas [ i ] . updateAvailableWorkspaceArea ( ) | | updated ;
}
2004-01-19 18:29:43 +00:00
2004-09-11 13:33:07 +00:00
if ( updated )
2004-01-19 18:29:43 +00:00
m_workspace_area_sig . notify ( ) ;
2003-06-18 13:42:21 +00:00
}
2001-12-11 20:47:02 +00:00
2002-07-23 17:11:59 +00:00
void BScreen : : addWorkspaceName ( const char * name ) {
2003-05-19 22:45:51 +00:00
m_workspace_names . push_back ( name ) ;
2001-12-11 20:47:02 +00:00
}
2002-08-11 22:28:18 +00:00
string BScreen : : getNameOfWorkspace ( unsigned int workspace ) const {
2003-12-14 01:09:00 +00:00
if ( workspace < m_workspace_names . size ( ) )
2003-05-19 22:45:51 +00:00
return m_workspace_names [ workspace ] ;
2003-12-14 01:09:00 +00:00
else
2002-12-01 13:42:15 +00:00
return " " ;
2001-12-11 20:47:02 +00:00
}
2003-04-28 00:38:42 +00:00
void BScreen : : reassociateWindow ( FluxboxWindow * w , unsigned int wkspc_id ,
bool ignore_sticky ) {
2003-04-14 15:01:55 +00:00
if ( w = = 0 )
return ;
2001-12-11 20:47:02 +00:00
2003-08-18 11:26:17 +00:00
if ( wkspc_id > = getCount ( ) )
2003-05-19 22:45:51 +00:00
wkspc_id = currentWorkspace ( ) - > workspaceID ( ) ;
2002-12-01 13:42:15 +00:00
2003-05-15 11:17:29 +00:00
if ( ! w - > isIconic ( ) & & w - > workspaceNumber ( ) = = wkspc_id )
2002-12-01 13:42:15 +00:00
return ;
2003-02-16 17:57:54 +00:00
2002-12-01 13:42:15 +00:00
if ( w - > isIconic ( ) ) {
removeIcon ( w ) ;
2003-04-14 15:01:55 +00:00
getWorkspace ( wkspc_id ) - > addWindow ( * w ) ;
2004-01-19 22:07:24 +00:00
// client list need to notify now even though
// we didn't remove/add any window,
// so listeners that uses the client list to
// show whats on current/other workspace
// gets updated
m_clientlist_sig . notify ( ) ;
2002-12-01 13:42:15 +00:00
} else if ( ignore_sticky | | ! w - > isStuck ( ) ) {
2005-01-05 01:56:19 +00:00
// fresh windows have workspaceNumber == -1, which leads to
// an invalid workspace (unsigned int)
if ( getWorkspace ( w - > workspaceNumber ( ) ) )
getWorkspace ( w - > workspaceNumber ( ) ) - > removeWindow ( w , true ) ;
2003-04-14 15:01:55 +00:00
getWorkspace ( wkspc_id ) - > addWindow ( * w ) ;
2004-01-19 22:07:24 +00:00
// see comment above
m_clientlist_sig . notify ( ) ;
2002-12-01 13:42:15 +00:00
}
2001-12-11 20:47:02 +00:00
}
2002-03-18 20:20:09 +00:00
void BScreen : : nextFocus ( int opts ) {
2003-05-15 12:00:46 +00:00
const int num_windows = currentWorkspace ( ) - > numberOfWindows ( ) ;
2002-12-01 13:42:15 +00:00
2003-08-04 12:57:23 +00:00
if ( num_windows < 1 )
return ;
if ( ! ( opts & CYCLELINEAR ) ) {
if ( ! cycling_focus ) {
cycling_focus = True ;
cycling_window = focused_list . begin ( ) ;
cycling_last = 0 ;
} else {
// already cycling, so restack to put windows back in their proper order
m_layermanager . restack ( ) ;
}
// if it is stacked, we want the highest window in the focused list
// that is on the same workspace
FocusedWindows : : iterator it = cycling_window ;
const FocusedWindows : : iterator it_end = focused_list . end ( ) ;
while ( true ) {
+ + it ;
if ( it = = it_end ) {
it = focused_list . begin ( ) ;
}
// give up [do nothing] if we reach the current focused again
if ( ( * it ) = = ( * cycling_window ) ) {
break ;
2003-04-15 00:50:25 +00:00
}
2002-12-01 13:42:15 +00:00
2005-04-29 02:52:36 +00:00
FluxboxWindow * fbwin = ( * it ) - > fbwindow ( ) ;
2003-08-04 12:57:23 +00:00
if ( fbwin & & ! fbwin - > isIconic ( ) & &
( fbwin - > isStuck ( )
| | fbwin - > workspaceNumber ( ) = = currentWorkspaceID ( ) ) ) {
// either on this workspace, or stuck
// keep track of the originally selected window in a set
WinClient & last_client = fbwin - > winClient ( ) ;
if ( ! ( doSkipWindow ( * * it , opts ) | | ! fbwin - > setCurrentClient ( * * it ) ) ) {
// moved onto a new fbwin
if ( ! cycling_last | | cycling_last - > fbwindow ( ) ! = fbwin ) {
if ( cycling_last )
// set back to orig current Client in that fbwin
cycling_last - > fbwindow ( ) - > setCurrentClient ( * cycling_last , false ) ;
cycling_last = & last_client ;
2003-04-15 23:09:26 +00:00
}
2003-08-04 12:57:23 +00:00
fbwin - > tempRaise ( ) ;
break ;
2003-04-15 00:50:25 +00:00
}
}
2003-08-04 12:57:23 +00:00
}
cycling_window = it ;
} else { // not stacked cycling
// I really don't like this, but evidently some people use it(!)
Workspace * wksp = currentWorkspace ( ) ;
Workspace : : Windows & wins = wksp - > windowList ( ) ;
Workspace : : Windows : : iterator it = wins . begin ( ) ;
FluxboxWindow * focused_group = 0 ;
// start from the focused window
bool have_focused = false ;
WinClient * focused = Fluxbox : : instance ( ) - > getFocusedWindow ( ) ;
if ( focused ! = 0 ) {
if ( focused - > screen ( ) . screenNumber ( ) = = screenNumber ( ) ) {
have_focused = true ;
focused_group = focused - > fbwindow ( ) ;
2003-04-15 00:50:25 +00:00
}
2003-08-04 12:57:23 +00:00
}
2003-07-28 15:06:36 +00:00
2003-08-04 12:57:23 +00:00
if ( ! have_focused ) {
focused_group = ( * it ) ;
} else {
// get focused window iterator
for ( ; it ! = wins . end ( ) & & ( * it ) ! = focused_group ; + + it )
continue ;
2002-12-01 13:42:15 +00:00
}
2003-08-04 12:57:23 +00:00
do {
+ + it ;
if ( it = = wins . end ( ) )
it = wins . begin ( ) ;
// see if the window should be skipped
if ( ! ( doSkipWindow ( ( * it ) - > winClient ( ) , opts ) | | ! ( * it ) - > setInputFocus ( ) ) )
break ;
} while ( ( * it ) ! = focused_group ) ;
if ( ( * it ) ! = focused_group & & it ! = wins . end ( ) )
( * it ) - > raise ( ) ;
2002-12-01 13:42:15 +00:00
}
2002-04-02 23:14:54 +00:00
2001-12-11 20:47:02 +00:00
}
2002-03-18 20:20:09 +00:00
void BScreen : : prevFocus ( int opts ) {
2003-05-15 12:00:46 +00:00
int num_windows = currentWorkspace ( ) - > numberOfWindows ( ) ;
2002-04-02 23:14:54 +00:00
2003-08-04 12:57:23 +00:00
if ( num_windows < 1 )
return ;
2003-04-15 00:50:25 +00:00
2003-08-04 12:57:23 +00:00
if ( ! ( opts & CYCLELINEAR ) ) {
if ( ! cycling_focus ) {
cycling_focus = true ;
cycling_window = focused_list . end ( ) ;
cycling_last = 0 ;
} else {
// already cycling, so restack to put windows back in their proper order
m_layermanager . restack ( ) ;
}
// if it is stacked, we want the highest window in the focused list
// that is on the same workspace
FocusedWindows : : iterator it = cycling_window ;
FocusedWindows : : iterator it_end = focused_list . end ( ) ;
while ( true ) {
- - it ;
if ( it = = it_end ) {
it = focused_list . end ( ) ;
2003-04-15 00:50:25 +00:00
- - it ;
2003-08-04 12:57:23 +00:00
}
// give up [do nothing] if we reach the current focused again
if ( ( * it ) = = ( * cycling_window ) ) {
break ;
}
2002-12-01 13:42:15 +00:00
2005-04-29 02:52:36 +00:00
FluxboxWindow * fbwin = ( * it ) - > fbwindow ( ) ;
2003-08-04 12:57:23 +00:00
if ( fbwin & & ! fbwin - > isIconic ( ) & &
( fbwin - > isStuck ( )
| | fbwin - > workspaceNumber ( ) = = currentWorkspaceID ( ) ) ) {
// either on this workspace, or stuck
2003-04-27 14:36:05 +00:00
2003-08-04 12:57:23 +00:00
// keep track of the originally selected window in a set
WinClient & last_client = fbwin - > winClient ( ) ;
2003-04-27 14:36:05 +00:00
2003-08-04 12:57:23 +00:00
if ( ! ( doSkipWindow ( * * it , opts ) | | ! fbwin - > setCurrentClient ( * * it ) ) ) {
// moved onto a new fbwin
if ( ! cycling_last | | cycling_last - > fbwindow ( ) ! = fbwin ) {
if ( cycling_last )
// set back to orig current Client in that fbwin
cycling_last - > fbwindow ( ) - > setCurrentClient ( * cycling_last , false ) ;
cycling_last = & last_client ;
2003-04-15 23:09:26 +00:00
}
2003-08-04 12:57:23 +00:00
fbwin - > tempRaise ( ) ;
break ;
2003-04-15 00:50:25 +00:00
}
}
2003-08-04 12:57:23 +00:00
}
cycling_window = it ;
} else { // not stacked cycling
2003-04-15 00:50:25 +00:00
2003-08-04 12:57:23 +00:00
Workspace * wksp = currentWorkspace ( ) ;
Workspace : : Windows & wins = wksp - > windowList ( ) ;
Workspace : : Windows : : iterator it = wins . begin ( ) ;
2003-04-15 00:50:25 +00:00
2003-08-04 12:57:23 +00:00
FluxboxWindow * focused_group = 0 ;
// start from the focused window
bool have_focused = false ;
WinClient * focused = Fluxbox : : instance ( ) - > getFocusedWindow ( ) ;
if ( focused ! = 0 ) {
if ( focused - > screen ( ) . screenNumber ( ) = = screenNumber ( ) ) {
have_focused = true ;
focused_group = focused - > fbwindow ( ) ;
2003-07-28 15:06:36 +00:00
}
2003-08-04 12:57:23 +00:00
}
2003-07-28 15:06:36 +00:00
2003-08-04 12:57:23 +00:00
if ( ! have_focused ) {
focused_group = ( * it ) ;
} else {
//get focused window iterator
for ( ; it ! = wins . end ( ) & & ( * it ) ! = focused_group ; + + it )
continue ;
}
2003-07-28 15:06:36 +00:00
2003-08-04 12:57:23 +00:00
do {
if ( it = = wins . begin ( ) )
it = wins . end ( ) ;
- - it ;
// see if the window should be skipped
if ( ! ( doSkipWindow ( ( * it ) - > winClient ( ) , opts ) | | ! ( * it ) - > setInputFocus ( ) ) )
break ;
} while ( ( * it ) ! = focused_group ) ;
2003-04-15 00:50:25 +00:00
2003-08-04 12:57:23 +00:00
if ( ( * it ) ! = focused_group & & it ! = wins . end ( ) )
( * it ) - > raise ( ) ;
2002-12-01 13:42:15 +00:00
}
2001-12-11 20:47:02 +00:00
}
2003-02-15 02:03:09 +00:00
2002-08-02 12:58:37 +00:00
void BScreen : : raiseFocus ( ) {
2002-12-01 13:42:15 +00:00
bool have_focused = false ;
2003-08-04 12:57:23 +00:00
Fluxbox & fb = * Fluxbox : : instance ( ) ;
// set have_focused if the currently focused window
// is on this screen
if ( fb . getFocusedWindow ( ) ) {
if ( fb . getFocusedWindow ( ) - > screen ( ) . screenNumber ( ) = = screenNumber ( ) ) {
2002-12-01 13:42:15 +00:00
have_focused = true ;
}
2003-08-04 12:57:23 +00:00
}
2002-12-01 13:42:15 +00:00
2003-08-04 12:57:23 +00:00
// if we have a focused window on this screen and
// number of windows is greater than one raise the focused window
if ( currentWorkspace ( ) - > numberOfWindows ( ) > 1 & & have_focused )
fb . getFocusedWindow ( ) - > raise ( ) ;
2001-12-11 20:47:02 +00:00
}
2003-04-15 00:50:25 +00:00
void BScreen : : setFocusedWindow ( WinClient & winclient ) {
// raise newly focused window to the top of the focused list
if ( ! cycling_focus ) { // don't change the order if we're cycling
focused_list . remove ( & winclient ) ;
focused_list . push_front ( & winclient ) ;
cycling_window = focused_list . begin ( ) ;
}
}
2004-04-28 14:59:12 +00:00
void BScreen : : dirFocus ( FluxboxWindow & win , const FocusDir dir ) {
2003-04-20 12:21:35 +00:00
// change focus to the window in direction dir from the given window
// we scan through the list looking for the window that is "closest"
// in the given direction
FluxboxWindow * foundwin = 0 ;
int weight = 999999 , exposure = 0 ; // extreme values
2003-08-25 16:07:09 +00:00
int borderW = winFrameTheme ( ) . border ( ) . width ( ) ,
2003-05-15 11:17:29 +00:00
top = win . y ( ) ,
bottom = win . y ( ) + win . height ( ) + 2 * borderW ,
left = win . x ( ) ,
right = win . x ( ) + win . width ( ) + 2 * borderW ;
2003-04-20 12:21:35 +00:00
2003-05-15 12:00:46 +00:00
Workspace : : Windows & wins = currentWorkspace ( ) - > windowList ( ) ;
2003-04-20 12:21:35 +00:00
Workspace : : Windows : : iterator it = wins . begin ( ) ;
for ( ; it ! = wins . end ( ) ; + + it ) {
2004-04-28 14:59:12 +00:00
if ( ( * it ) = = & win
| | ( * it ) - > isIconic ( )
| | ( * it ) - > isFocusHidden ( )
| | ! ( * it ) - > winClient ( ) . acceptsFocus ( ) )
continue ; // skip self
2003-04-20 12:21:35 +00:00
// we check things against an edge, and within the bounds (draw a picture)
int edge = 0 , upper = 0 , lower = 0 , oedge = 0 , oupper = 0 , olower = 0 ;
2003-05-15 11:17:29 +00:00
int otop = ( * it ) - > y ( ) ,
obottom = ( * it ) - > y ( ) + ( * it ) - > height ( ) + 2 * borderW ,
oleft = ( * it ) - > x ( ) ,
oright = ( * it ) - > x ( ) + ( * it ) - > width ( ) + 2 * borderW ;
2003-04-20 12:21:35 +00:00
// check if they intersect
switch ( dir ) {
case FOCUSUP :
edge = obottom ;
oedge = bottom ;
upper = left ;
oupper = oleft ;
lower = right ;
olower = oright ;
break ;
case FOCUSDOWN :
edge = top ;
oedge = otop ;
upper = left ;
oupper = oleft ;
lower = right ;
olower = oright ;
break ;
case FOCUSLEFT :
edge = oright ;
oedge = right ;
upper = top ;
oupper = otop ;
lower = bottom ;
olower = obottom ;
break ;
case FOCUSRIGHT :
edge = left ;
oedge = oleft ;
upper = top ;
oupper = otop ;
lower = bottom ;
olower = obottom ;
break ;
}
if ( oedge < edge ) continue ; // not in the right direction
if ( olower < = upper | | oupper > = lower ) {
// outside our horz bounds, get a heavy weight penalty
int myweight = 100000 + oedge - edge + abs ( upper - oupper ) + abs ( lower - olower ) ;
if ( myweight < weight ) {
foundwin = * it ;
exposure = 0 ;
weight = myweight ;
}
} else if ( ( oedge - edge ) < weight ) {
foundwin = * it ;
weight = oedge - edge ;
exposure = ( ( lower < olower ) ? lower : olower ) - ( ( upper > oupper ) ? upper : oupper ) ;
} else if ( foundwin & & oedge - edge = = weight ) {
int myexp = ( ( lower < olower ) ? lower : olower ) - ( ( upper > oupper ) ? upper : oupper ) ;
if ( myexp > exposure ) {
foundwin = * it ;
// weight is same
exposure = myexp ;
}
} // else not improvement
}
if ( foundwin )
foundwin - > setInputFocus ( ) ;
}
2004-05-02 21:12:22 +00:00
void BScreen : : initMenus ( ) {
m_workspacemenu . reset ( MenuCreator : : createMenuType ( " workspacemenu " , screenNumber ( ) ) ) ;
initMenu ( ) ;
}
2003-04-20 12:21:35 +00:00
2002-08-02 12:58:37 +00:00
void BScreen : : initMenu ( ) {
2001-12-11 20:47:02 +00:00
2002-12-13 20:19:05 +00:00
if ( m_rootmenu . get ( ) ) {
2003-04-26 15:00:25 +00:00
// since all menus in root is submenus in m_rootmenu
2003-05-19 22:45:51 +00:00
// just remove every item in m_rootmenu and then clear m_rootmenu_list
2002-12-13 20:19:05 +00:00
while ( m_rootmenu - > numberOfItems ( ) )
2003-04-18 12:51:14 +00:00
m_rootmenu - > remove ( 0 ) ;
2003-05-19 22:45:51 +00:00
m_rootmenu_list . clear ( ) ;
2003-04-26 15:00:25 +00:00
2002-12-01 13:42:15 +00:00
} else
2003-12-10 23:08:06 +00:00
m_rootmenu . reset ( createMenu ( " " ) ) ;
2002-12-01 13:42:15 +00:00
Fluxbox * const fb = Fluxbox : : instance ( ) ;
2003-08-10 12:50:04 +00:00
if ( fb - > getMenuFilename ( ) . size ( ) > 0 ) {
2004-05-02 21:12:22 +00:00
m_rootmenu . reset ( MenuCreator : : createFromFile ( fb - > getMenuFilename ( ) ,
2004-10-04 15:37:58 +00:00
screenNumber ( ) , true ) ) ;
2004-05-02 21:12:22 +00:00
2002-12-01 13:42:15 +00:00
}
2004-05-02 21:12:22 +00:00
if ( m_rootmenu . get ( ) = = 0 ) {
2004-06-07 11:46:05 +00:00
_FB_USES_NLS ;
m_rootmenu . reset ( createMenu ( _FBTEXT ( Menu , DefaultRootMenu , " Fluxbox default menu " , " Title of fallback root menu " ) ) ) ;
2004-05-02 21:12:22 +00:00
FbTk : : RefCount < FbTk : : Command > restart_fb ( CommandParser : : instance ( ) . parseLine ( " restart " ) ) ;
FbTk : : RefCount < FbTk : : Command > exit_fb ( CommandParser : : instance ( ) . parseLine ( " exit " ) ) ;
FbTk : : RefCount < FbTk : : Command > execute_xterm ( CommandParser : : instance ( ) . parseLine ( " exec xterm " ) ) ;
2002-12-13 20:19:05 +00:00
m_rootmenu - > setInternalMenu ( ) ;
2004-06-07 11:46:05 +00:00
m_rootmenu - > insert ( _FBTEXT ( Menu , xterm , " xterm " , " xterm - in fallback menu " ) ,
2003-01-09 17:41:02 +00:00
execute_xterm ) ;
2004-06-07 11:46:05 +00:00
m_rootmenu - > insert ( _FBTEXT ( Menu , Restart , " Restart " , " Restart command " ) ,
2003-01-09 17:41:02 +00:00
restart_fb ) ;
2004-06-07 11:46:05 +00:00
m_rootmenu - > insert ( _FBTEXT ( Menu , Exit , " Exit " , " Exit command " ) ,
2003-01-09 17:41:02 +00:00
exit_fb ) ;
2003-08-10 12:50:04 +00:00
}
2001-12-11 20:47:02 +00:00
2004-12-13 14:03:17 +00:00
m_rootmenu - > updateMenu ( ) ;
2001-12-11 20:47:02 +00:00
}
2004-05-02 21:12:22 +00:00
2003-07-20 02:45:57 +00:00
void BScreen : : addConfigMenu ( const char * label , FbTk : : Menu & menu ) {
m_configmenu_list . push_back ( std : : make_pair ( label , & menu ) ) ;
setupConfigmenu ( * m_configmenu . get ( ) ) ;
}
void BScreen : : removeConfigMenu ( FbTk : : Menu & menu ) {
2005-05-02 12:10:01 +00:00
Configmenus : : iterator erase_it = find_if ( m_configmenu_list . begin ( ) ,
m_configmenu_list . end ( ) ,
FbTk : : Compose ( bind2nd ( equal_to < FbTk : : Menu * > ( ) , & menu ) ,
FbTk : : Select2nd < Configmenus : : value_type > ( ) ) ) ;
if ( erase_it ! = m_configmenu_list . end ( ) )
m_configmenu_list . erase ( erase_it ) ;
2003-07-20 02:45:57 +00:00
setupConfigmenu ( * m_configmenu . get ( ) ) ;
2004-06-14 12:25:31 +00:00
2003-07-20 02:45:57 +00:00
}
2003-01-12 17:59:20 +00:00
void BScreen : : setupConfigmenu ( FbTk : : Menu & menu ) {
2004-06-07 11:46:05 +00:00
_FB_USES_NLS ;
2003-01-12 17:59:20 +00:00
2003-07-20 02:45:57 +00:00
menu . removeAll ( ) ;
2003-01-12 17:59:20 +00:00
FbTk : : MacroCommand * s_a_reconf_macro = new FbTk : : MacroCommand ( ) ;
2003-02-15 02:03:09 +00:00
FbTk : : RefCount < FbTk : : Command > saverc_cmd ( new FbTk : : SimpleCommand < Fluxbox > ( * Fluxbox : : instance ( ) ,
& Fluxbox : : save_rc ) ) ;
2004-05-02 21:12:22 +00:00
FbTk : : RefCount < FbTk : : Command > reconf_cmd ( CommandParser : : instance ( ) . parseLine ( " reconfigure " ) ) ;
2003-01-12 17:59:20 +00:00
s_a_reconf_macro - > add ( saverc_cmd ) ;
s_a_reconf_macro - > add ( reconf_cmd ) ;
FbTk : : RefCount < FbTk : : Command > save_and_reconfigure ( s_a_reconf_macro ) ;
2003-02-20 23:31:13 +00:00
// create focus menu
2003-04-26 15:00:25 +00:00
// we don't set this to internal menu so will
// be deleted toghether with the parent
2004-06-07 11:46:05 +00:00
const char * focusmenu_label = _FBTEXT ( Configmenu , FocusModel ,
" Focus Model " , " Method used to give focus to windows " ) ;
2003-12-10 23:08:06 +00:00
FbTk : : Menu * focus_menu = createMenu ( focusmenu_label ? focusmenu_label : " " ) ;
2003-02-20 23:31:13 +00:00
2004-06-07 11:46:05 +00:00
# define _FOCUSITEM(a, b, c, d, e) focus_menu->insert(new FocusModelMenuItem(_FBTEXT(a, b, c, d), *this, e, save_and_reconfigure))
2004-05-02 21:12:22 +00:00
2004-06-07 11:46:05 +00:00
_FOCUSITEM ( Configmenu , ClickToFocus ,
" Click To Focus " , " Click to focus " ,
2004-05-02 21:12:22 +00:00
CLICKTOFOCUS ) ;
2004-06-07 11:46:05 +00:00
_FOCUSITEM ( Configmenu , SloppyFocus ,
" Sloppy Focus " , " Sloppy Focus " ,
2004-05-02 21:12:22 +00:00
SLOPPYFOCUS ) ;
2004-06-07 11:46:05 +00:00
_FOCUSITEM ( Configmenu , SemiSloppyFocus ,
" Semi Sloppy Focus " , " Semi Sloppy Focus " ,
2004-05-02 21:12:22 +00:00
SEMISLOPPYFOCUS ) ;
# undef _FOCUSITEM
2003-08-04 12:57:23 +00:00
2004-06-07 11:46:05 +00:00
focus_menu - > insert ( new BoolMenuItem ( _FBTEXT ( Configmenu ,
AutoRaise ,
" Auto Raise " ,
" Auto Raise windows on sloppy " ) ,
2003-02-22 16:09:44 +00:00
* resource . auto_raise ,
2003-02-20 23:31:13 +00:00
save_and_reconfigure ) ) ;
2004-12-13 14:03:17 +00:00
focus_menu - > updateMenu ( ) ;
2003-04-16 00:38:06 +00:00
2003-07-25 10:03:55 +00:00
menu . insert ( focusmenu_label , focus_menu ) ;
2003-01-12 17:59:20 +00:00
# ifdef SLIT
2003-05-15 12:00:46 +00:00
if ( slit ( ) ! = 0 ) {
slit ( ) - > menu ( ) . setInternalMenu ( ) ;
menu . insert ( " Slit " , & slit ( ) - > menu ( ) ) ;
2003-04-26 15:00:25 +00:00
}
2003-01-12 17:59:20 +00:00
# endif // SLIT
2003-06-25 05:47:23 +00:00
2003-07-20 02:45:57 +00:00
Configmenus : : iterator it = m_configmenu_list . begin ( ) ;
Configmenus : : iterator it_end = m_configmenu_list . end ( ) ;
for ( ; it ! = it_end ; + + it )
menu . insert ( it - > first , it - > second ) ;
2004-06-07 11:46:05 +00:00
# define _BOOLITEM(a, b, c, d, e, f) menu.insert(new BoolMenuItem(_FBTEXT(a, b, c, d), e, f))
2004-05-02 21:12:22 +00:00
2004-06-07 11:46:05 +00:00
_BOOLITEM ( Configmenu , ImageDithering ,
" Image Dithering " , " Image Dithering " ,
2004-05-02 21:12:22 +00:00
* resource . image_dither , save_and_reconfigure ) ;
2004-06-07 11:46:05 +00:00
_BOOLITEM ( Configmenu , OpaqueMove ,
" Opaque Window Moving " , " Window Moving with whole window visible (as opposed to outline moving) " ,
2004-05-02 21:12:22 +00:00
* resource . opaque_move , saverc_cmd ) ;
2004-06-07 11:46:05 +00:00
_BOOLITEM ( Configmenu , FullMax ,
" Full Maximization " , " Maximise over slit, toolbar, etc " ,
2004-05-02 21:12:22 +00:00
* resource . full_max , saverc_cmd ) ;
2004-06-07 11:46:05 +00:00
_BOOLITEM ( Configmenu , FocusNew ,
" Focus New Windows " , " Focus newly created windows " ,
2004-05-02 21:12:22 +00:00
* resource . focus_new , saverc_cmd ) ;
2004-06-07 11:46:05 +00:00
_BOOLITEM ( Configmenu , FocusLast ,
" Focus Last Window on Workspace " , " Focus Last Window on Workspace " ,
2004-05-02 21:12:22 +00:00
* resource . focus_last , saverc_cmd ) ;
2004-06-07 11:46:05 +00:00
_BOOLITEM ( Configmenu , WorkspaceWarping ,
" Workspace Warping " , " Workspace Warping - dragging windows to the edge and onto the next workspace " ,
2004-05-02 21:12:22 +00:00
* resource . workspace_warping , saverc_cmd ) ;
2004-06-07 11:46:05 +00:00
_BOOLITEM ( Configmenu , DesktopWheeling ,
" Desktop MouseWheel Switching " , " Workspace switching using mouse wheel " ,
2004-05-02 21:12:22 +00:00
* resource . desktop_wheeling , saverc_cmd ) ;
2004-06-07 11:46:05 +00:00
_BOOLITEM ( Configmenu , DecorateTransient ,
" Decorate Transient Windows " , " Decorate Transient Windows " ,
2004-05-02 21:12:22 +00:00
* resource . decorate_transient , saverc_cmd ) ;
2004-06-07 11:46:05 +00:00
_BOOLITEM ( Configmenu , ClickRaises ,
" Click Raises " , " Click Raises " ,
2004-05-02 21:12:22 +00:00
* resource . click_raises , saverc_cmd ) ;
2004-08-30 11:33:23 +00:00
# ifdef USE_XFT
2003-02-17 12:35:59 +00:00
// setup antialias cmd to reload style and save resource on toggle
2004-06-07 11:46:05 +00:00
_BOOLITEM ( Configmenu , AntiAlias ,
" AntiAlias " , " Use Anti-aliased fonts " ,
2004-05-02 21:12:22 +00:00
* resource . antialias , save_and_reconfigure ) ;
2004-08-30 11:33:23 +00:00
# endif // USE_XFT
2004-05-02 21:12:22 +00:00
2004-08-30 11:33:23 +00:00
# ifdef HAVE_XRENDER
2004-09-12 14:56:20 +00:00
if ( FbTk : : Transparent : : haveRender ( ) | |
FbTk : : Transparent : : haveComposite ( ) ) {
const char * alphamenu_label = _FBTEXT ( Configmenu , Transparency ,
" Transparency " , " Menu containing various transparency options " ) ;
FbTk : : Menu * alpha_menu = createMenu ( alphamenu_label ? alphamenu_label : " " ) ;
if ( FbTk : : Transparent : : haveComposite ( true ) ) {
alpha_menu - > insert ( new BoolMenuItem ( _FBTEXT ( Configmenu , ForcePseudoTrans ,
" Force Pseudo-Transparency " , " When composite is available, still use old pseudo-transparency " ) ,
Fluxbox : : instance ( ) - > getPseudoTrans ( ) , save_and_reconfigure ) ) ;
}
FbTk : : MenuItem * focused_alpha_item = new IntResMenuItem ( _FBTEXT ( Configmenu , FocusedAlpha , " Focused Window Alpha " , " Transparency level of the focused window " ) ,
2005-05-03 13:53:25 +00:00
resource . focused_alpha , 0 , 255 , * alpha_menu ) ;
2004-09-12 14:56:20 +00:00
focused_alpha_item - > setCommand ( saverc_cmd ) ;
alpha_menu - > insert ( focused_alpha_item ) ;
FbTk : : MenuItem * unfocused_alpha_item = new IntResMenuItem ( _FBTEXT ( Configmenu , UnfocusedAlpha , " Unfocused Window Alpha " , " Transparency level of unfocused windows " ) ,
2005-05-03 13:53:25 +00:00
resource . unfocused_alpha , 0 , 255 , * alpha_menu ) ;
2004-09-12 14:56:20 +00:00
unfocused_alpha_item - > setCommand ( saverc_cmd ) ;
alpha_menu - > insert ( unfocused_alpha_item ) ;
FbTk : : MenuItem * menu_alpha_item = new IntResMenuItem ( _FBTEXT ( Configmenu , MenuAlpha , " Menu Alpha " , " Transparency level of menu " ) ,
2005-05-03 13:53:25 +00:00
resource . menu_alpha , 0 , 255 , * alpha_menu ) ;
2004-09-12 14:56:20 +00:00
menu_alpha_item - > setCommand ( saverc_cmd ) ;
alpha_menu - > insert ( menu_alpha_item ) ;
2004-12-13 14:03:17 +00:00
alpha_menu - > updateMenu ( ) ;
2004-09-12 14:56:20 +00:00
menu . insert ( alphamenu_label , alpha_menu ) ;
}
2004-08-30 11:33:23 +00:00
# endif // HAVE_XRENDER
2004-09-12 14:56:20 +00:00
# undef _BOOLITEM
2003-04-20 13:46:18 +00:00
2003-01-12 17:59:20 +00:00
// finaly update menu
2004-12-13 14:03:17 +00:00
menu . updateMenu ( ) ;
2003-01-12 17:59:20 +00:00
}
2001-12-11 20:47:02 +00:00
2002-08-02 12:58:37 +00:00
void BScreen : : shutdown ( ) {
2003-05-10 22:59:32 +00:00
rootWindow ( ) . setEventMask ( NoEventMask ) ;
2003-12-04 21:31:02 +00:00
FbTk : : App : : instance ( ) - > sync ( false ) ;
2003-08-12 12:21:42 +00:00
m_shutdown = true ;
2003-05-19 22:45:51 +00:00
for_each ( m_workspaces_list . begin ( ) ,
m_workspaces_list . end ( ) ,
2003-04-14 15:01:55 +00:00
mem_fun ( & Workspace : : shutdown ) ) ;
2001-12-11 20:47:02 +00:00
}
void BScreen : : showPosition ( int x , int y ) {
2004-06-07 11:46:05 +00:00
if ( ! doShowWindowPos ( ) )
2003-12-10 22:28:07 +00:00
return ;
2004-01-16 11:47:07 +00:00
if ( ! pos_visible ) {
2003-05-19 22:45:51 +00:00
if ( hasXinerama ( ) ) {
unsigned int head = getCurrHead ( ) ;
2004-01-16 11:47:07 +00:00
m_pos_window . move ( getHeadX ( head ) + ( getHeadWidth ( head ) - m_pos_window . width ( ) ) / 2 ,
getHeadY ( head ) + ( getHeadHeight ( head ) - m_pos_window . height ( ) ) / 2 ) ;
2003-05-19 22:45:51 +00:00
} else {
2004-01-16 11:47:07 +00:00
m_pos_window . move ( ( width ( ) - m_pos_window . width ( ) ) / 2 , ( height ( ) - m_pos_window . height ( ) ) / 2 ) ;
2003-05-19 22:45:51 +00:00
}
2002-03-19 14:30:43 +00:00
2004-01-16 11:47:07 +00:00
m_pos_window . show ( ) ;
m_pos_window . raise ( ) ;
2001-12-11 20:47:02 +00:00
2004-01-16 11:47:07 +00:00
pos_visible = true ;
2002-12-01 13:42:15 +00:00
}
2003-02-20 23:31:13 +00:00
char label [ 256 ] ;
2004-06-07 11:46:05 +00:00
_FB_USES_NLS ;
2003-02-20 23:31:13 +00:00
sprintf ( label ,
2004-06-07 11:46:05 +00:00
_FBTEXT ( Screen , PositionFormat ,
" X: %4d x Y: %4d " ,
" Format for screen coordinates - %4d for X, and %4d for Y " ) , x , y ) ;
2003-02-16 01:14:54 +00:00
2004-01-16 11:47:07 +00:00
m_pos_window . clear ( ) ;
2003-02-16 01:14:54 +00:00
2004-09-11 23:01:34 +00:00
winFrameTheme ( ) . font ( ) . drawText ( m_pos_window ,
2003-05-15 12:00:46 +00:00
screenNumber ( ) ,
winFrameTheme ( ) . labelTextFocusGC ( ) ,
label , strlen ( label ) ,
2003-09-12 23:35:31 +00:00
winFrameTheme ( ) . bevelWidth ( ) ,
winFrameTheme ( ) . bevelWidth ( ) +
2003-05-15 12:00:46 +00:00
winFrameTheme ( ) . font ( ) . ascent ( ) ) ;
2002-10-15 17:17:00 +00:00
2001-12-11 20:47:02 +00:00
}
2004-01-16 11:47:07 +00:00
void BScreen : : hidePosition ( ) {
if ( pos_visible ) {
m_pos_window . hide ( ) ;
pos_visible = false ;
}
}
2001-12-11 20:47:02 +00:00
void BScreen : : showGeometry ( unsigned int gx , unsigned int gy ) {
2003-12-10 22:28:07 +00:00
if ( ! doShowWindowPos ( ) )
return ;
2002-12-01 13:42:15 +00:00
if ( ! geom_visible ) {
2003-05-19 22:45:51 +00:00
if ( hasXinerama ( ) ) {
unsigned int head = getCurrHead ( ) ;
m_geom_window . move ( getHeadX ( head ) + ( getHeadWidth ( head ) - m_geom_window . width ( ) ) / 2 ,
getHeadY ( head ) + ( getHeadHeight ( head ) - m_geom_window . height ( ) ) / 2 ) ;
} else {
m_geom_window . move ( ( width ( ) - m_geom_window . width ( ) ) / 2 , ( height ( ) - m_geom_window . height ( ) ) / 2 ) ;
}
m_geom_window . show ( ) ;
m_geom_window . raise ( ) ;
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
geom_visible = true ;
}
2001-12-11 20:47:02 +00:00
2003-02-20 23:31:13 +00:00
char label [ 256 ] ;
2004-06-07 11:46:05 +00:00
_FB_USES_NLS ;
2002-12-01 13:42:15 +00:00
sprintf ( label ,
2004-06-07 11:46:05 +00:00
_FBTEXT ( Screen , GeometryFormat ,
" W: %4d x H: %4d " ,
2004-09-11 23:01:34 +00:00
" Format for width and height window, %4d for width, and %4d for height " ) ,
2004-06-07 11:46:05 +00:00
gx , gy ) ;
2002-12-01 13:42:15 +00:00
2003-05-19 22:45:51 +00:00
m_geom_window . clear ( ) ;
2002-12-01 13:42:15 +00:00
2003-08-18 11:26:17 +00:00
//!! TODO: geom window again?! repeated
2004-09-11 23:01:34 +00:00
winFrameTheme ( ) . font ( ) . drawText ( m_geom_window ,
2003-05-15 12:00:46 +00:00
screenNumber ( ) ,
winFrameTheme ( ) . labelTextFocusGC ( ) ,
label , strlen ( label ) ,
2003-09-12 23:35:31 +00:00
winFrameTheme ( ) . bevelWidth ( ) ,
winFrameTheme ( ) . bevelWidth ( ) +
2003-05-15 12:00:46 +00:00
winFrameTheme ( ) . font ( ) . ascent ( ) ) ;
2001-12-11 20:47:02 +00:00
}
2002-08-02 12:58:37 +00:00
void BScreen : : hideGeometry ( ) {
2002-12-01 13:42:15 +00:00
if ( geom_visible ) {
2003-05-19 22:45:51 +00:00
m_geom_window . hide ( ) ;
2002-12-01 13:42:15 +00:00
geom_visible = false ;
}
2001-12-11 20:47:02 +00:00
}
2003-02-02 16:32:41 +00:00
void BScreen : : setLayer ( FbTk : : XLayerItem & item , int layernum ) {
2003-02-03 13:56:12 +00:00
m_layermanager . moveToLayer ( item , layernum ) ;
2003-02-02 16:32:41 +00:00
}
2002-11-27 21:55:36 +00:00
/**
Goes to the workspace " right " of the current
*/
2002-02-20 23:04:51 +00:00
void BScreen : : nextWorkspace ( const int delta ) {
2003-05-15 12:00:46 +00:00
changeWorkspaceID ( ( currentWorkspaceID ( ) + delta ) % getCount ( ) ) ;
2001-12-11 20:47:02 +00:00
}
2002-11-27 21:55:36 +00:00
/**
Goes to the workspace " left " of the current
*/
2002-02-20 23:04:51 +00:00
void BScreen : : prevWorkspace ( const int delta ) {
2003-05-15 12:00:46 +00:00
changeWorkspaceID ( ( currentWorkspaceID ( ) - delta + getCount ( ) ) % getCount ( ) ) ;
2001-12-11 20:47:02 +00:00
}
2002-02-02 19:51:15 +00:00
2002-11-27 21:55:36 +00:00
/**
Goes to the workspace " right " of the current
*/
2002-02-20 23:04:51 +00:00
void BScreen : : rightWorkspace ( const int delta ) {
2003-05-15 12:00:46 +00:00
if ( currentWorkspaceID ( ) + delta < getCount ( ) )
changeWorkspaceID ( currentWorkspaceID ( ) + delta ) ;
2002-02-02 19:51:15 +00:00
}
2002-11-27 21:55:36 +00:00
/**
Goes to the workspace " left " of the current
*/
2002-02-20 23:04:51 +00:00
void BScreen : : leftWorkspace ( const int delta ) {
2003-05-15 12:00:46 +00:00
if ( currentWorkspaceID ( ) > = static_cast < unsigned int > ( delta ) )
changeWorkspaceID ( currentWorkspaceID ( ) - delta ) ;
2002-02-02 19:51:15 +00:00
}
2002-02-07 14:46:23 +00:00
2002-11-27 21:55:36 +00:00
/**
@ return true if the windows should be skiped else false
*/
2003-06-15 11:37:53 +00:00
bool BScreen : : doSkipWindow ( const WinClient & winclient , int opts ) {
const FluxboxWindow * win = winclient . fbwindow ( ) ;
return ( ! win | |
( opts & CYCLESKIPSTUCK ) ! = 0 & & win - > isStuck ( ) | | // skip if stuck
2003-06-15 20:09:13 +00:00
// skip if not active client (i.e. only visit each fbwin once)
2003-07-28 15:06:36 +00:00
( opts & CYCLEGROUPS ) ! = 0 & & win - > winClient ( ) . window ( ) ! = winclient . window ( ) | |
2004-01-19 18:29:43 +00:00
( opts & CYCLESKIPSHADED ) ! = 0 & & win - > isShaded ( ) | | // skip if shaded
2004-02-20 09:07:27 +00:00
win - > isFocusHidden ( )
2003-08-04 12:57:23 +00:00
) ;
2002-04-02 23:14:54 +00:00
}
2003-06-12 15:24:37 +00:00
void BScreen : : renderGeomWindow ( ) {
2004-06-07 11:46:05 +00:00
_FB_USES_NLS ;
2003-08-25 13:15:53 +00:00
2004-06-07 11:46:05 +00:00
const char * s = _FBTEXT ( Screen ,
GeometryLength ,
" W: 0000 x H: 0000 " ,
" Representative maximum sized text for width and height dialog " ) ;
2003-08-25 13:15:53 +00:00
int l = strlen ( s ) ;
2003-09-12 23:35:31 +00:00
int geom_h = winFrameTheme ( ) . font ( ) . height ( ) + winFrameTheme ( ) . bevelWidth ( ) * 2 ;
int geom_w = winFrameTheme ( ) . font ( ) . textWidth ( s , l ) + winFrameTheme ( ) . bevelWidth ( ) * 2 ;
2003-08-25 13:15:53 +00:00
m_geom_window . resize ( geom_w , geom_h ) ;
2003-08-25 16:07:09 +00:00
m_geom_window . setBorderWidth ( winFrameTheme ( ) . border ( ) . width ( ) ) ;
m_geom_window . setBorderColor ( winFrameTheme ( ) . border ( ) . color ( ) ) ;
2003-08-25 13:15:53 +00:00
2003-06-12 15:24:37 +00:00
Pixmap tmp = geom_pixmap ;
if ( winFrameTheme ( ) . labelFocusTexture ( ) . type ( ) & FbTk : : Texture : : PARENTRELATIVE ) {
2003-12-07 16:39:43 +00:00
if ( ! winFrameTheme ( ) . titleFocusTexture ( ) . usePixmap ( ) ) {
2003-06-12 15:24:37 +00:00
geom_pixmap = None ;
m_geom_window . setBackgroundColor ( winFrameTheme ( ) . titleFocusTexture ( ) . color ( ) ) ;
} else {
geom_pixmap = imageControl ( ) . renderImage ( m_geom_window . width ( ) , m_geom_window . height ( ) ,
winFrameTheme ( ) . titleFocusTexture ( ) ) ;
m_geom_window . setBackgroundPixmap ( geom_pixmap ) ;
}
} else {
2003-12-07 16:39:43 +00:00
if ( ! winFrameTheme ( ) . labelFocusTexture ( ) . usePixmap ( ) ) {
2003-06-12 15:24:37 +00:00
geom_pixmap = None ;
m_geom_window . setBackgroundColor ( winFrameTheme ( ) . labelFocusTexture ( ) . color ( ) ) ;
} else {
geom_pixmap = imageControl ( ) . renderImage ( m_geom_window . width ( ) , m_geom_window . height ( ) ,
winFrameTheme ( ) . labelFocusTexture ( ) ) ;
m_geom_window . setBackgroundPixmap ( geom_pixmap ) ;
}
}
if ( tmp )
imageControl ( ) . removeImage ( tmp ) ;
}
2004-01-16 11:47:07 +00:00
void BScreen : : renderPosWindow ( ) {
2004-06-07 11:46:05 +00:00
_FB_USES_NLS ;
2004-01-16 11:47:07 +00:00
2004-06-07 11:46:05 +00:00
const char * s = _FBTEXT ( Screen ,
PositionLength ,
" 0: 0000 x 0: 0000 " ,
" Representative maximum sized text for X and Y dialog " ) ;
2004-01-16 11:47:07 +00:00
int l = strlen ( s ) ;
int pos_h = winFrameTheme ( ) . font ( ) . height ( ) + winFrameTheme ( ) . bevelWidth ( ) * 2 ;
int pos_w = winFrameTheme ( ) . font ( ) . textWidth ( s , l ) + winFrameTheme ( ) . bevelWidth ( ) * 2 ;
m_pos_window . resize ( pos_w , pos_h ) ;
m_pos_window . setBorderWidth ( winFrameTheme ( ) . border ( ) . width ( ) ) ;
m_pos_window . setBorderColor ( winFrameTheme ( ) . border ( ) . color ( ) ) ;
Pixmap tmp = pos_pixmap ;
if ( winFrameTheme ( ) . labelFocusTexture ( ) . type ( ) & FbTk : : Texture : : PARENTRELATIVE ) {
if ( ! winFrameTheme ( ) . titleFocusTexture ( ) . usePixmap ( ) ) {
pos_pixmap = None ;
m_pos_window . setBackgroundColor ( winFrameTheme ( ) . titleFocusTexture ( ) . color ( ) ) ;
} else {
pos_pixmap = imageControl ( ) . renderImage ( m_pos_window . width ( ) , m_pos_window . height ( ) ,
winFrameTheme ( ) . titleFocusTexture ( ) ) ;
m_pos_window . setBackgroundPixmap ( pos_pixmap ) ;
}
} else {
if ( ! winFrameTheme ( ) . labelFocusTexture ( ) . usePixmap ( ) ) {
pos_pixmap = None ;
m_pos_window . setBackgroundColor ( winFrameTheme ( ) . labelFocusTexture ( ) . color ( ) ) ;
} else {
pos_pixmap = imageControl ( ) . renderImage ( m_pos_window . width ( ) , m_pos_window . height ( ) ,
winFrameTheme ( ) . labelFocusTexture ( ) ) ;
m_pos_window . setBackgroundPixmap ( pos_pixmap ) ;
}
}
if ( tmp )
imageControl ( ) . removeImage ( tmp ) ;
}
2003-04-15 00:50:25 +00:00
/**
Called when a set of watched modifiers has been released
*/
void BScreen : : notifyReleasedKeys ( XKeyEvent & ke ) {
if ( cycling_focus ) {
cycling_focus = false ;
2003-04-27 14:36:05 +00:00
cycling_last = 0 ;
2003-04-15 00:50:25 +00:00
// put currently focused window to top
2003-06-23 14:16:05 +00:00
// the iterator may be invalid if the window died
// in which case we'll do a proper revert focus
if ( cycling_window ! = focused_list . end ( ) ) {
WinClient * client = * cycling_window ;
focused_list . erase ( cycling_window ) ;
focused_list . push_front ( client ) ;
client - > fbwindow ( ) - > raise ( ) ;
} else {
Fluxbox : : instance ( ) - > revertFocus ( * this ) ;
}
2003-04-15 00:50:25 +00:00
}
}
2003-05-04 23:38:06 +00:00
/**
* Used to find out which window was last focused on the given workspace
* If workspace is outside the ID range , then the absolute last focused window
* is given .
*/
WinClient * BScreen : : getLastFocusedWindow ( int workspace ) {
if ( focused_list . empty ( ) ) return 0 ;
if ( workspace < 0 | | workspace > = ( int ) getCount ( ) )
return focused_list . front ( ) ;
FocusedWindows : : iterator it = focused_list . begin ( ) ;
FocusedWindows : : iterator it_end = focused_list . end ( ) ;
2003-12-18 15:27:21 +00:00
for ( ; it ! = it_end ; + + it ) {
2003-05-04 23:38:06 +00:00
if ( ( * it ) - > fbwindow ( ) & &
2003-05-15 11:17:29 +00:00
( ( ( int ) ( * it ) - > fbwindow ( ) - > workspaceNumber ( ) ) = = workspace
2003-05-13 11:14:05 +00:00
& & ! ( * it ) - > fbwindow ( ) - > isIconic ( )
2003-05-08 01:51:18 +00:00
& & ( ! ( * it ) - > fbwindow ( ) - > isStuck ( ) | | ( * it ) - > fbwindow ( ) - > isFocused ( ) ) ) )
// only give focus to a stuck window if it is currently focused
// otherwise they tend to override normal workspace focus
2003-05-04 23:38:06 +00:00
return * it ;
2003-12-18 15:27:21 +00:00
}
2003-05-04 23:38:06 +00:00
return 0 ;
}
2004-03-21 09:00:25 +00:00
/**
* Used to find out which window was last active in the given group
* If ignore_client is given , it excludes that client .
* Stuck , iconic etc don ' t matter within a group
*/
WinClient * BScreen : : getLastFocusedWindow ( FluxboxWindow & group , WinClient * ignore_client ) {
if ( focused_list . empty ( ) ) return 0 ;
FocusedWindows : : iterator it = focused_list . begin ( ) ;
FocusedWindows : : iterator it_end = focused_list . end ( ) ;
for ( ; it ! = it_end ; + + it ) {
if ( ( ( * it ) - > fbwindow ( ) = = & group ) & &
( * it ) ! = ignore_client )
return * it ;
}
return 0 ;
}
2003-05-12 04:28:46 +00:00
void BScreen : : updateSize ( ) {
2003-12-18 15:27:21 +00:00
// force update geometry
2003-05-12 04:28:46 +00:00
rootWindow ( ) . updateGeometry ( ) ;
2003-05-12 04:47:34 +00:00
// reset background
m_root_theme - > reconfigTheme ( ) ;
2003-12-18 15:27:21 +00:00
// send resize notify
2003-08-24 13:07:01 +00:00
m_resize_sig . notify ( ) ;
2003-05-12 04:28:46 +00:00
}
2003-05-19 14:26:30 +00:00
2003-05-19 15:32:47 +00:00
2003-06-23 14:16:05 +00:00
/**
* Find the group of windows to this window ' s left
* So , we check the leftgroup hint , and see if we know any windows
*/
FluxboxWindow * BScreen : : findGroupLeft ( WinClient & winclient ) {
Window w = winclient . getGroupLeftWindow ( ) ;
if ( w = = None )
return 0 ;
2003-07-28 15:06:36 +00:00
WinClient * have_client = Fluxbox : : instance ( ) - > searchWindow ( w ) ;
2003-06-23 14:16:05 +00:00
2003-07-28 15:06:36 +00:00
if ( ! have_client ) {
2003-06-23 14:16:05 +00:00
// not found, add it to expecting
m_expecting_groups [ w ] = & winclient ;
2003-07-28 15:06:36 +00:00
} else if ( & have_client - > screen ( ) ! = & winclient . screen ( ) )
2003-06-23 14:16:05 +00:00
// something is not consistent
return 0 ;
2003-07-28 15:06:36 +00:00
if ( have_client )
return have_client - > fbwindow ( ) ;
else
return 0 ;
2003-06-23 14:16:05 +00:00
}
FluxboxWindow * BScreen : : findGroupRight ( WinClient & winclient ) {
Groupables : : iterator it = m_expecting_groups . find ( winclient . window ( ) ) ;
if ( it = = m_expecting_groups . end ( ) )
return 0 ;
// yay, this'll do.
WinClient * other = it - > second ;
m_expecting_groups . erase ( it ) ; // don't expect it anymore
// forget about it if it isn't the left-most client in the group, plus
// it must have the atom set on it (i.e. previously encountered by fluxbox)
// for us to check our expecting
if ( ! winclient . hasGroupLeftWindow ( ) | |
other - > getGroupLeftWindow ( ) ! = None )
return 0 ;
2005-04-29 02:52:36 +00:00
return other - > fbwindow ( ) ;
2003-06-23 14:16:05 +00:00
}
2003-05-19 15:32:47 +00:00
void BScreen : : initXinerama ( ) {
2003-05-19 14:26:30 +00:00
# ifdef XINERAMA
2003-05-19 15:32:47 +00:00
Display * display = FbTk : : App : : instance ( ) - > display ( ) ;
2003-05-19 14:26:30 +00:00
if ( ! XineramaIsActive ( display ) ) {
2004-09-11 13:33:07 +00:00
# ifdef DEBUG
cerr < < " BScreen::initXinerama(): dont have Xinerama " < < endl ;
# endif // DEBUG
2003-05-19 14:26:30 +00:00
m_xinerama_avail = false ;
m_xinerama_headinfo = 0 ;
2003-05-22 01:17:15 +00:00
m_xinerama_num_heads = 0 ;
2003-05-19 14:26:30 +00:00
return ;
}
2004-09-11 13:33:07 +00:00
# ifdef DEBUG
cerr < < " BScreen::initXinerama(): have Xinerama " < < endl ;
# endif // DEBUG
2003-05-19 14:26:30 +00:00
m_xinerama_avail = true ;
XineramaScreenInfo * screen_info ;
int number ;
screen_info = XineramaQueryScreens ( display , & number ) ;
m_xinerama_headinfo = new XineramaHeadInfo [ number ] ;
m_xinerama_num_heads = number ;
for ( int i = 0 ; i < number ; i + + ) {
m_xinerama_headinfo [ i ] . x = screen_info [ i ] . x_org ;
m_xinerama_headinfo [ i ] . y = screen_info [ i ] . y_org ;
m_xinerama_headinfo [ i ] . width = screen_info [ i ] . width ;
m_xinerama_headinfo [ i ] . height = screen_info [ i ] . height ;
}
2004-11-22 19:40:34 +00:00
XFree ( screen_info ) ;
2004-09-11 13:33:07 +00:00
# ifdef DEBUG
cerr < < " BScreen::initXinerama(): number of heads = " < < number < < endl ;
# endif // DEBUG
2003-05-19 15:32:47 +00:00
# else // XINERAMA
2003-05-19 22:45:51 +00:00
// no xinerama
2003-05-19 15:32:47 +00:00
m_xinerama_avail = false ;
m_xinerama_num_heads = 0 ;
# endif // XINERAMA
2003-05-19 14:26:30 +00:00
}
int BScreen : : getHead ( int x , int y ) const {
if ( ! hasXinerama ( ) ) return 0 ;
2003-05-19 15:32:47 +00:00
# ifdef XINERAMA
2003-05-19 14:26:30 +00:00
for ( int i = 0 ; i < m_xinerama_num_heads ; i + + ) {
if ( x > = m_xinerama_headinfo [ i ] . x & &
x < ( m_xinerama_headinfo [ i ] . x + m_xinerama_headinfo [ i ] . width ) & &
y > = m_xinerama_headinfo [ i ] . y & &
y < ( m_xinerama_headinfo [ i ] . y + m_xinerama_headinfo [ i ] . height ) ) {
return i + 1 ;
}
}
2003-05-19 15:32:47 +00:00
# endif // XINERAMA
2003-05-19 14:26:30 +00:00
return 0 ;
}
2003-05-20 11:03:11 +00:00
int BScreen : : getHead ( FbTk : : FbWindow & win ) const {
if ( hasXinerama ( ) )
return getHead ( win . x ( ) + win . width ( ) / 2 , win . y ( ) + win . height ( ) / 2 ) ;
else
return 0 ;
}
2003-05-19 14:26:30 +00:00
int BScreen : : getCurrHead ( ) const {
if ( ! hasXinerama ( ) ) return 0 ;
2003-05-19 15:32:47 +00:00
int root_x = 0 , root_y = 0 ;
# ifdef XINERAMA
int ignore_i ;
2003-05-19 14:26:30 +00:00
unsigned int ignore_ui ;
Window ignore_w ;
XQueryPointer ( FbTk : : App : : instance ( ) - > display ( ) ,
rootWindow ( ) . window ( ) , & ignore_w ,
& ignore_w , & root_x , & root_y ,
& ignore_i , & ignore_i , & ignore_ui ) ;
2003-05-19 15:32:47 +00:00
# endif // XINERAMA
2003-05-19 14:26:30 +00:00
return getHead ( root_x , root_y ) ;
}
int BScreen : : getHeadX ( int head ) const {
2003-05-19 15:32:47 +00:00
# ifdef XINERAMA
2003-05-19 14:26:30 +00:00
if ( head = = 0 | | head > m_xinerama_num_heads ) return 0 ;
return m_xinerama_headinfo [ head - 1 ] . x ;
2003-05-19 15:32:47 +00:00
# else
return 0 ;
# endif // XINERAMA
2003-05-19 14:26:30 +00:00
}
int BScreen : : getHeadY ( int head ) const {
2003-05-19 15:32:47 +00:00
# ifdef XINERAMA
2003-05-19 14:26:30 +00:00
if ( head = = 0 | | head > m_xinerama_num_heads ) return 0 ;
return m_xinerama_headinfo [ head - 1 ] . y ;
2003-05-19 15:32:47 +00:00
# else
return 0 ;
# endif // XINERAMA
2003-05-19 14:26:30 +00:00
}
int BScreen : : getHeadWidth ( int head ) const {
2003-05-19 15:32:47 +00:00
# ifdef XINERAMA
2003-05-19 14:26:30 +00:00
if ( head = = 0 | | head > m_xinerama_num_heads ) return width ( ) ;
return m_xinerama_headinfo [ head - 1 ] . width ;
2003-05-19 15:32:47 +00:00
# else
return width ( ) ;
# endif // XINERAMA
2003-05-19 14:26:30 +00:00
}
int BScreen : : getHeadHeight ( int head ) const {
2003-05-19 15:32:47 +00:00
# ifdef XINERAMA
2003-05-19 14:26:30 +00:00
if ( head = = 0 | | head > m_xinerama_num_heads ) return height ( ) ;
return m_xinerama_headinfo [ head - 1 ] . height ;
2003-05-19 15:32:47 +00:00
# else
return height ( ) ;
# endif // XINERAMA
2003-05-19 14:26:30 +00:00
}
2004-09-11 13:33:07 +00:00
pair < int , int > BScreen : : clampToHead ( int head , int x , int y , int w , int h ) const {
// if there are multiple heads, head=0 is not valid
// a better way would be to search the closest head
if ( head = = 0 & & numHeads ( ) ! = 0 )
head = 1 ;
int hx = getHeadX ( head ) ;
int hy = getHeadY ( head ) ;
int hw = getHeadWidth ( head ) ;
int hh = getHeadHeight ( head ) ;
if ( x + w > hx + hw )
x = hx + hw - w ;
if ( y + h > hy + hh )
y = hy + hh - h ;
if ( x < hx )
x = hx ;
if ( y < hy )
y = hy ;
return make_pair ( x , y ) ;
}
2003-06-23 13:10:52 +00:00
// TODO: when toolbar gets its resources moved into Toolbar.hh/cc, then
// this can be gone and a consistent interface for the two used
// on the actual objects
2004-12-21 16:09:36 +00:00
template < >
void BScreen : : setOnHead < FluxboxWindow > ( FluxboxWindow & win , int head ) {
if ( head > 0 & & head < = numHeads ( ) ) {
int current_head = getHead ( win . fbWindow ( ) ) ;
win . move ( getHeadX ( head ) + win . frame ( ) . x ( ) - getHeadX ( current_head ) ,
getHeadY ( head ) + win . frame ( ) . y ( ) - getHeadY ( current_head ) ) ;
}
}