2002-01-09 14:11:20 +00:00
|
|
|
// Screen.cc for Fluxbox Window Manager
|
2006-02-16 06:53:05 +00:00
|
|
|
// Copyright (c) 2001 - 2006 Henrik Kinnunen (fluxgen at fluxbox dot org)
|
2002-01-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.
|
|
|
|
|
2002-10-25 20:58:14 +00:00
|
|
|
#include "Screen.hh"
|
|
|
|
|
|
|
|
#include "fluxbox.hh"
|
2007-03-04 17:47:37 +00:00
|
|
|
#include "Keys.hh"
|
2002-10-25 20:58:14 +00:00
|
|
|
#include "Window.hh"
|
2007-10-15 18:05:28 +00:00
|
|
|
#include "WindowCmd.hh"
|
2002-10-25 20:58:14 +00:00
|
|
|
#include "Workspace.hh"
|
2004-05-02 21:12:22 +00:00
|
|
|
|
2006-03-16 18:25:33 +00:00
|
|
|
#include "Layer.hh"
|
2006-02-18 11:39:38 +00:00
|
|
|
#include "FocusControl.hh"
|
2006-02-19 11:11:22 +00:00
|
|
|
#include "ScreenPlacement.hh"
|
2006-02-18 11:39:38 +00:00
|
|
|
|
2004-05-02 21:12:22 +00:00
|
|
|
// menus
|
2015-01-15 17:49:35 +00:00
|
|
|
#include "ConfigMenu.hh"
|
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"
|
2008-01-11 07:41:22 +00:00
|
|
|
#include "FbTk/CommandParser.hh"
|
2004-04-19 22:44:42 +00:00
|
|
|
#include "AtomHandler.hh"
|
2004-09-11 13:33:07 +00:00
|
|
|
#include "HeadArea.hh"
|
2011-03-19 14:00:34 +00:00
|
|
|
#include "RectangleUtil.hh"
|
2007-01-20 18:26:55 +00:00
|
|
|
#include "FbCommands.hh"
|
2013-01-10 11:11:24 +00:00
|
|
|
#ifdef USE_SYSTRAY
|
2010-08-23 17:49:47 +00:00
|
|
|
#include "SystemTray.hh"
|
2013-01-10 11:11:24 +00:00
|
|
|
#endif
|
2010-03-17 15:35:07 +00:00
|
|
|
#include "Debug.hh"
|
2004-05-02 21:12:22 +00:00
|
|
|
|
2004-06-07 11:46:05 +00:00
|
|
|
#include "FbTk/I18n.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"
|
2011-02-23 21:49:27 +00:00
|
|
|
#include "FbTk/LayerItem.hh"
|
2003-12-19 00:34:23 +00:00
|
|
|
#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"
|
2006-05-07 10:08:25 +00:00
|
|
|
#include "FbTk/FbString.hh"
|
2007-12-28 06:22:38 +00:00
|
|
|
#include "FbTk/STLUtil.hh"
|
2008-01-02 08:31:18 +00:00
|
|
|
#include "FbTk/KeyUtil.hh"
|
2010-09-09 13:31:54 +00:00
|
|
|
#include "FbTk/Util.hh"
|
2003-12-19 00:34:23 +00:00
|
|
|
|
2012-12-05 14:43:33 +00:00
|
|
|
#ifdef USE_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 {};
|
2012-12-05 14:43:33 +00:00
|
|
|
#endif // USE_SLIT
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2008-01-12 06:36:38 +00:00
|
|
|
#ifdef USE_TOOLBAR
|
|
|
|
#include "Toolbar.hh"
|
|
|
|
#else
|
|
|
|
class Toolbar {};
|
|
|
|
#endif // USE_TOOLBAR
|
|
|
|
|
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_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-11-27 21:55:36 +00:00
|
|
|
#ifdef TIME_WITH_SYS_TIME
|
|
|
|
#include <sys/time.h>
|
|
|
|
#include <time.h>
|
|
|
|
#else // !TIME_WITH_SYS_TIME
|
2015-01-16 09:52:00 +00:00
|
|
|
#ifdef HAVE_SYS_TIME_H
|
2002-11-27 21:55:36 +00:00
|
|
|
#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
|
|
|
|
|
2012-12-12 09:18:20 +00:00
|
|
|
#if defined(HAVE_RANDR) || defined(HAVE_RANDR1_2)
|
2008-01-12 06:36:38 +00:00
|
|
|
#include <X11/extensions/Xrandr.h>
|
|
|
|
#endif // HAVE_RANDR
|
|
|
|
|
2001-12-11 20:47:02 +00:00
|
|
|
#include <iostream>
|
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>
|
2015-01-16 09:52:00 +00:00
|
|
|
#include <cstdarg>
|
|
|
|
#include <cstring>
|
2002-01-20 02:17:23 +00:00
|
|
|
|
2006-10-27 06:57:43 +00:00
|
|
|
using std::cerr;
|
|
|
|
using std::endl;
|
|
|
|
using std::string;
|
|
|
|
using std::make_pair;
|
|
|
|
using std::pair;
|
|
|
|
using std::list;
|
|
|
|
using std::vector;
|
|
|
|
using std::mem_fun;
|
|
|
|
using std::bind2nd;
|
|
|
|
using std::equal_to;
|
|
|
|
|
|
|
|
using std::hex;
|
|
|
|
using std::dec;
|
2001-12-11 20:47:02 +00:00
|
|
|
|
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;
|
2006-10-27 06:57:43 +00:00
|
|
|
cerr<<_FB_CONSOLETEXT(Screen, AnotherWMRunning,
|
2004-06-07 11:46:05 +00:00
|
|
|
"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
|
|
|
|
2010-05-01 12:27:45 +00:00
|
|
|
int calcSquareDistance(int x1, int y1, int x2, int y2) {
|
|
|
|
return (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1);
|
|
|
|
}
|
2010-09-09 13:31:54 +00:00
|
|
|
void clampMenuDelay(int& delay) {
|
|
|
|
delay = FbTk::Util::clamp(delay, 0, 5000);
|
|
|
|
}
|
|
|
|
|
2010-09-18 07:26:05 +00:00
|
|
|
|
2013-01-31 08:13:45 +00:00
|
|
|
Atom atom_fbcmd = 0;
|
|
|
|
Atom atom_wm_check = 0;
|
|
|
|
Atom atom_net_desktop = 0;
|
|
|
|
Atom atom_utf8_string = 0;
|
|
|
|
Atom atom_kde_systray = 0;
|
|
|
|
Atom atom_kwm1 = 0;
|
|
|
|
|
|
|
|
void initAtoms(Display* dpy) {
|
|
|
|
atom_wm_check = XInternAtom(dpy, "_NET_SUPPORTING_WM_CHECK", False);
|
|
|
|
atom_net_desktop = XInternAtom(dpy, "_NET_CURRENT_DESKTOP", False);
|
|
|
|
atom_fbcmd = XInternAtom(dpy, "_FLUXBOX_ACTION", False);
|
|
|
|
atom_utf8_string = XInternAtom(dpy, "UTF8_STRING", False);
|
|
|
|
atom_kde_systray = XInternAtom(dpy, "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR", False);
|
|
|
|
atom_kwm1 = XInternAtom(dpy, "KWM_DOCKWINDOW", False);
|
|
|
|
}
|
|
|
|
|
2004-05-02 21:12:22 +00:00
|
|
|
} // end anonymous namespace
|
2002-01-20 02:17:23 +00:00
|
|
|
|
2006-03-22 12:23:17 +00:00
|
|
|
|
|
|
|
|
2002-01-20 02:17:23 +00:00
|
|
|
|
2003-05-18 22:01:14 +00:00
|
|
|
BScreen::BScreen(FbTk::ResourceManager &rm,
|
2006-10-27 06:57:43 +00:00
|
|
|
const string &screenname,
|
|
|
|
const string &altscreenname,
|
|
|
|
int scrn, int num_layers) :
|
2003-04-28 00:38:42 +00:00
|
|
|
m_layermanager(num_layers),
|
2015-01-16 09:52:00 +00:00
|
|
|
root_colormap_installed(false),
|
2010-09-17 21:34:03 +00:00
|
|
|
m_image_control(0),
|
2015-01-16 09:52:00 +00:00
|
|
|
m_current_workspace(0),
|
2008-01-07 20:08:56 +00:00
|
|
|
m_focused_windowtheme(new FbWinFrameTheme(scrn, ".focus", ".Focus")),
|
|
|
|
m_unfocused_windowtheme(new FbWinFrameTheme(scrn, ".unfocus", ".Unfocus")),
|
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
|
2008-01-08 08:50:58 +00:00
|
|
|
m_focused_winbutton_theme(new WinButtonTheme(scrn, "", "", *m_focused_windowtheme)),
|
|
|
|
m_unfocused_winbutton_theme(new WinButtonTheme(scrn, ".unfocus", ".Unfocus", *m_unfocused_windowtheme)),
|
|
|
|
m_pressed_winbutton_theme(new WinButtonTheme(scrn, ".pressed", ".Pressed", *m_focused_windowtheme)),
|
2007-12-28 07:16:17 +00:00
|
|
|
m_menutheme(new FbTk::MenuTheme(scrn)),
|
2003-05-10 22:59:32 +00:00
|
|
|
m_root_window(scrn),
|
2008-05-09 17:39:02 +00:00
|
|
|
m_geom_window(new OSDWindow(m_root_window, *this, *m_focused_windowtheme)),
|
|
|
|
m_pos_window(new OSDWindow(m_root_window, *this, *m_focused_windowtheme)),
|
|
|
|
m_tooltip_window(new TooltipWindow(m_root_window, *this, *m_focused_windowtheme)),
|
2013-01-31 08:13:45 +00:00
|
|
|
m_dummy_window(scrn, -1, -1, 1, 1, 0, true, false, CopyFromParent, InputOnly),
|
2003-04-28 22:43:26 +00:00
|
|
|
resource(rm, screenname, altscreenname),
|
2006-02-18 11:39:38 +00:00
|
|
|
m_resource_manager(rm),
|
2003-06-20 01:30:08 +00:00
|
|
|
m_name(screenname),
|
|
|
|
m_altname(altscreenname),
|
2006-02-18 11:39:38 +00:00
|
|
|
m_focus_control(new FocusControl(*this)),
|
2006-02-19 11:11:22 +00:00
|
|
|
m_placement_strategy(new ScreenPlacement(*this)),
|
2007-10-24 17:09:26 +00:00
|
|
|
m_cycling(false), m_cycle_opts(0),
|
2006-08-06 22:33:54 +00:00
|
|
|
m_restart(false),
|
2003-08-12 12:21:42 +00:00
|
|
|
m_shutdown(false) {
|
2003-04-28 00:38:42 +00:00
|
|
|
|
2003-12-29 01:23:04 +00:00
|
|
|
|
2008-01-12 06:36:38 +00:00
|
|
|
Fluxbox *fluxbox = Fluxbox::instance();
|
2013-01-31 08:13:45 +00:00
|
|
|
Display *disp = fluxbox->display();
|
|
|
|
|
|
|
|
initAtoms(disp);
|
|
|
|
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2007-07-11 11:54:53 +00:00
|
|
|
// TODO fluxgen: check if this is the right place (it was not -lis)
|
|
|
|
//
|
|
|
|
// Create the first one, initXinerama will expand this if needed.
|
|
|
|
m_head_areas.resize(1);
|
|
|
|
m_head_areas[0] = new HeadArea();
|
|
|
|
|
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
|
|
|
|
2013-01-31 08:13:45 +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;
|
2006-04-22 15:37:04 +00:00
|
|
|
if (! managed) {
|
|
|
|
delete m_placement_strategy; m_placement_strategy = 0;
|
|
|
|
delete m_focus_control; m_focus_control = 0;
|
2002-12-01 13:42:15 +00:00
|
|
|
return;
|
2006-04-22 15:37:04 +00:00
|
|
|
}
|
2004-09-11 13:33:07 +00:00
|
|
|
|
2008-01-12 06:36:38 +00:00
|
|
|
// we're going to manage the screen, so now add our pid
|
|
|
|
#ifdef HAVE_GETPID
|
2011-04-14 13:07:37 +00:00
|
|
|
unsigned long bpid = static_cast<unsigned long>(getpid());
|
2008-01-12 06:36:38 +00:00
|
|
|
|
|
|
|
rootWindow().changeProperty(fluxbox->getFluxboxPidAtom(), XA_CARDINAL,
|
|
|
|
sizeof(pid_t) * 8, PropModeReplace,
|
|
|
|
(unsigned char *) &bpid, 1);
|
|
|
|
#endif // HAVE_GETPID
|
|
|
|
|
2006-08-06 22:33:54 +00:00
|
|
|
// check if we're the first EWMH compliant window manager on this screen
|
|
|
|
Atom xa_ret_type;
|
|
|
|
int ret_format;
|
|
|
|
unsigned long ret_nitems, ret_bytes_after;
|
|
|
|
unsigned char *ret_prop;
|
2013-01-31 08:13:45 +00:00
|
|
|
if (rootWindow().property(atom_wm_check, 0l, 1l,
|
2006-08-06 22:33:54 +00:00
|
|
|
False, XA_WINDOW, &xa_ret_type, &ret_format, &ret_nitems,
|
2011-07-02 18:13:19 +00:00
|
|
|
&ret_bytes_after, &ret_prop) ) {
|
2006-08-06 22:33:54 +00:00
|
|
|
m_restart = (ret_prop != NULL);
|
|
|
|
XFree(ret_prop);
|
|
|
|
}
|
|
|
|
|
2008-01-12 06:36:38 +00:00
|
|
|
|
2012-12-12 09:18:20 +00:00
|
|
|
// setup RANDR for this screens root window
|
2013-02-13 21:33:09 +00:00
|
|
|
#if defined(HAVE_RANDR)
|
2012-12-12 09:18:20 +00:00
|
|
|
int randr_mask = RRScreenChangeNotifyMask;
|
2013-02-13 21:33:09 +00:00
|
|
|
# ifdef RRCrtcChangeNotifyMask
|
2012-12-12 09:18:20 +00:00
|
|
|
randr_mask |= RRCrtcChangeNotifyMask;
|
2013-02-13 21:33:09 +00:00
|
|
|
# endif
|
|
|
|
# ifdef RROutputChangeNotifyMask
|
2012-12-12 09:18:20 +00:00
|
|
|
randr_mask |= RROutputChangeNotifyMask;
|
2013-02-13 21:33:09 +00:00
|
|
|
# endif
|
|
|
|
# ifdef RROutputPropertyNotifyMask
|
2012-12-12 09:18:20 +00:00
|
|
|
randr_mask |= RROutputPropertyNotifyMask;
|
2013-02-13 21:33:09 +00:00
|
|
|
# endif
|
2012-12-12 09:18:20 +00:00
|
|
|
XRRSelectInput(disp, rootWindow().window(), randr_mask);
|
2008-01-12 06:36:38 +00:00
|
|
|
#endif // HAVE_RANDR
|
|
|
|
|
2012-12-12 09:18:20 +00:00
|
|
|
|
2004-06-07 11:46:05 +00:00
|
|
|
_FB_USES_NLS;
|
2006-10-27 06:57:43 +00:00
|
|
|
|
2008-04-25 13:01:43 +00:00
|
|
|
#ifdef DEBUG
|
2006-06-21 14:41:16 +00:00
|
|
|
fprintf(stderr, _FB_CONSOLETEXT(Screen, ManagingScreen,
|
2004-06-07 11:46:05 +00:00
|
|
|
"BScreen::BScreen: managing screen %d "
|
2006-10-27 06:57:43 +00:00
|
|
|
"using visual 0x%lx, depth %d\n",
|
2006-05-20 15:08:14 +00:00
|
|
|
"informational message saying screen number (%d), visual (%lx), and colour depth (%d)").c_str(),
|
2003-05-15 12:00:46 +00:00
|
|
|
screenNumber(), XVisualIDFromVisual(rootWindow().visual()),
|
2003-05-10 22:59:32 +00:00
|
|
|
rootWindow().depth());
|
2008-04-25 13:01:43 +00:00
|
|
|
#endif // DEBUG
|
2002-12-01 13:42:15 +00:00
|
|
|
|
2007-03-04 17:47:37 +00:00
|
|
|
FbTk::EventManager *evm = FbTk::EventManager::instance();
|
|
|
|
evm->add(*this, rootWindow());
|
2013-01-31 08:13:45 +00:00
|
|
|
Keys *keys = fluxbox->keys();
|
2007-10-13 21:51:37 +00:00
|
|
|
if (keys)
|
2007-11-20 19:01:45 +00:00
|
|
|
keys->registerWindow(rootWindow().window(), *this,
|
2007-10-13 21:51:37 +00:00
|
|
|
Keys::GLOBAL|Keys::ON_DESKTOP);
|
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
|
2008-06-26 19:41:43 +00:00
|
|
|
m_image_control.reset(new FbTk::ImageControl(scrn,
|
2005-11-22 21:59:48 +00:00
|
|
|
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
|
|
|
|
2007-03-10 18:06:09 +00:00
|
|
|
m_root_theme.reset(new RootTheme(imageControl()));
|
2007-03-06 19:40:38 +00:00
|
|
|
m_root_theme->reconfigTheme();
|
2005-11-22 21:59:48 +00:00
|
|
|
|
2008-01-07 20:08:56 +00:00
|
|
|
focusedWinFrameTheme()->setAlpha(*resource.focused_alpha);
|
|
|
|
unfocusedWinFrameTheme()->setAlpha(*resource.unfocused_alpha);
|
2003-07-19 03:59:56 +00:00
|
|
|
m_menutheme->setAlpha(*resource.menu_alpha);
|
2010-09-09 13:31:54 +00:00
|
|
|
|
|
|
|
clampMenuDelay(*resource.menu_delay);
|
2003-12-18 15:27:21 +00:00
|
|
|
|
2008-10-13 04:55:03 +00:00
|
|
|
m_menutheme->setDelay(*resource.menu_delay);
|
2003-04-25 11:05:11 +00:00
|
|
|
|
2011-04-29 08:52:28 +00:00
|
|
|
m_tracker.join(focusedWinFrameTheme()->reconfigSig(),
|
|
|
|
FbTk::MemFun(*this, &BScreen::focusedWinFrameThemeReconfigured));
|
2003-08-25 13:15:53 +00:00
|
|
|
|
2004-09-16 10:10:37 +00:00
|
|
|
|
|
|
|
renderGeomWindow();
|
2004-01-16 11:47:07 +00:00
|
|
|
renderPosWindow();
|
2008-05-09 17:39:02 +00:00
|
|
|
m_tooltip_window->setDelay(*resource.tooltip_delay);
|
2004-01-16 11:47:07 +00:00
|
|
|
|
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();
|
2006-10-27 06:57:43 +00:00
|
|
|
|
2015-01-16 07:39:05 +00:00
|
|
|
m_windowmenu.reset(MenuCreator::createMenu("", *this));
|
2008-05-12 00:22:40 +00:00
|
|
|
m_windowmenu->setInternalMenu();
|
|
|
|
m_windowmenu->setReloadHelper(new FbTk::AutoReloadHelper());
|
|
|
|
m_windowmenu->reloadHelper()->setReloadCmd(FbTk::RefCount<FbTk::Command<void> >(new FbTk::SimpleCommand<BScreen>(*this, &BScreen::rereadWindowMenu)));
|
|
|
|
|
2015-01-16 07:39:05 +00:00
|
|
|
m_rootmenu.reset(MenuCreator::createMenu("", *this));
|
2008-05-12 00:22:40 +00:00
|
|
|
m_rootmenu->setReloadHelper(new FbTk::AutoReloadHelper());
|
|
|
|
m_rootmenu->reloadHelper()->setReloadCmd(FbTk::RefCount<FbTk::Command<void> >(new FbTk::SimpleCommand<BScreen>(*this, &BScreen::rereadMenu)));
|
|
|
|
|
2015-01-16 07:39:05 +00:00
|
|
|
m_configmenu.reset(MenuCreator::createMenu(_FB_XTEXT(Menu, Configuration,
|
|
|
|
"Configuration", "Title of configuration menu"), *this));
|
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
|
|
|
|
2007-01-14 19:05:34 +00:00
|
|
|
// check which desktop we should start on
|
|
|
|
unsigned int first_desktop = 0;
|
|
|
|
if (m_restart) {
|
Can check CARDINAL properties in CLIENT PATTERNS
Introduces a new member function, FbWindow::cardinalProperty()
This change also changes other code that previously used
FbWindow::property() to do the same thing as the new function; this
reduces code duplication.
There are still some bits of code (Ewmh.cc, extractNetWmIcon()) that use
FbWindow::property() to retrieve XA_CARDINAL values, but as the new
method is designed for getting a _single_ property, and that code uses
FbWindow::property() to retrieve the number of values present, and then
grab all of them; it's a different use case. I opted to not try to make
cardinalProperty() into some monolithic all-purpose cardinal method;
FbWindow::property() works just fine for that.
This change also adds an optional (default=NULL) boolean to
FbWindow::textProperty and friends that allows the caller to determine
whether or not a value was actually retrieved. This was necessary for
integrating FbWindow::cardinalProperty with the codebase, and it seemed
to fit with FbWindow::textProperty as well. Prior to this change, if
you got a return value of "", you wouldn't know if you successfully
retrieved the value which happened to be blank, or if you failed to
retrieve the value. Now, you can pass the address of a boolean if you
so choose in order to differentiate these situations; the same applies
to the new FbWindow::cardinalProperty().
2011-05-08 02:38:13 +00:00
|
|
|
bool exists;
|
2013-01-31 08:13:45 +00:00
|
|
|
unsigned int ret=static_cast<unsigned int>(rootWindow().cardinalProperty(atom_net_desktop, &exists));
|
Can check CARDINAL properties in CLIENT PATTERNS
Introduces a new member function, FbWindow::cardinalProperty()
This change also changes other code that previously used
FbWindow::property() to do the same thing as the new function; this
reduces code duplication.
There are still some bits of code (Ewmh.cc, extractNetWmIcon()) that use
FbWindow::property() to retrieve XA_CARDINAL values, but as the new
method is designed for getting a _single_ property, and that code uses
FbWindow::property() to retrieve the number of values present, and then
grab all of them; it's a different use case. I opted to not try to make
cardinalProperty() into some monolithic all-purpose cardinal method;
FbWindow::property() works just fine for that.
This change also adds an optional (default=NULL) boolean to
FbWindow::textProperty and friends that allows the caller to determine
whether or not a value was actually retrieved. This was necessary for
integrating FbWindow::cardinalProperty with the codebase, and it seemed
to fit with FbWindow::textProperty as well. Prior to this change, if
you got a return value of "", you wouldn't know if you successfully
retrieved the value which happened to be blank, or if you failed to
retrieve the value. Now, you can pass the address of a boolean if you
so choose in order to differentiate these situations; the same applies
to the new FbWindow::cardinalProperty().
2011-05-08 02:38:13 +00:00
|
|
|
if (exists) {
|
|
|
|
if (ret < static_cast<unsigned int>(nr_ws))
|
|
|
|
first_desktop = ret;
|
2007-01-14 19:05:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
changeWorkspaceID(first_desktop);
|
2003-12-31 00:38:40 +00:00
|
|
|
|
2012-12-05 14:43:33 +00:00
|
|
|
#ifdef USE_SLIT
|
2011-03-23 11:02:15 +00:00
|
|
|
m_slit.reset(new Slit(*this, *layerManager().getLayer(ResourceLayer::DESKTOP),
|
2004-09-09 14:29:10 +00:00
|
|
|
fluxbox->getSlitlistFilename().c_str()));
|
2012-12-05 14:43:33 +00:00
|
|
|
#endif // USE_SLIT
|
2004-06-07 21:22:42 +00:00
|
|
|
|
2004-04-19 22:44:42 +00:00
|
|
|
rm.unlock();
|
2006-10-27 06:57:43 +00:00
|
|
|
|
2004-04-19 22:44:42 +00:00
|
|
|
XFlush(disp);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
BScreen::~BScreen() {
|
2006-10-27 06:57:43 +00:00
|
|
|
|
2004-04-19 22:44:42 +00:00
|
|
|
if (! managed)
|
|
|
|
return;
|
2011-03-19 18:19:26 +00:00
|
|
|
|
|
|
|
m_configmenu.reset(0);
|
|
|
|
|
2008-01-12 06:36:38 +00:00
|
|
|
m_toolbar.reset(0);
|
|
|
|
|
2007-03-04 17:47:37 +00:00
|
|
|
FbTk::EventManager *evm = FbTk::EventManager::instance();
|
|
|
|
evm->remove(rootWindow());
|
2015-01-15 17:49:35 +00:00
|
|
|
|
2007-10-13 21:51:37 +00:00
|
|
|
Keys *keys = Fluxbox::instance()->keys();
|
|
|
|
if (keys)
|
|
|
|
keys->unregisterWindow(rootWindow().window());
|
2007-03-04 17:47:37 +00:00
|
|
|
|
2004-09-06 13:17:56 +00:00
|
|
|
if (m_rootmenu.get() != 0)
|
|
|
|
m_rootmenu->removeAll();
|
2006-10-27 06:57:43 +00:00
|
|
|
|
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
|
|
|
|
2008-02-05 17:31:15 +00:00
|
|
|
if (m_extramenus.size()) {
|
|
|
|
// check whether extramenus are included in windowmenu
|
|
|
|
// if not, we clean them ourselves
|
|
|
|
bool extramenus_in_windowmenu = false;
|
|
|
|
for (size_t i = 0, n = m_windowmenu->numberOfItems(); i < n; i++)
|
|
|
|
if (m_windowmenu->find(i)->submenu() == m_extramenus.begin()->second) {
|
|
|
|
extramenus_in_windowmenu = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
ExtraMenus::iterator mit = m_extramenus.begin();
|
|
|
|
ExtraMenus::iterator mit_end = m_extramenus.end();
|
|
|
|
for (; mit != mit_end; ++mit) {
|
|
|
|
// we set them to NOT internal so that they will be deleted when the
|
|
|
|
// menu is cleaned up. We can't delete them here because they are
|
|
|
|
// still in the menu
|
|
|
|
// (They need to be internal for most of the time so that if we
|
|
|
|
// rebuild the menu, then they won't be removed.
|
|
|
|
if (! extramenus_in_windowmenu) {
|
|
|
|
// not attached to our windowmenu
|
|
|
|
// so we clean it up
|
|
|
|
delete mit->second;
|
|
|
|
} else {
|
|
|
|
// let the parent clean it up
|
|
|
|
mit->second->setInternalMenu(false);
|
|
|
|
}
|
2005-06-23 03:07:25 +00:00
|
|
|
}
|
|
|
|
}
|
2006-10-27 06:57:43 +00:00
|
|
|
|
2004-04-19 22:44:42 +00:00
|
|
|
removeWorkspaceNames();
|
2007-12-28 06:22:38 +00:00
|
|
|
using namespace FbTk::STLUtil;
|
2006-05-13 15:35:47 +00:00
|
|
|
destroyAndClear(m_workspaces_list);
|
|
|
|
destroyAndClear(m_managed_resources);
|
2004-04-19 22:44:42 +00:00
|
|
|
|
2006-10-27 06:57:43 +00:00
|
|
|
//why not destroyAndClear(m_icon_list); ?
|
2004-11-20 18:12:51 +00:00
|
|
|
//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();
|
|
|
|
}
|
2006-10-27 06:57:43 +00:00
|
|
|
|
2015-01-16 07:44:49 +00:00
|
|
|
if (hasXinerama()) {
|
|
|
|
m_xinerama.heads.clear();
|
2004-04-19 22:44:42 +00:00
|
|
|
}
|
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);
|
|
|
|
|
2011-03-19 18:19:26 +00:00
|
|
|
delete m_rootmenu.release();
|
|
|
|
delete m_workspacemenu.release();
|
|
|
|
delete m_windowmenu.release();
|
2015-01-15 17:49:35 +00:00
|
|
|
|
2004-09-11 13:33:07 +00:00
|
|
|
// TODO fluxgen: check if this is the right place
|
2008-01-28 09:46:05 +00:00
|
|
|
for (size_t i = 0; i < m_head_areas.size(); i++)
|
2007-07-11 11:54:53 +00:00
|
|
|
delete m_head_areas[i];
|
2006-02-19 11:11:22 +00:00
|
|
|
|
2006-02-19 08:11:10 +00:00
|
|
|
delete m_focus_control;
|
2006-02-19 11:11:22 +00:00
|
|
|
delete m_placement_strategy;
|
2004-04-19 22:44:42 +00:00
|
|
|
}
|
|
|
|
|
2006-08-06 22:33:54 +00:00
|
|
|
bool BScreen::isRestart() {
|
|
|
|
return Fluxbox::instance()->isStartup() && m_restart;
|
|
|
|
}
|
|
|
|
|
2004-04-19 22:44:42 +00:00
|
|
|
void BScreen::initWindows() {
|
2008-01-15 09:56:25 +00:00
|
|
|
|
|
|
|
#ifdef USE_TOOLBAR
|
|
|
|
m_toolbar.reset(new Toolbar(*this,
|
2011-03-23 11:02:15 +00:00
|
|
|
*layerManager().getLayer(::ResourceLayer::NORMAL)));
|
2008-01-15 09:56:25 +00:00
|
|
|
#endif // USE_TOOLBAR
|
|
|
|
|
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
|
|
|
|
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) {
|
2010-03-17 15:35:07 +00:00
|
|
|
|
|
|
|
fbdbg<<"BScreen::initWindows(): children[j] = 0x"<<hex<<children[j]<<dec<<endl;
|
|
|
|
fbdbg<<"BScreen::initWindows(): = icon_window"<<endl;
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
2006-02-20 21:04:35 +00:00
|
|
|
Fluxbox *fluxbox = Fluxbox::instance();
|
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
// manage shown windows
|
2004-11-22 19:40:34 +00:00
|
|
|
Window transient_for = 0;
|
2006-07-27 00:04:11 +00:00
|
|
|
bool safety_flag = false;
|
|
|
|
unsigned int num_transients = 0;
|
|
|
|
for (unsigned int i = 0; i <= nchild; ++i) {
|
|
|
|
if (i == nchild) {
|
|
|
|
if (num_transients) {
|
2006-07-27 07:00:30 +00:00
|
|
|
if (num_transients == nchild)
|
|
|
|
safety_flag = true;
|
2006-07-27 00:04:11 +00:00
|
|
|
nchild = num_transients;
|
|
|
|
i = num_transients = 0;
|
|
|
|
} else
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2004-07-14 18:28:05 +00:00
|
|
|
if (children[i] == None)
|
|
|
|
continue;
|
|
|
|
else if (!fluxbox->validateWindow(children[i])) {
|
2010-03-17 15:35:07 +00:00
|
|
|
|
|
|
|
fbdbg<<"BScreen::initWindows(): not valid window = "<<hex<<children[i]<<dec<<endl;
|
|
|
|
|
2004-07-14 18:28:05 +00:00
|
|
|
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...
|
2006-07-27 00:04:11 +00:00
|
|
|
// postpone creation of this window until after all others
|
2004-07-14 18:28:05 +00:00
|
|
|
if (XGetTransientForHint(disp, children[i], &transient_for) &&
|
2006-07-27 00:04:11 +00:00
|
|
|
fluxbox->searchWindow(transient_for) == 0 && !safety_flag) {
|
|
|
|
// add this window back to the beginning of the list of children
|
|
|
|
children[num_transients] = children[i];
|
|
|
|
num_transients++;
|
2004-11-22 19:40:34 +00:00
|
|
|
|
2010-03-17 15:35:07 +00:00
|
|
|
fbdbg<<"BScreen::initWindows(): postpone creation of 0x"<<hex<<children[i]<<dec<<endl;
|
|
|
|
fbdbg<<"BScreen::initWindows(): transient_for = 0x"<<hex<<transient_for<<dec<<endl;
|
|
|
|
|
2006-07-27 00:04:11 +00:00
|
|
|
continue;
|
2004-07-14 18:28:05 +00:00
|
|
|
}
|
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
|
|
|
|
2007-04-01 21:42:01 +00:00
|
|
|
if (attrib.map_state != IsUnmapped)
|
|
|
|
createWindow(children[i]);
|
2003-01-05 22:26:56 +00:00
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
|
|
XFree(children);
|
2003-08-11 16:27:23 +00:00
|
|
|
|
2008-01-12 06:36:38 +00:00
|
|
|
// now, show slit and toolbar
|
2012-12-05 14:43:33 +00:00
|
|
|
#ifdef USE_SLIT
|
2008-01-12 06:36:38 +00:00
|
|
|
if (slit())
|
|
|
|
slit()->show();
|
2012-12-05 14:43:33 +00:00
|
|
|
#endif // USE_SLIT
|
2008-01-12 06:36:38 +00:00
|
|
|
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
|
2006-10-27 06:57:43 +00:00
|
|
|
unsigned int BScreen::currentWorkspaceID() const {
|
|
|
|
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 {
|
2007-07-11 11:54:53 +00:00
|
|
|
if (head > numHeads()) {
|
|
|
|
/* May this ever happen? */
|
|
|
|
static Strut whole(-1 /* should never be used */, 0, width(), 0, height());
|
|
|
|
return &whole;
|
|
|
|
}
|
|
|
|
return m_head_areas[head ? head-1 : 0]->availableWorkspaceArea();
|
2004-09-11 13:33:07 +00:00
|
|
|
}
|
|
|
|
|
2003-05-20 11:03:11 +00:00
|
|
|
unsigned int BScreen::maxLeft(int head) const {
|
2006-10-27 06:57:43 +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())
|
2006-10-27 06:57:43 +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())
|
2006-10-27 06:57:43 +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
|
|
|
}
|
|
|
|
|
2011-04-29 08:52:28 +00:00
|
|
|
void BScreen::focusedWinFrameThemeReconfigured() {
|
2003-08-25 13:15:53 +00:00
|
|
|
renderGeomWindow();
|
2004-01-16 11:47:07 +00:00
|
|
|
renderPosWindow();
|
2006-06-26 11:45:14 +00:00
|
|
|
|
|
|
|
Fluxbox *fluxbox = Fluxbox::instance();
|
2007-12-21 07:35:36 +00:00
|
|
|
const std::list<Focusable *> winlist =
|
|
|
|
focusControl().focusedOrderWinList().clientList();
|
|
|
|
std::list<Focusable *>::const_iterator it = winlist.begin(),
|
|
|
|
it_end = winlist.end();
|
2006-06-26 11:45:14 +00:00
|
|
|
for (; it != it_end; ++it)
|
2007-12-21 07:35:36 +00:00
|
|
|
fluxbox->updateFrameExtents(*(*it)->fbwindow());
|
2006-10-27 06:57:43 +00:00
|
|
|
|
2003-08-25 13:15:53 +00:00
|
|
|
}
|
|
|
|
|
2007-07-03 18:50:53 +00:00
|
|
|
void BScreen::propertyNotify(Atom atom) {
|
2013-01-31 08:13:45 +00:00
|
|
|
|
|
|
|
if (allowRemoteActions() && atom == atom_fbcmd) {
|
2007-07-03 18:50:53 +00:00
|
|
|
Atom xa_ret_type;
|
|
|
|
int ret_format;
|
|
|
|
unsigned long ret_nitems, ret_bytes_after;
|
|
|
|
char *str;
|
2013-01-31 08:13:45 +00:00
|
|
|
if (rootWindow().property(atom_fbcmd, 0l, 64l,
|
2007-07-03 18:50:53 +00:00
|
|
|
True, XA_STRING, &xa_ret_type, &ret_format, &ret_nitems,
|
|
|
|
&ret_bytes_after, (unsigned char **)&str) && str) {
|
|
|
|
|
|
|
|
if (ret_bytes_after) {
|
|
|
|
XFree(str);
|
|
|
|
long len = 64 + (ret_bytes_after + 3)/4;
|
2013-01-31 08:13:45 +00:00
|
|
|
rootWindow().property(atom_fbcmd, 0l, len,
|
2007-07-03 18:50:53 +00:00
|
|
|
True, XA_STRING, &xa_ret_type, &ret_format, &ret_nitems,
|
|
|
|
&ret_bytes_after, (unsigned char **)&str);
|
|
|
|
}
|
|
|
|
|
2008-10-04 06:09:11 +00:00
|
|
|
static std::auto_ptr<FbTk::Command<void> > cmd(0);
|
|
|
|
cmd.reset(FbTk::CommandParser<void>::instance().parse(str, false));
|
2013-01-31 08:13:45 +00:00
|
|
|
if (cmd.get()) {
|
2007-07-03 18:50:53 +00:00
|
|
|
cmd->execute();
|
2013-01-31 08:13:45 +00:00
|
|
|
}
|
2007-07-03 18:50:53 +00:00
|
|
|
XFree(str);
|
|
|
|
|
|
|
|
}
|
|
|
|
// TODO: this doesn't belong in FbPixmap
|
|
|
|
} else if (FbTk::FbPixmap::rootwinPropertyNotify(screenNumber(), atom))
|
2008-09-21 14:12:36 +00:00
|
|
|
m_bg_change_sig.emit(*this);
|
2007-07-03 18:50:53 +00:00
|
|
|
}
|
|
|
|
|
2007-03-04 17:47:37 +00:00
|
|
|
void BScreen::keyPressEvent(XKeyEvent &ke) {
|
2013-08-02 06:46:45 +00:00
|
|
|
Fluxbox::instance()->keys()->doAction(ke.type, ke.state, ke.keycode,
|
|
|
|
Keys::GLOBAL|Keys::ON_DESKTOP);
|
2007-03-04 17:47:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void BScreen::keyReleaseEvent(XKeyEvent &ke) {
|
2008-09-28 08:26:21 +00:00
|
|
|
if (m_cycling) {
|
|
|
|
unsigned int state = FbTk::KeyUtil::instance().cleanMods(ke.state);
|
|
|
|
state &= ~FbTk::KeyUtil::instance().keycodeToModmask(ke.keycode);
|
|
|
|
|
|
|
|
if (state) // still cycling
|
|
|
|
return;
|
2007-03-04 17:47:37 +00:00
|
|
|
|
2008-09-28 08:26:21 +00:00
|
|
|
m_cycling = false;
|
|
|
|
focusControl().stopCyclingFocus();
|
|
|
|
}
|
2008-10-04 05:59:14 +00:00
|
|
|
if (!Fluxbox::instance()->keys()->inKeychain())
|
|
|
|
FbTk::EventManager::instance()->ungrabKeyboard();
|
2007-03-04 17:47:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void BScreen::buttonPressEvent(XButtonEvent &be) {
|
|
|
|
if (be.button == 1 && !isRootColormapInstalled())
|
|
|
|
imageControl().installRootColormap();
|
|
|
|
|
|
|
|
Keys *keys = Fluxbox::instance()->keys();
|
2007-12-09 20:47:41 +00:00
|
|
|
keys->doAction(be.type, be.state, be.button, Keys::GLOBAL|Keys::ON_DESKTOP,
|
2008-02-11 18:17:45 +00:00
|
|
|
0, be.time);
|
2007-03-04 17:47:37 +00:00
|
|
|
}
|
|
|
|
|
2007-10-13 21:51:37 +00:00
|
|
|
void BScreen::cycleFocus(int options, const ClientPattern *pat, bool reverse) {
|
2007-03-04 17:47:37 +00:00
|
|
|
// get modifiers from event that causes this for focus order cycling
|
|
|
|
XEvent ev = Fluxbox::instance()->lastEvent();
|
|
|
|
unsigned int mods = 0;
|
|
|
|
if (ev.type == KeyPress)
|
|
|
|
mods = FbTk::KeyUtil::instance().cleanMods(ev.xkey.state);
|
|
|
|
else if (ev.type == ButtonPress)
|
|
|
|
mods = FbTk::KeyUtil::instance().cleanMods(ev.xbutton.state);
|
|
|
|
|
2007-10-24 17:09:26 +00:00
|
|
|
if (!m_cycling && mods) {
|
2007-03-04 17:47:37 +00:00
|
|
|
m_cycling = true;
|
2008-09-28 08:26:21 +00:00
|
|
|
FbTk::EventManager::instance()->grabKeyboard(rootWindow().window());
|
2007-03-04 17:47:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (mods == 0) // can't stacked cycle unless there is a mod to grab
|
2007-11-12 21:59:43 +00:00
|
|
|
options |= FocusableList::STATIC_ORDER;
|
2007-10-13 21:51:37 +00:00
|
|
|
|
2007-11-12 21:59:43 +00:00
|
|
|
const FocusableList *win_list =
|
|
|
|
FocusableList::getListFromOptions(*this, options);
|
2007-10-13 21:51:37 +00:00
|
|
|
focusControl().cycleFocus(*win_list, pat, reverse);
|
2007-03-04 17:47:37 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2006-05-20 15:08:14 +00:00
|
|
|
void BScreen::addExtraWindowMenu(const FbTk::FbString &label, FbTk::Menu *menu) {
|
2005-06-23 03:07:25 +00:00
|
|
|
menu->setInternalMenu();
|
|
|
|
menu->disableTitle();
|
2006-10-27 06:57:43 +00:00
|
|
|
m_extramenus.push_back(make_pair(label, menu));
|
2008-05-12 00:22:40 +00:00
|
|
|
rereadWindowMenu();
|
2005-06-23 03:07:25 +00:00
|
|
|
}
|
|
|
|
|
2002-08-02 12:58:37 +00:00
|
|
|
void BScreen::reconfigure() {
|
2005-10-21 19:23:57 +00:00
|
|
|
Fluxbox *fluxbox = Fluxbox::instance();
|
2005-04-27 09:52:30 +00:00
|
|
|
|
2008-01-07 20:08:56 +00:00
|
|
|
focusedWinFrameTheme()->setAlpha(*resource.focused_alpha);
|
|
|
|
unfocusedWinFrameTheme()->setAlpha(*resource.unfocused_alpha);
|
2003-07-19 03:59:56 +00:00
|
|
|
m_menutheme->setAlpha(*resource.menu_alpha);
|
2003-12-18 15:27:21 +00:00
|
|
|
|
2010-09-09 13:31:54 +00:00
|
|
|
clampMenuDelay(*resource.menu_delay);
|
2003-12-18 15:27:21 +00:00
|
|
|
|
2008-10-13 04:55:03 +00:00
|
|
|
m_menutheme->setDelay(*resource.menu_delay);
|
2003-12-12 18:18:49 +00:00
|
|
|
|
2005-04-27 09:52:30 +00:00
|
|
|
// realize the number of workspaces from the init-file
|
2006-01-16 18:46:39 +00:00
|
|
|
const unsigned int nr_ws = *resource.workspaces;
|
2005-04-27 09:52:30 +00:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-05-12 00:22:40 +00:00
|
|
|
// update menu filenames
|
|
|
|
m_rootmenu->reloadHelper()->setMainFile(fluxbox->getMenuFilename());
|
|
|
|
m_windowmenu->reloadHelper()->setMainFile(windowMenuFilename());
|
2003-05-13 00:23:05 +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));
|
2006-10-27 06:57:43 +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));
|
2006-10-27 06:57:43 +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
|
2011-05-07 20:32:48 +00:00
|
|
|
m_reconfigure_sig.emit(*this);
|
2004-03-23 09:21:29 +00:00
|
|
|
|
2005-10-21 19:23:57 +00:00
|
|
|
// Reload style
|
|
|
|
FbTk::ThemeManager::instance().load(fluxbox->getStyleFilename(),
|
2005-11-16 22:08:05 +00:00
|
|
|
fluxbox->getStyleOverlayFilename(),
|
2005-10-21 19:23:57 +00:00
|
|
|
m_root_theme->screenNum());
|
2006-03-22 12:23:17 +00:00
|
|
|
|
|
|
|
reconfigureTabs();
|
|
|
|
}
|
|
|
|
|
|
|
|
void BScreen::reconfigureTabs() {
|
2007-12-21 07:35:36 +00:00
|
|
|
const std::list<Focusable *> winlist =
|
|
|
|
focusControl().focusedOrderWinList().clientList();
|
|
|
|
std::list<Focusable *>::const_iterator it = winlist.begin(),
|
|
|
|
it_end = winlist.end();
|
|
|
|
for (; it != it_end; ++it)
|
|
|
|
(*it)->fbwindow()->applyDecorations();
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
|
2007-07-07 01:56:46 +00:00
|
|
|
void BScreen::updateWorkspaceName(unsigned int w) {
|
|
|
|
Workspace *space = getWorkspace(w);
|
|
|
|
if (space) {
|
|
|
|
m_workspace_names[w] = space->name();
|
2008-09-21 13:25:47 +00:00
|
|
|
m_workspacenames_sig.emit(*this);
|
2007-07-07 01:56:46 +00:00
|
|
|
Fluxbox::instance()->save_rc();
|
|
|
|
}
|
|
|
|
}
|
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
|
|
|
}
|
|
|
|
|
|
|
|
void BScreen::addIcon(FluxboxWindow *w) {
|
2006-10-27 06:57:43 +00:00
|
|
|
if (w == 0)
|
2004-05-02 21:12:22 +00:00
|
|
|
return;
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2004-09-05 01:11:41 +00:00
|
|
|
// make sure we have a unique list
|
2005-07-04 18:18:32 +00:00
|
|
|
if (find(iconList().begin(), iconList().end(), w) != iconList().end())
|
2004-09-05 01:11:41 +00:00
|
|
|
return;
|
|
|
|
|
2008-09-22 05:44:40 +00:00
|
|
|
iconList().push_back(w);
|
2004-09-05 01:11:41 +00:00
|
|
|
|
2004-05-02 21:12:22 +00:00
|
|
|
// notify listeners
|
2008-09-22 05:44:40 +00:00
|
|
|
iconListSig().emit(*this);
|
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
|
|
|
|
2005-07-04 18:18:32 +00:00
|
|
|
Icons::iterator erase_it = remove_if(iconList().begin(),
|
|
|
|
iconList().end(),
|
2003-04-14 15:01:55 +00:00
|
|
|
bind2nd(equal_to<FluxboxWindow *>(), w));
|
2006-10-27 06:57:43 +00:00
|
|
|
// no need to send iconlist signal if we didn't
|
2004-09-05 01:11:41 +00:00
|
|
|
// change the iconlist
|
|
|
|
if (erase_it != m_icon_list.end()) {
|
2005-07-04 18:18:32 +00:00
|
|
|
iconList().erase(erase_it);
|
2008-09-22 05:44:40 +00:00
|
|
|
iconListSig().emit(*this);
|
2004-09-05 01:11:41 +00:00
|
|
|
}
|
2003-07-28 18:28:03 +00:00
|
|
|
}
|
|
|
|
|
2002-09-08 19:45:59 +00:00
|
|
|
void BScreen::removeWindow(FluxboxWindow *win) {
|
2010-03-17 15:35:07 +00:00
|
|
|
|
|
|
|
fbdbg<<"BScreen::removeWindow("<<win<<")"<<endl;
|
|
|
|
|
2006-10-27 06:57:43 +00:00
|
|
|
// extra precaution, if for some reason, the
|
2004-09-05 01:11:41 +00:00
|
|
|
// 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
|
|
|
|
2006-02-18 11:39:38 +00:00
|
|
|
focusControl().removeClient(client);
|
2003-09-24 14:26:01 +00:00
|
|
|
|
2007-10-13 21:51:37 +00:00
|
|
|
if (client.fbwindow() && client.fbwindow()->isIconic())
|
2008-09-21 18:45:01 +00:00
|
|
|
iconListSig().emit(*this);
|
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-08-02 12:58:37 +00:00
|
|
|
int BScreen::addWorkspace() {
|
2005-04-27 09:52:30 +00:00
|
|
|
|
2008-09-08 22:50:25 +00:00
|
|
|
bool save_name = getNameOfWorkspace(m_workspaces_list.size()) == "";
|
2007-10-13 21:51:37 +00:00
|
|
|
Workspace *wkspc = new Workspace(*this,
|
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);
|
2006-10-27 06:57:43 +00:00
|
|
|
|
2008-09-08 22:50:25 +00:00
|
|
|
if (save_name) {
|
2010-09-08 18:17:21 +00:00
|
|
|
addWorkspaceName(wkspc->name().c_str());
|
2008-09-21 13:25:47 +00:00
|
|
|
m_workspacenames_sig.emit(*this);
|
2008-09-08 22:50:25 +00:00
|
|
|
}
|
2005-04-27 09:52:30 +00:00
|
|
|
|
2003-05-19 22:45:51 +00:00
|
|
|
saveWorkspaces(m_workspaces_list.size());
|
2008-09-18 20:27:16 +00:00
|
|
|
workspaceCountSig().emit( *this );
|
2006-10-27 06:57:43 +00:00
|
|
|
|
2003-05-19 22:45:51 +00:00
|
|
|
return m_workspaces_list.size();
|
2006-10-27 06:57:43 +00:00
|
|
|
|
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
|
|
|
|
2006-07-22 07:15:24 +00:00
|
|
|
wkspc->removeAll(wkspc->workspaceID()-1);
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2006-07-23 02:20:42 +00:00
|
|
|
Icons::iterator it = iconList().begin();
|
|
|
|
const Icons::iterator it_end = iconList().end();
|
|
|
|
for (; it != it_end; ++it) {
|
|
|
|
if ((*it)->workspaceNumber() == wkspc->workspaceID())
|
|
|
|
(*it)->setWorkspace(wkspc->workspaceID()-1);
|
|
|
|
}
|
2008-09-21 17:32:40 +00:00
|
|
|
m_clientlist_sig.emit(*this);
|
2006-07-23 02:20:42 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
//remove last workspace
|
2006-10-27 06:57:43 +00:00
|
|
|
m_workspaces_list.pop_back();
|
2004-12-30 14:33:38 +00:00
|
|
|
|
2003-05-19 22:45:51 +00:00
|
|
|
saveWorkspaces(m_workspaces_list.size());
|
2008-09-18 20:27:16 +00:00
|
|
|
workspaceCountSig().emit( *this );
|
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
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-11-12 23:16:13 +00:00
|
|
|
void BScreen::changeWorkspaceID(unsigned int id, bool revert) {
|
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
|
|
|
|
2009-03-09 18:05:41 +00:00
|
|
|
/* Ignore all EnterNotify events until the pointer actually moves */
|
|
|
|
this->focusControl().ignoreAtPointer();
|
|
|
|
|
2004-11-30 22:19:35 +00:00
|
|
|
FbTk::App::instance()->sync(false);
|
2003-10-05 02:31:23 +00:00
|
|
|
|
2008-10-09 00:15:53 +00:00
|
|
|
FluxboxWindow *focused = FocusControl::focusedFbWindow();
|
|
|
|
|
|
|
|
if (focused && focused->isMoving() && doOpaqueMove())
|
|
|
|
// don't reassociate if not opaque moving
|
|
|
|
reassociateWindow(focused, id, true);
|
|
|
|
|
2007-11-04 17:36:40 +00:00
|
|
|
// set new workspace
|
|
|
|
Workspace *old = currentWorkspace();
|
|
|
|
m_current_workspace = getWorkspace(id);
|
|
|
|
|
|
|
|
// we show new workspace first in order to appear faster
|
|
|
|
currentWorkspace()->showAll();
|
|
|
|
|
2003-05-11 11:47:19 +00:00
|
|
|
// reassociate all windows that are stuck to the new workspace
|
2007-11-08 02:06:33 +00:00
|
|
|
Workspace::Windows wins = old->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
|
|
|
|
2007-03-17 08:15:04 +00:00
|
|
|
// change workspace ID of stuck iconified windows, too
|
|
|
|
Icons::iterator icon_it = iconList().begin();
|
|
|
|
for (; icon_it != iconList().end(); ++icon_it) {
|
|
|
|
if ((*icon_it)->isStuck())
|
|
|
|
(*icon_it)->setWorkspace(id);
|
|
|
|
}
|
|
|
|
|
2008-10-09 00:15:53 +00:00
|
|
|
if (focused && focused->isMoving() && doOpaqueMove())
|
2007-10-13 21:51:37 +00:00
|
|
|
focused->focus();
|
2008-10-09 00:15:53 +00:00
|
|
|
else if (revert)
|
2007-01-26 17:18:14 +00:00
|
|
|
FocusControl::revertFocus(*this);
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2007-11-04 17:36:40 +00:00
|
|
|
old->hideAll(false);
|
|
|
|
|
2004-01-19 18:29:43 +00:00
|
|
|
FbTk::App::instance()->sync(false);
|
2003-09-14 10:13:54 +00:00
|
|
|
|
2008-09-21 11:44:48 +00:00
|
|
|
m_currentworkspace_sig.emit(*this);
|
2007-10-13 21:51:37 +00:00
|
|
|
|
2007-11-22 20:21:47 +00:00
|
|
|
// do this after atom handlers, so scripts can access new workspace number
|
|
|
|
Fluxbox::instance()->keys()->doAction(FocusIn, 0, 0, Keys::ON_DESKTOP);
|
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
|
|
|
|
2006-07-12 00:08:57 +00:00
|
|
|
if (!win)
|
|
|
|
win = FocusControl::focusedFbWindow();
|
2002-02-26 22:25:53 +00:00
|
|
|
|
2008-06-23 20:12:41 +00:00
|
|
|
if (!win || &win->screen() != this || win->isStuck())
|
2007-06-03 20:27:52 +00:00
|
|
|
return;
|
2003-12-04 00:08:55 +00:00
|
|
|
|
2007-10-13 21:51:37 +00:00
|
|
|
FbTk::App::instance()->sync(false);
|
2003-12-04 00:08:55 +00:00
|
|
|
|
2007-06-03 20:27:52 +00:00
|
|
|
windowMenu().hide();
|
|
|
|
reassociateWindow(win, id, true);
|
2003-12-18 15:27:21 +00:00
|
|
|
|
2007-06-03 20:27:52 +00:00
|
|
|
// change workspace ?
|
2007-10-13 21:51:37 +00:00
|
|
|
if (changeWS)
|
2007-11-12 23:16:13 +00:00
|
|
|
changeWorkspaceID(id, false);
|
2007-10-13 21:51:37 +00:00
|
|
|
|
|
|
|
// if the window is on current workspace, show it; else hide it.
|
|
|
|
if (id == currentWorkspace()->workspaceID() && !win->isIconic())
|
2007-11-23 00:45:56 +00:00
|
|
|
win->show();
|
2007-10-13 21:51:37 +00:00
|
|
|
else {
|
|
|
|
win->hide(true);
|
|
|
|
FocusControl::revertFocus(*this);
|
2007-06-03 20:27:52 +00:00
|
|
|
}
|
2002-10-11 10:22:06 +00:00
|
|
|
|
2007-06-03 20:27:52 +00:00
|
|
|
// send all the transients too
|
|
|
|
FluxboxWindow::ClientList::iterator client_it = win->clientList().begin();
|
|
|
|
FluxboxWindow::ClientList::iterator client_it_end = win->clientList().end();
|
|
|
|
for (; client_it != client_it_end; ++client_it) {
|
|
|
|
WinClient::TransientList::const_iterator it = (*client_it)->transientList().begin();
|
|
|
|
WinClient::TransientList::const_iterator it_end = (*client_it)->transientList().end();
|
|
|
|
for (; it != it_end; ++it) {
|
|
|
|
if ((*it)->fbwindow())
|
|
|
|
sendToWorkspace(id, (*it)->fbwindow(), false);
|
|
|
|
}
|
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
|
|
|
|
2004-04-19 22:44:42 +00:00
|
|
|
bool BScreen::isKdeDockapp(Window client) const {
|
|
|
|
//Check and see if client is KDE dock applet.
|
|
|
|
bool iskdedockapp = false;
|
|
|
|
Atom ajunk;
|
|
|
|
int ijunk;
|
2006-08-09 04:54:58 +00:00
|
|
|
unsigned long *data = 0, uljunk;
|
2004-04-19 22:44:42 +00:00
|
|
|
Display *disp = FbTk::App::instance()->display();
|
|
|
|
// Check if KDE v2.x dock applet
|
2013-01-31 08:13:45 +00:00
|
|
|
if (XGetWindowProperty(disp, client, atom_kde_systray,
|
2004-04-19 22:44:42 +00:00
|
|
|
0l, 1l, False,
|
|
|
|
XA_WINDOW, &ajunk, &ijunk, &uljunk,
|
2006-08-09 04:54:58 +00:00
|
|
|
&uljunk, (unsigned char **) &data) == Success) {
|
2006-10-27 06:57:43 +00:00
|
|
|
|
2004-04-19 22:44:42 +00:00
|
|
|
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) {
|
2003-07-28 20:11:55 +00:00
|
|
|
if (XGetWindowProperty(disp, client,
|
2013-01-31 08:13:45 +00:00
|
|
|
atom_kwm1, 0l, 1l, False,
|
|
|
|
atom_kwm1, &ajunk, &ijunk, &uljunk,
|
2006-08-09 04:54:58 +00:00
|
|
|
&uljunk, (unsigned char **) &data) == Success && data) {
|
2004-04-19 22:44:42 +00:00
|
|
|
iskdedockapp = (data && data[0] != 0);
|
2003-07-28 20:11:55 +00:00
|
|
|
XFree((void *) data);
|
|
|
|
data = 0;
|
|
|
|
}
|
2006-10-27 06:57:43 +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);
|
|
|
|
FbTk::EventHandler *evh = 0;
|
|
|
|
FbTk::EventManager *evm = FbTk::EventManager::instance();
|
2010-08-23 17:49:47 +00:00
|
|
|
|
2011-01-13 15:27:53 +00:00
|
|
|
AtomHandler* handler = 0;
|
2013-01-10 11:11:24 +00:00
|
|
|
#if USE_SYSTRAY
|
2011-01-13 15:27:53 +00:00
|
|
|
handler = Fluxbox::instance()->getAtomHandler(SystemTray::getNetSystemTrayAtom(screenNumber()));
|
|
|
|
#endif
|
2004-04-19 22:44:42 +00:00
|
|
|
if (handler == 0) {
|
2012-12-05 14:43:33 +00:00
|
|
|
#ifdef USE_SLIT
|
2007-12-25 06:36:22 +00:00
|
|
|
if (slit() != 0 && slit()->acceptKdeDockapp())
|
2004-04-19 22:44:42 +00:00
|
|
|
slit()->addClient(client);
|
|
|
|
else
|
2012-12-05 14:43:33 +00:00
|
|
|
#endif // USE_SLIT
|
2004-04-19 22:44:42 +00:00
|
|
|
return false;
|
|
|
|
} else {
|
2006-10-27 06:57:43 +00:00
|
|
|
// this handler is a special case
|
2004-05-02 21:12:22 +00:00
|
|
|
// 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);
|
|
|
|
|
2014-09-29 07:24:42 +00:00
|
|
|
if (winclient->initial_state == WithdrawnState ||
|
|
|
|
winclient->getWMClassClass() == "DockApp") {
|
2003-06-27 15:05:19 +00:00
|
|
|
delete winclient;
|
2012-12-05 14:43:33 +00:00
|
|
|
#ifdef USE_SLIT
|
2007-12-25 06:36:22 +00:00
|
|
|
if (slit() && !isKdeDockapp(client))
|
2004-04-19 22:44:42 +00:00
|
|
|
slit()->addClient(client);
|
2012-12-05 14:43:33 +00:00
|
|
|
#endif // USE_SLIT
|
2003-05-17 11:05:33 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2003-01-05 22:26:56 +00:00
|
|
|
|
2003-06-23 14:16:05 +00:00
|
|
|
// check if it should be grouped with something else
|
|
|
|
FluxboxWindow *win;
|
2006-07-20 03:25:28 +00:00
|
|
|
WinClient *other;
|
|
|
|
if ((other = findGroupLeft(*winclient)) && (win = other->fbwindow())) {
|
2003-06-23 14:16:05 +00:00
|
|
|
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);
|
2007-03-10 18:19:23 +00:00
|
|
|
if (winclient->fbwindow()) { // may have been set in an atomhandler
|
2003-07-04 01:03:41 +00:00
|
|
|
win = winclient->fbwindow();
|
2007-03-10 18:19:23 +00:00
|
|
|
Workspace *workspace = getWorkspace(win->workspaceNumber());
|
|
|
|
if (workspace)
|
|
|
|
workspace->updateClientmenu();
|
|
|
|
} else {
|
2008-08-27 22:29:33 +00:00
|
|
|
win = new FluxboxWindow(*winclient);
|
2006-10-27 06:57:43 +00:00
|
|
|
|
2003-07-04 01:03:41 +00:00
|
|
|
if (!win->isManaged()) {
|
|
|
|
delete win;
|
|
|
|
return 0;
|
2006-10-27 06:57:43 +00:00
|
|
|
}
|
2003-07-04 01:03:41 +00:00
|
|
|
}
|
|
|
|
}
|
2006-10-27 06:57:43 +00:00
|
|
|
|
2007-01-26 17:21:44 +00:00
|
|
|
// add the window to the focus list
|
2007-01-27 18:06:28 +00:00
|
|
|
// always add to front on startup to keep the focus order the same
|
2007-12-25 17:14:20 +00:00
|
|
|
if (win->isFocused() || Fluxbox::instance()->isStartup())
|
2007-01-26 17:21:44 +00:00
|
|
|
focusControl().addFocusFront(*winclient);
|
|
|
|
else
|
|
|
|
focusControl().addFocusBack(*winclient);
|
2006-07-06 04:10:34 +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.
|
2006-07-20 03:25:28 +00:00
|
|
|
if ((other = findGroupRight(*winclient)) && other->fbwindow() != win)
|
|
|
|
win->attachClient(*other);
|
2006-08-04 21:43:47 +00:00
|
|
|
else if (other) // should never happen
|
2006-07-20 03:25:28 +00:00
|
|
|
win->moveClientRightOf(*other, *winclient);
|
2003-06-23 14:16:05 +00:00
|
|
|
|
2008-09-21 17:32:40 +00:00
|
|
|
m_clientlist_sig.emit(*this);
|
2004-01-19 18:29:43 +00:00
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2008-08-27 22:29:33 +00:00
|
|
|
FluxboxWindow *win = new FluxboxWindow(client);
|
2004-04-19 22:44:42 +00:00
|
|
|
|
2003-04-14 15:01:55 +00:00
|
|
|
#ifdef SLIT
|
2014-09-29 07:24:42 +00:00
|
|
|
if (slit() != 0) {
|
|
|
|
|
|
|
|
if (win->initialState() == WithdrawnState) {
|
|
|
|
slit()->addClient(client.window());
|
|
|
|
} else if (client->getWMClassClass() == "DockApp") {
|
|
|
|
slit()->addClient(client.window());
|
|
|
|
}
|
2005-01-05 01:56:19 +00:00
|
|
|
}
|
2003-04-14 15:01:55 +00:00
|
|
|
#endif // SLIT
|
2006-10-27 06:57:43 +00:00
|
|
|
|
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
|
|
|
|
2007-01-27 18:06:28 +00:00
|
|
|
win->show();
|
|
|
|
// don't ask me why, but client doesn't seem to keep focus in new window
|
|
|
|
// and we don't seem to get a FocusIn event from setInputFocus
|
|
|
|
if ((focusControl().focusNew() || FocusControl::focusedWindow() == &client)
|
2007-10-13 21:51:37 +00:00
|
|
|
&& win->focus())
|
2006-07-09 06:51:28 +00:00
|
|
|
FocusControl::setFocusedWindow(&client);
|
2006-07-06 04:10:34 +00:00
|
|
|
|
2008-09-21 17:32:40 +00:00
|
|
|
m_clientlist_sig.emit(*this);
|
2004-01-19 18:29:43 +00:00
|
|
|
|
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) {
|
2006-10-27 06:57:43 +00:00
|
|
|
// head does not exist (if head == 1, then numHeads() == 0,
|
2004-09-11 13:33:07 +00:00
|
|
|
// 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++) {
|
2007-07-11 11:54:53 +00:00
|
|
|
next = m_head_areas[i]->requestStrut(i+1, left, right, top, bottom, next);
|
2004-09-11 13:33:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return next;
|
|
|
|
}
|
|
|
|
|
|
|
|
void BScreen::clearStrut(Strut *str) {
|
2006-10-27 06:57:43 +00:00
|
|
|
if (str->next())
|
2004-09-11 13:33:07 +00:00
|
|
|
clearStrut(str->next());
|
|
|
|
int head = str->head() ? str->head() - 1 : 0;
|
2007-07-11 11:54:53 +00:00
|
|
|
/* The number of heads may have changed, be careful. */
|
2008-05-16 00:49:19 +00:00
|
|
|
if (head < (numHeads() ? numHeads() : 1))
|
2007-07-11 11:54:53 +00:00
|
|
|
m_head_areas[head]->clearStrut(str);
|
2004-09-11 13:33:07 +00:00
|
|
|
// 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++) {
|
2007-07-11 11:54:53 +00:00
|
|
|
updated = m_head_areas[i]->updateAvailableWorkspaceArea() || updated;
|
2004-09-11 13:33:07 +00:00
|
|
|
}
|
2004-01-19 18:29:43 +00:00
|
|
|
|
2004-09-11 13:33:07 +00:00
|
|
|
if (updated)
|
2008-09-28 14:00:48 +00:00
|
|
|
m_workspace_area_sig.emit(*this);
|
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) {
|
2006-05-07 10:08:25 +00:00
|
|
|
m_workspace_names.push_back(FbTk::FbStringUtil::LocaleStrToFb(name));
|
2007-02-17 17:39:00 +00:00
|
|
|
Workspace *wkspc = getWorkspace(m_workspace_names.size()-1);
|
|
|
|
if (wkspc)
|
|
|
|
wkspc->setName(m_workspace_names.back());
|
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
|
|
|
}
|
|
|
|
|
2006-10-27 06:57:43 +00:00
|
|
|
void BScreen::reassociateWindow(FluxboxWindow *w, unsigned int wkspc_id,
|
2003-04-28 00:38:42 +00:00
|
|
|
bool ignore_sticky) {
|
2003-04-14 15:01:55 +00:00
|
|
|
if (w == 0)
|
|
|
|
return;
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2005-07-04 18:18:32 +00:00
|
|
|
if (wkspc_id >= numberOfWorkspaces())
|
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);
|
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)
|
2011-02-24 15:56:53 +00:00
|
|
|
Workspace* ws = getWorkspace(w->workspaceNumber());
|
|
|
|
if (ws)
|
|
|
|
ws->removeWindow(w, true);
|
2003-04-14 15:01:55 +00:00
|
|
|
getWorkspace(wkspc_id)->addWindow(*w);
|
2002-12-01 13:42:15 +00:00
|
|
|
}
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
|
2004-05-02 21:12:22 +00:00
|
|
|
void BScreen::initMenus() {
|
|
|
|
m_workspacemenu.reset(MenuCreator::createMenuType("workspacemenu", screenNumber()));
|
2008-05-12 00:22:40 +00:00
|
|
|
m_rootmenu->reloadHelper()->setMainFile(Fluxbox::instance()->getMenuFilename());
|
|
|
|
m_windowmenu->reloadHelper()->setMainFile(windowMenuFilename());
|
2004-05-02 21:12:22 +00:00
|
|
|
}
|
2003-04-20 12:21:35 +00:00
|
|
|
|
2005-06-23 03:07:25 +00:00
|
|
|
|
2008-05-12 00:22:40 +00:00
|
|
|
void BScreen::rereadMenu() {
|
2006-10-27 06:57:43 +00:00
|
|
|
|
2008-05-12 00:22:40 +00:00
|
|
|
m_rootmenu->removeAll();
|
2010-09-08 18:17:21 +00:00
|
|
|
m_rootmenu->setLabel(FbTk::BiDiString(""));
|
2002-12-01 13:42:15 +00:00
|
|
|
|
|
|
|
Fluxbox * const fb = Fluxbox::instance();
|
2008-05-11 17:17:21 +00:00
|
|
|
if (!fb->getMenuFilename().empty())
|
2008-05-12 00:22:40 +00:00
|
|
|
MenuCreator::createFromFile(fb->getMenuFilename(), *m_rootmenu,
|
|
|
|
m_rootmenu->reloadHelper());
|
2002-12-01 13:42:15 +00:00
|
|
|
|
2008-05-11 17:17:21 +00:00
|
|
|
if (m_rootmenu->numberOfItems() == 0) {
|
2004-06-07 11:46:05 +00:00
|
|
|
_FB_USES_NLS;
|
2008-05-11 17:17:21 +00:00
|
|
|
m_rootmenu->setLabel(_FB_XTEXT(Menu, DefaultRootMenu, "Fluxbox default menu", "Title of fallback root menu"));
|
2008-01-11 07:41:22 +00:00
|
|
|
FbTk::RefCount<FbTk::Command<void> > restart_fb(FbTk::CommandParser<void>::instance().parse("restart"));
|
|
|
|
FbTk::RefCount<FbTk::Command<void> > exit_fb(FbTk::CommandParser<void>::instance().parse("exit"));
|
|
|
|
FbTk::RefCount<FbTk::Command<void> > execute_xterm(FbTk::CommandParser<void>::instance().parse("exec xterm"));
|
2002-12-13 20:19:05 +00:00
|
|
|
m_rootmenu->setInternalMenu();
|
2015-01-15 13:24:46 +00:00
|
|
|
m_rootmenu->insertCommand("xterm", execute_xterm);
|
|
|
|
m_rootmenu->insertCommand(_FB_XTEXT(Menu, Restart, "Restart", "Restart command"),
|
2003-01-09 17:41:02 +00:00
|
|
|
restart_fb);
|
2015-01-15 13:24:46 +00:00
|
|
|
m_rootmenu->insertCommand(_FB_XTEXT(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
|
|
|
|
|
|
|
}
|
|
|
|
|
2008-06-20 03:48:26 +00:00
|
|
|
const std::string BScreen::windowMenuFilename() const {
|
|
|
|
if ((*resource.windowmenufile).empty())
|
|
|
|
return Fluxbox::instance()->getDefaultDataFilename("windowmenu");
|
|
|
|
return *resource.windowmenufile;
|
|
|
|
}
|
|
|
|
|
2008-05-12 00:22:40 +00:00
|
|
|
void BScreen::rereadWindowMenu() {
|
|
|
|
|
|
|
|
m_windowmenu->removeAll();
|
|
|
|
if (!windowMenuFilename().empty())
|
2008-06-06 13:58:20 +00:00
|
|
|
MenuCreator::createFromFile(windowMenuFilename(), *m_windowmenu,
|
|
|
|
m_windowmenu->reloadHelper());
|
2008-05-12 00:22:40 +00:00
|
|
|
|
|
|
|
}
|
2004-05-02 21:12:22 +00:00
|
|
|
|
2006-05-20 15:08:14 +00:00
|
|
|
void BScreen::addConfigMenu(const FbTk::FbString &label, FbTk::Menu &menu) {
|
2015-01-16 07:36:49 +00:00
|
|
|
|
|
|
|
FbTk::Menu* cm = m_configmenu.get();
|
|
|
|
if (cm) {
|
|
|
|
int pos = cm->findSubmenuIndex(&menu);
|
|
|
|
if (pos == -1) { // not found? add
|
|
|
|
cm->insertSubmenu(label, &menu, pos);
|
|
|
|
}
|
|
|
|
}
|
2003-07-20 02:45:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void BScreen::removeConfigMenu(FbTk::Menu &menu) {
|
2004-06-14 12:25:31 +00:00
|
|
|
|
2015-01-16 07:36:49 +00:00
|
|
|
FbTk::Menu* cm = m_configmenu.get();
|
|
|
|
if (cm) {
|
|
|
|
int pos = cm->findSubmenuIndex(&menu);
|
|
|
|
if (pos > -1) {
|
|
|
|
cm->remove(pos);
|
|
|
|
}
|
|
|
|
}
|
2006-10-27 06:57:43 +00:00
|
|
|
}
|
2003-07-20 02:45:57 +00:00
|
|
|
|
2006-03-18 22:03:23 +00:00
|
|
|
|
|
|
|
void BScreen::addManagedResource(FbTk::Resource_base *resource) {
|
|
|
|
m_managed_resources.push_back(resource);
|
|
|
|
}
|
|
|
|
|
2012-04-06 12:10:24 +00:00
|
|
|
int BScreen::getGap(int head, const char type) {
|
|
|
|
return type == 'w' ? getXGap(head) : getYGap(head);
|
|
|
|
}
|
|
|
|
|
|
|
|
int BScreen::calRelativeSize(int head, int i, char type) {
|
|
|
|
// return floor(i * getGap(head, type) / 100 + 0.5);
|
|
|
|
return FbTk::RelCalcHelper::calPercentageValueOf(i, getGap(head, type));
|
|
|
|
}
|
|
|
|
int BScreen::calRelativeWidth(int head, int i) {
|
|
|
|
return calRelativeSize(head, i, 'w');
|
|
|
|
}
|
|
|
|
int BScreen::calRelativeHeight(int head, int i) {
|
|
|
|
return calRelativeSize(head, i, 'h');
|
|
|
|
}
|
|
|
|
|
|
|
|
int BScreen::calRelativePosition(int head, int i, char type) {
|
|
|
|
int max = type == 'w' ? maxLeft(head) : maxTop(head);
|
|
|
|
// return floor((i - min) / getGap(head, type) * 100 + 0.5);
|
|
|
|
return FbTk::RelCalcHelper::calPercentageOf((i - max), getGap(head, type));
|
|
|
|
}
|
|
|
|
// returns a pixel, which is relative to the width of the screen
|
|
|
|
// screen starts from 0, 1000 px width, if i is 10 then it should return 100
|
|
|
|
int BScreen::calRelativePositionWidth(int head, int i) {
|
|
|
|
return calRelativePosition(head, i, 'w');
|
|
|
|
}
|
|
|
|
// returns a pixel, which is relative to the height of th escreen
|
|
|
|
// screen starts from 0, 1000 px height, if i is 10 then it should return 100
|
|
|
|
int BScreen::calRelativePositionHeight(int head, int i) {
|
|
|
|
return calRelativePosition(head, i, 'h');
|
|
|
|
}
|
|
|
|
|
|
|
|
int BScreen::calRelativeDimension(int head, int i, char type) {
|
|
|
|
// return floor(i / getGap(head, type) * 100 + 0.5);
|
|
|
|
return FbTk::RelCalcHelper::calPercentageOf(i, getGap(head, type));
|
|
|
|
}
|
|
|
|
int BScreen::calRelativeDimensionWidth(int head, int i) {
|
|
|
|
return calRelativeDimension(head, i, 'w');
|
|
|
|
}
|
|
|
|
int BScreen::calRelativeDimensionHeight(int head, int i) {
|
|
|
|
return calRelativeDimension(head, i, 'h');
|
|
|
|
}
|
|
|
|
|
|
|
|
float BScreen::getXGap(int head) {
|
|
|
|
return maxRight(head) - maxLeft(head);
|
|
|
|
}
|
|
|
|
float BScreen::getYGap(int head) {
|
|
|
|
return maxBottom(head) - maxTop(head);
|
|
|
|
}
|
|
|
|
|
2003-01-12 17:59:20 +00:00
|
|
|
void BScreen::setupConfigmenu(FbTk::Menu &menu) {
|
2007-10-13 21:51:37 +00:00
|
|
|
|
2015-01-21 08:53:54 +00:00
|
|
|
struct ConfigMenu::SetupHelper sh(*this, m_resource_manager, resource);
|
2015-01-15 17:49:35 +00:00
|
|
|
menu.removeAll();
|
|
|
|
ConfigMenu::setup(menu, sh);
|
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;
|
2006-07-19 07:31:39 +00:00
|
|
|
m_focus_control->shutdown();
|
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) {
|
2008-01-19 12:00:46 +00:00
|
|
|
if (!doShowWindowPos())
|
2003-12-10 22:28:07 +00:00
|
|
|
return;
|
|
|
|
|
2010-09-08 18:17:21 +00:00
|
|
|
char buf[256];
|
|
|
|
sprintf(buf, "X:%5d x Y:%5d", x, y);
|
|
|
|
|
|
|
|
FbTk::BiDiString label(buf);
|
2008-05-09 17:39:02 +00:00
|
|
|
m_pos_window->showText(label);
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-01-16 11:47:07 +00:00
|
|
|
void BScreen::hidePosition() {
|
2008-05-09 17:39:02 +00:00
|
|
|
m_pos_window->hide();
|
2004-01-16 11:47:07 +00:00
|
|
|
}
|
|
|
|
|
2008-08-15 11:24:03 +00:00
|
|
|
void BScreen::showGeometry(unsigned int gx, unsigned int gy) {
|
2003-12-10 22:28:07 +00:00
|
|
|
if (!doShowWindowPos())
|
|
|
|
return;
|
|
|
|
|
2010-09-08 18:17:21 +00:00
|
|
|
char buf[256];
|
2004-06-07 11:46:05 +00:00
|
|
|
_FB_USES_NLS;
|
2002-12-01 13:42:15 +00:00
|
|
|
|
2010-09-08 18:17:21 +00:00
|
|
|
sprintf(buf,
|
2006-06-21 14:41:16 +00:00
|
|
|
_FB_XTEXT(Screen, GeometryFormat,
|
2004-06-07 11:46:05 +00:00
|
|
|
"W: %4d x H: %4d",
|
2006-05-20 15:08:14 +00:00
|
|
|
"Format for width and height window, %4d for width, and %4d for height").c_str(),
|
2004-06-07 11:46:05 +00:00
|
|
|
gx, gy);
|
2010-09-08 18:17:21 +00:00
|
|
|
|
|
|
|
FbTk::BiDiString label(buf);
|
2008-05-09 17:39:02 +00:00
|
|
|
m_geom_window->showText(label);
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-09-08 18:17:21 +00:00
|
|
|
void BScreen::showTooltip(const FbTk::BiDiString &text) {
|
2008-05-05 12:05:52 +00:00
|
|
|
if (*resource.tooltip_delay >= 0)
|
2008-05-09 17:39:02 +00:00
|
|
|
m_tooltip_window->showText(text);
|
2008-05-05 12:05:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void BScreen::hideTooltip() {
|
|
|
|
if (*resource.tooltip_delay >= 0)
|
2008-05-09 17:39:02 +00:00
|
|
|
m_tooltip_window->hide();
|
2008-05-05 12:05:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-08-02 12:58:37 +00:00
|
|
|
void BScreen::hideGeometry() {
|
2008-05-09 17:39:02 +00:00
|
|
|
m_geom_window->hide();
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
|
2011-02-23 21:49:27 +00:00
|
|
|
void BScreen::setLayer(FbTk::LayerItem &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
|
|
|
|
*/
|
2011-03-23 17:45:34 +00:00
|
|
|
void BScreen::nextWorkspace(int delta) {
|
2005-07-04 18:18:32 +00:00
|
|
|
changeWorkspaceID( (currentWorkspaceID() + delta) % numberOfWorkspaces());
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
|
2002-11-27 21:55:36 +00:00
|
|
|
/**
|
|
|
|
Goes to the workspace "left" of the current
|
|
|
|
*/
|
2011-03-23 17:45:34 +00:00
|
|
|
void BScreen::prevWorkspace(int delta) {
|
2006-04-11 18:26:00 +00:00
|
|
|
changeWorkspaceID( (static_cast<signed>(numberOfWorkspaces()) + currentWorkspaceID() - (delta % numberOfWorkspaces())) % numberOfWorkspaces());
|
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
|
|
|
|
*/
|
2011-03-23 17:45:34 +00:00
|
|
|
void BScreen::rightWorkspace(int delta) {
|
2005-07-04 18:18:32 +00:00
|
|
|
if (currentWorkspaceID()+delta < numberOfWorkspaces())
|
2003-05-15 12:00:46 +00:00
|
|
|
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
|
|
|
|
*/
|
2011-03-23 17:45:34 +00:00
|
|
|
void BScreen::leftWorkspace(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-04-02 23:14:54 +00:00
|
|
|
|
2003-06-12 15:24:37 +00:00
|
|
|
void BScreen::renderGeomWindow() {
|
2006-03-18 22:03:23 +00:00
|
|
|
|
2010-09-08 18:17:21 +00:00
|
|
|
char buf[256];
|
2004-06-07 11:46:05 +00:00
|
|
|
_FB_USES_NLS;
|
2003-08-25 13:15:53 +00:00
|
|
|
|
2015-01-03 20:45:14 +00:00
|
|
|
const std::string msg = _FB_XTEXT(Screen, GeometrySpacing,
|
|
|
|
"W: %04d x H: %04d", "Representative maximum sized text for width and height dialog");
|
|
|
|
const int n = snprintf(buf, msg.size(), msg.c_str(), 0, 0);
|
2010-09-08 18:17:21 +00:00
|
|
|
|
2015-01-03 20:45:14 +00:00
|
|
|
FbTk::BiDiString label(std::string(buf, n));
|
|
|
|
m_geom_window->resizeForText(label);
|
2008-05-09 17:39:02 +00:00
|
|
|
m_geom_window->reconfigTheme();
|
2003-06-12 15:24:37 +00:00
|
|
|
}
|
|
|
|
|
2004-01-16 11:47:07 +00:00
|
|
|
|
|
|
|
void BScreen::renderPosWindow() {
|
2015-01-03 20:45:14 +00:00
|
|
|
m_pos_window->resizeForText(FbTk::BiDiString("0:00000 x 0:00000"));
|
2008-05-09 17:39:02 +00:00
|
|
|
m_pos_window->reconfigTheme();
|
2004-01-16 11:47:07 +00:00
|
|
|
}
|
|
|
|
|
2003-05-12 04:28:46 +00:00
|
|
|
void BScreen::updateSize() {
|
2007-07-11 11:54:53 +00:00
|
|
|
// update xinerama layout
|
|
|
|
initXinerama();
|
|
|
|
|
2008-10-15 02:40:33 +00:00
|
|
|
// check if window geometry has changed
|
|
|
|
if (rootWindow().updateGeometry()) {
|
|
|
|
// reset background
|
|
|
|
m_root_theme->reset();
|
2003-05-12 04:28:46 +00:00
|
|
|
|
2008-10-15 02:40:33 +00:00
|
|
|
// send resize notify
|
|
|
|
m_resize_sig.emit(*this);
|
|
|
|
m_workspace_area_sig.emit(*this);
|
2007-03-01 22:18:18 +00:00
|
|
|
|
2008-10-15 02:40:33 +00:00
|
|
|
// move windows out of inactive heads
|
|
|
|
clearHeads();
|
|
|
|
}
|
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
|
|
|
/**
|
2006-07-20 03:25:28 +00:00
|
|
|
* Find the winclient to this window's left
|
2003-06-23 14:16:05 +00:00
|
|
|
* So, we check the leftgroup hint, and see if we know any windows
|
|
|
|
*/
|
2006-07-20 03:25:28 +00:00
|
|
|
WinClient *BScreen::findGroupLeft(WinClient &winclient) {
|
2003-06-23 14:16:05 +00:00
|
|
|
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;
|
|
|
|
|
2006-07-20 03:25:28 +00:00
|
|
|
return have_client;
|
2003-06-23 14:16:05 +00:00
|
|
|
}
|
|
|
|
|
2006-07-20 03:25:28 +00:00
|
|
|
WinClient *BScreen::findGroupRight(WinClient &winclient) {
|
2003-06-23 14:16:05 +00:00
|
|
|
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
|
|
|
|
|
2006-08-05 05:21:15 +00:00
|
|
|
// forget about it if it isn't the left-most client in the group
|
|
|
|
Window leftwin = other->getGroupLeftWindow();
|
|
|
|
if (leftwin != None && leftwin != winclient.window())
|
2003-06-23 14:16:05 +00:00
|
|
|
return 0;
|
|
|
|
|
2006-07-20 03:25:28 +00:00
|
|
|
return other;
|
2003-06-23 14:16:05 +00:00
|
|
|
}
|
2008-02-10 17:16:50 +00:00
|
|
|
void BScreen::clearXinerama() {
|
2010-03-17 15:35:07 +00:00
|
|
|
fbdbg<<"BScreen::initXinerama(): dont have Xinerama"<<endl;
|
|
|
|
|
2015-01-16 07:44:49 +00:00
|
|
|
m_xinerama.avail = false;
|
|
|
|
m_xinerama.heads.clear();
|
2008-02-10 17:16:50 +00:00
|
|
|
}
|
2006-07-20 03:25:28 +00:00
|
|
|
|
2003-05-19 15:32:47 +00:00
|
|
|
void BScreen::initXinerama() {
|
2003-05-19 14:26:30 +00:00
|
|
|
#ifdef XINERAMA
|
2015-01-16 07:44:49 +00:00
|
|
|
Display* display = FbTk::App::instance()->display();
|
|
|
|
int number = 0;
|
|
|
|
XineramaScreenInfo *si = XineramaQueryScreens(display, &number);
|
2003-05-19 14:26:30 +00:00
|
|
|
|
2015-01-16 07:44:49 +00:00
|
|
|
if (!si && number == 0) {
|
2008-02-10 17:16:50 +00:00
|
|
|
clearXinerama();
|
2003-05-19 14:26:30 +00:00
|
|
|
return;
|
|
|
|
}
|
2010-03-17 15:35:07 +00:00
|
|
|
|
2015-01-16 07:44:49 +00:00
|
|
|
m_xinerama.avail = true;
|
2003-05-19 14:26:30 +00:00
|
|
|
|
2015-01-16 07:44:49 +00:00
|
|
|
fbdbg<<"BScreen::initXinerama(): have Xinerama"<<endl;
|
2007-07-09 14:45:47 +00:00
|
|
|
|
|
|
|
/* The call may have actually failed. If this is the first time we init
|
|
|
|
* Xinerama, fall back to turning it off. If not, pretend nothing
|
|
|
|
* happened -- another event will tell us and it will work then. */
|
2015-01-16 07:44:49 +00:00
|
|
|
if (!si) {
|
|
|
|
if (m_xinerama.heads.empty())
|
2008-02-10 17:16:50 +00:00
|
|
|
clearXinerama();
|
|
|
|
return;
|
2007-07-09 14:45:47 +00:00
|
|
|
}
|
|
|
|
|
2015-01-16 07:44:49 +00:00
|
|
|
m_xinerama.heads.resize(number);
|
|
|
|
for (int i = 0; i < number; i++) {
|
|
|
|
m_xinerama.heads[i]._x = si[i].x_org;
|
|
|
|
m_xinerama.heads[i]._y = si[i].y_org;
|
|
|
|
m_xinerama.heads[i]._width = si[i].width;
|
|
|
|
m_xinerama.heads[i]._height = si[i].height;
|
2003-05-19 14:26:30 +00:00
|
|
|
}
|
2015-01-16 07:44:49 +00:00
|
|
|
XFree(si);
|
2010-03-17 15:35:07 +00:00
|
|
|
|
|
|
|
fbdbg<<"BScreen::initXinerama(): number of heads ="<<number<<endl;
|
2004-09-11 13:33:07 +00:00
|
|
|
|
2007-07-11 11:54:53 +00:00
|
|
|
/* Reallocate to the new number of heads. */
|
2010-05-01 12:29:41 +00:00
|
|
|
int ha_num = numHeads() ? numHeads() : 1;
|
|
|
|
int ha_oldnum = m_head_areas.size();
|
2007-07-11 11:54:53 +00:00
|
|
|
if (ha_num > ha_oldnum) {
|
|
|
|
m_head_areas.resize(ha_num);
|
|
|
|
for (int i = ha_oldnum; i < ha_num; i++)
|
|
|
|
m_head_areas[i] = new HeadArea();
|
|
|
|
} else if (ha_num < ha_oldnum) {
|
|
|
|
for (int i = ha_num; i < ha_oldnum; i++)
|
|
|
|
delete m_head_areas[i];
|
|
|
|
m_head_areas.resize(ha_num);
|
|
|
|
}
|
|
|
|
|
2003-05-19 15:32:47 +00:00
|
|
|
#else // XINERAMA
|
2015-01-16 07:44:49 +00:00
|
|
|
m_xinerama.avail = false;
|
2003-05-19 15:32:47 +00:00
|
|
|
#endif // XINERAMA
|
2003-05-19 14:26:30 +00:00
|
|
|
}
|
|
|
|
|
2007-03-01 22:18:18 +00:00
|
|
|
/* Move windows out of inactive heads */
|
|
|
|
void BScreen::clearHeads() {
|
|
|
|
if (!hasXinerama()) return;
|
|
|
|
|
|
|
|
for (Workspaces::iterator i = m_workspaces_list.begin();
|
2011-11-02 17:33:38 +00:00
|
|
|
i != m_workspaces_list.end(); ++i) {
|
2010-05-01 12:29:31 +00:00
|
|
|
for (Workspace::Windows::iterator win = (*i)->windowList().begin();
|
2011-11-02 17:33:38 +00:00
|
|
|
win != (*i)->windowList().end(); ++win) {
|
2010-05-01 12:29:31 +00:00
|
|
|
|
2011-03-19 14:05:39 +00:00
|
|
|
FluxboxWindow& w = *(*win);
|
|
|
|
|
|
|
|
// check if the window is invisible
|
|
|
|
bool invisible = true;
|
|
|
|
int j;
|
2015-01-16 07:44:49 +00:00
|
|
|
for (j = 0; j < numHeads(); ++j) {
|
|
|
|
XineramaHeadInfo& hi = m_xinerama.heads[j];
|
2011-03-19 14:05:39 +00:00
|
|
|
if (RectangleUtil::overlapRectangles(hi, w)) {
|
|
|
|
invisible = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (invisible) { // get closest head and replace the (now invisible) cwindow
|
|
|
|
int closest_head = getHead(w.fbWindow());
|
|
|
|
if (closest_head == 0) {
|
|
|
|
closest_head = 1; // first head is a safe bet here
|
|
|
|
}
|
|
|
|
w.placeWindow(closest_head);
|
2007-03-01 22:18:18 +00:00
|
|
|
}
|
2010-05-01 12:29:31 +00:00
|
|
|
}
|
2007-03-01 22:18:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-05-19 14:26:30 +00:00
|
|
|
int BScreen::getHead(int x, int y) const {
|
2010-05-01 12:29:41 +00:00
|
|
|
#ifdef XINERAMA
|
|
|
|
if (hasXinerama()) {
|
2015-01-16 07:44:49 +00:00
|
|
|
for (int i = 0; i < numHeads(); i++) {
|
|
|
|
if (RectangleUtil::insideBorder(m_xinerama.heads[i], x, y, 0)) {
|
2010-05-01 12:29:41 +00:00
|
|
|
return i+1;
|
|
|
|
}
|
2003-05-19 14:26:30 +00:00
|
|
|
}
|
|
|
|
}
|
2003-05-19 15:32:47 +00:00
|
|
|
#endif // XINERAMA
|
2003-05-19 14:26:30 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2010-05-01 12:27:45 +00:00
|
|
|
|
2007-03-31 22:00:39 +00:00
|
|
|
int BScreen::getHead(const FbTk::FbWindow &win) const {
|
2010-05-01 12:27:45 +00:00
|
|
|
|
|
|
|
int head = 0; // whole screen
|
|
|
|
|
2010-08-22 18:11:59 +00:00
|
|
|
#ifdef XINERAMA
|
2010-05-01 12:27:45 +00:00
|
|
|
if (hasXinerama()) {
|
|
|
|
|
|
|
|
// cast needed to prevent win.x() become "unsigned int" which is bad
|
2013-05-23 07:16:19 +00:00
|
|
|
// since it might be negative
|
2010-05-01 12:27:45 +00:00
|
|
|
int cx = win.x() + static_cast<int>(win.width() / 2);
|
|
|
|
int cy = win.y() + static_cast<int>(win.height() / 2);
|
|
|
|
|
2013-02-26 19:15:44 +00:00
|
|
|
head = getHead(cx, cy);
|
|
|
|
if ( head == 0 ) {
|
|
|
|
// if the center of the window is not on any head then select
|
|
|
|
// the head which center is nearest to the window center
|
|
|
|
long dist = -1;
|
|
|
|
int i;
|
2015-01-16 07:44:49 +00:00
|
|
|
for (i = 0; i < numHeads(); ++i) {
|
|
|
|
const XineramaHeadInfo& hi = m_xinerama.heads[i];
|
|
|
|
long d = calcSquareDistance(cx, cy,
|
2013-02-26 19:15:44 +00:00
|
|
|
hi.x() + (hi.width() / 2), hi.y() + (hi.height() / 2));
|
|
|
|
if (dist == -1 || d < dist) { // found a closer head
|
|
|
|
head = i + 1;
|
|
|
|
dist = d;
|
|
|
|
}
|
2010-05-01 12:27:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return head;
|
2003-05-20 11:03:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
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(),
|
2006-10-27 06:57:43 +00:00
|
|
|
rootWindow().window(), &ignore_w,
|
2003-05-19 14:26:30 +00:00
|
|
|
&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
|
2015-01-16 07:44:49 +00:00
|
|
|
if (head == 0 || head > numHeads()) return 0;
|
|
|
|
return m_xinerama.heads[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
|
2015-01-16 07:44:49 +00:00
|
|
|
if (head == 0 || head > numHeads()) return 0;
|
|
|
|
return m_xinerama.heads[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
|
2015-01-16 07:44:49 +00:00
|
|
|
if (head == 0 || head > numHeads()) return width();
|
|
|
|
return m_xinerama.heads[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
|
2015-01-16 07:44:49 +00:00
|
|
|
if (head == 0 || head > numHeads()) return height();
|
|
|
|
return m_xinerama.heads[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)
|
2010-05-01 12:29:41 +00:00
|
|
|
head = 1;
|
2006-10-27 06:57:43 +00:00
|
|
|
|
2004-09-11 13:33:07 +00:00
|
|
|
int hx = getHeadX(head);
|
|
|
|
int hy = getHeadY(head);
|
|
|
|
int hw = getHeadWidth(head);
|
|
|
|
int hh = getHeadHeight(head);
|
2006-10-27 06:57:43 +00:00
|
|
|
|
2010-09-09 13:31:54 +00:00
|
|
|
x = FbTk::Util::clamp(x, hx, hx + hw - w);
|
|
|
|
y = FbTk::Util::clamp(y, hy, hy + hh - h);
|
2004-09-11 13:33:07 +00:00
|
|
|
|
|
|
|
return make_pair(x,y);
|
|
|
|
}
|