fluxbox/src/fluxbox.cc

2321 lines
75 KiB
C++
Raw Normal View History

// fluxbox.cc for Fluxbox Window Manager
2003-01-09 18:32:09 +00:00
// Copyright (c) 2001 - 2003 Henrik Kinnunen (fluxgen at users.sourceforge.net)
//
2001-12-11 20:47:02 +00:00
// blackbox.cc for blackbox - an X11 Window manager
2003-01-09 18:32:09 +00:00
// Copyright (c) 1997 - 2000 Brad Hughes (bhughes at tcac.net)
2001-12-11 20:47:02 +00:00
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2003-01-09 18:32:09 +00:00
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
2001-12-11 20:47:02 +00:00
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
// $Id: fluxbox.cc,v 1.107 2003/04/15 00:50:25 rathnor Exp $
2002-08-13 21:19:00 +00:00
#include "fluxbox.hh"
2001-12-11 20:47:02 +00:00
#include "i18n.hh"
#include "Screen.hh"
#include "Toolbar.hh"
#include "Window.hh"
#include "Workspace.hh"
2002-01-06 11:07:42 +00:00
#include "StringUtil.hh"
#include "Resource.hh"
2002-01-20 02:19:16 +00:00
#include "XrmDatabaseHelper.hh"
#include "AtomHandler.hh"
2002-11-30 20:18:35 +00:00
#include "ImageControl.hh"
2002-12-02 23:49:56 +00:00
#include "EventManager.hh"
2003-02-17 12:31:17 +00:00
#include "FbCommands.hh"
2003-04-14 15:28:52 +00:00
#include "WinClient.hh"
2002-08-13 21:19:00 +00:00
//Use GNU extensions
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif // _GNU_SOURCE
2003-01-09 18:32:09 +00:00
#ifdef HAVE_CONFIG_H
2002-08-13 21:19:00 +00:00
#include "../config.h"
#endif // HAVE_CONFIG_H
#ifdef SLIT
#include "Slit.hh"
#endif // SLIT
#ifdef USE_GNOME
#include "Gnome.hh"
#endif // USE_GNOME
#ifdef USE_NEWWMSPEC
#include "Ewmh.hh"
#endif //USE_NEWWMSPEC
// X headers
2002-01-06 11:07:42 +00:00
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xresource.h>
#include <X11/Xatom.h>
#include <X11/keysym.h>
#include <X11/cursorfont.h>
2002-08-02 13:00:23 +00:00
#ifdef SHAPE
2002-01-06 11:07:42 +00:00
#include <X11/extensions/shape.h>
#endif // SHAPE
2002-08-02 13:00:23 +00:00
#include <cstdio>
2002-08-13 21:19:00 +00:00
#include <cstdlib>
#include <cstring>
2001-12-11 20:47:02 +00:00
2002-08-02 13:00:23 +00:00
#ifdef HAVE_UNISTD_H
#include <sys/types.h>
#include <unistd.h>
2001-12-11 20:47:02 +00:00
#endif // HAVE_UNISTD_H
2002-08-02 13:00:23 +00:00
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
2001-12-11 20:47:02 +00:00
#endif // HAVE_SYS_PARAM_H
#ifndef MAXPATHLEN
#define MAXPATHLEN 255
2001-12-11 20:47:02 +00:00
#endif // MAXPATHLEN
2002-08-02 13:00:23 +00:00
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
2001-12-11 20:47:02 +00:00
#endif // HAVE_SYS_SELECT_H
#ifdef HAVE_SYS_STAT_H
#include <sys/types.h>
#include <sys/stat.h>
2001-12-11 20:47:02 +00:00
#endif // HAVE_SYS_STAT_H
#ifdef TIME_WITH_SYS_TIME
#include <sys/time.h>
#include <time.h>
2001-12-11 20:47:02 +00:00
#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
2001-12-11 20:47:02 +00:00
#endif // TIME_WITH_SYS_TIME
#ifdef HAVE_LIBGEN_H
# include <libgen.h>
2001-12-11 20:47:02 +00:00
#endif // HAVE_LIBGEN_H
#include <sys/wait.h>
2001-12-11 20:47:02 +00:00
#include <iostream>
#include <string>
2002-01-09 15:08:22 +00:00
#include <memory>
2002-07-14 01:00:23 +00:00
#include <algorithm>
#include <typeinfo>
2002-01-20 02:19:16 +00:00
using namespace std;
using namespace FbTk;
2001-12-11 20:47:02 +00:00
#ifndef HAVE_BASENAME
2002-08-02 13:00:23 +00:00
namespace {
char *basename (char *s) {
2002-12-01 13:42:15 +00:00
char *save = s;
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
while (*s) {
if (*s++ == '/')
save = s;
}
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
return save;
2001-12-11 20:47:02 +00:00
}
}; // end anonymous namespace
2002-08-02 13:00:23 +00:00
2001-12-11 20:47:02 +00:00
#endif // HAVE_BASENAME
#define RC_PATH "fluxbox"
#define RC_INIT_FILE "init"
//-----------------------------------------------------------------
//---- accessors for int, bool, and some enums with Resource ------
//-----------------------------------------------------------------
template<>
void Resource<int>::
setFromString(const char* strval) {
2002-12-01 13:42:15 +00:00
int val;
if (sscanf(strval, "%d", &val)==1)
*this = val;
}
template<>
void Resource<std::string>::
setFromString(const char *strval) {
2002-12-01 13:42:15 +00:00
*this = strval;
}
template<>
void Resource<bool>::
setFromString(char const *strval) {
2002-12-01 13:42:15 +00:00
if (strcasecmp(strval, "true")==0)
*this = true;
else
*this = false;
}
template<>
void Resource<Fluxbox::FocusModel>::
setFromString(char const *strval) {
// auto raise options here for backwards read compatibility
// they are not supported for saving purposes. Nor does the "AutoRaise"
// part actually do anything
if (strcasecmp(strval, "SloppyFocus") == 0
|| strcasecmp(strval, "AutoRaiseSloppyFocus") == 0)
m_value = Fluxbox::SLOPPYFOCUS;
else if (strcasecmp(strval, "SemiSloppyFocus") == 0
|| strcasecmp(strval, "AutoRaiseSemiSloppyFocus") == 0)
m_value = Fluxbox::SEMISLOPPYFOCUS;
else if (strcasecmp(strval, "ClickToFocus") == 0)
m_value = Fluxbox::CLICKTOFOCUS;
else
setDefaultValue();
}
template<>
void Resource<Fluxbox::TitlebarList>::
setFromString(char const *strval) {
2002-12-01 13:42:15 +00:00
vector<std::string> val;
StringUtil::stringtok(val, strval);
int size=val.size();
//clear old values
m_value.clear();
2002-12-01 13:42:15 +00:00
for (int i=0; i<size; i++) {
if (strcasecmp(val[i].c_str(), "Maximize")==0)
m_value.push_back(Fluxbox::MAXIMIZE);
else if (strcasecmp(val[i].c_str(), "Minimize")==0)
m_value.push_back(Fluxbox::MINIMIZE);
else if (strcasecmp(val[i].c_str(), "Shade")==0)
m_value.push_back(Fluxbox::SHADE);
else if (strcasecmp(val[i].c_str(), "Stick")==0)
m_value.push_back(Fluxbox::STICK);
else if (strcasecmp(val[i].c_str(), "Menu")==0)
m_value.push_back(Fluxbox::MENU);
else if (strcasecmp(val[i].c_str(), "Close")==0)
m_value.push_back(Fluxbox::CLOSE);
}
}
template<>
void Resource<unsigned int>::
setFromString(const char *strval) {
2002-12-01 13:42:15 +00:00
if (sscanf(strval, "%ul", &m_value) != 1)
setDefaultValue();
}
//-----------------------------------------------------------------
//---- manipulators for int, bool, and some enums with Resource ---
//-----------------------------------------------------------------
template<>
std::string Resource<bool>::
getString() {
2002-12-01 13:42:15 +00:00
return std::string(**this == true ? "true" : "false");
}
template<>
std::string Resource<int>::
getString() {
2002-12-01 13:42:15 +00:00
char strval[256];
sprintf(strval, "%d", **this);
return std::string(strval);
}
template<>
std::string Resource<std::string>::
getString() { return **this; }
template<>
std::string Resource<Fluxbox::FocusModel>::
getString() {
switch (m_value) {
case Fluxbox::SLOPPYFOCUS:
return string("SloppyFocus");
case Fluxbox::SEMISLOPPYFOCUS:
return string("SemiSloppyFocus");
case Fluxbox::CLICKTOFOCUS:
return string("ClickToFocus");
}
// default string
return string("ClickToFocus");
}
template<>
2002-02-04 06:57:26 +00:00
std::string Resource<Fluxbox::TitlebarList>::
getString() {
2002-12-01 13:42:15 +00:00
string retval;
int size=m_value.size();
for (int i=0; i<size; i++) {
switch (m_value[i]) {
case Fluxbox::SHADE:
retval.append("Shade");
break;
case Fluxbox::MINIMIZE:
retval.append("Minimize");
break;
case Fluxbox::MAXIMIZE:
retval.append("Maximize");
break;
case Fluxbox::CLOSE:
retval.append("Close");
break;
case Fluxbox::STICK:
retval.append("Stick");
break;
case Fluxbox::MENU:
retval.append("Menu");
break;
default:
break;
}
retval.append(" ");
}
return retval;
2001-12-11 20:47:02 +00:00
}
template<>
string Resource<unsigned int>::
getString() {
2002-12-01 13:42:15 +00:00
char tmpstr[128];
sprintf(tmpstr, "%ul", m_value);
return string(tmpstr);
}
2001-12-11 20:47:02 +00:00
template<>
void Resource<Fluxbox::Layer>::
setFromString(const char *strval) {
int tempnum = 0;
if (sscanf(strval, "%d", &tempnum) == 1)
m_value = tempnum;
else if (strcasecmp(strval, "Menu") == 0)
m_value = Fluxbox::instance()->getMenuLayer();
else if (strcasecmp(strval, "AboveDock") == 0)
m_value = Fluxbox::instance()->getAboveDockLayer();
else if (strcasecmp(strval, "Dock") == 0)
m_value = Fluxbox::instance()->getDockLayer();
else if (strcasecmp(strval, "Top") == 0)
m_value = Fluxbox::instance()->getTopLayer();
else if (strcasecmp(strval, "Normal") == 0)
m_value = Fluxbox::instance()->getNormalLayer();
else if (strcasecmp(strval, "Bottom") == 0)
m_value = Fluxbox::instance()->getBottomLayer();
else if (strcasecmp(strval, "Desktop") == 0)
m_value = Fluxbox::instance()->getDesktopLayer();
else
setDefaultValue();
}
template<>
string Resource<Fluxbox::Layer>::
getString() {
if (m_value.getNum() == Fluxbox::instance()->getMenuLayer())
return string("Menu");
else if (m_value.getNum() == Fluxbox::instance()->getAboveDockLayer())
return string("AboveDock");
else if (m_value.getNum() == Fluxbox::instance()->getDockLayer())
return string("Dock");
else if (m_value.getNum() == Fluxbox::instance()->getTopLayer())
return string("Top");
else if (m_value.getNum() == Fluxbox::instance()->getNormalLayer())
return string("Normal");
else if (m_value.getNum() == Fluxbox::instance()->getBottomLayer())
return string("Bottom");
else if (m_value.getNum() == Fluxbox::instance()->getDesktopLayer())
return string("Desktop");
else {
char tmpstr[128];
sprintf(tmpstr, "%d", m_value.getNum());
return string(tmpstr);
}
}
2001-12-11 20:47:02 +00:00
//static singleton var
Fluxbox *Fluxbox::singleton=0;
2002-03-01 15:28:56 +00:00
//default values for titlebar left and right
//don't forget to change last value in m_rc_titlebar_* if you add more to these
Fluxbox::Titlebar Fluxbox::m_titlebar_left[] = {STICK};
Fluxbox::Titlebar Fluxbox::m_titlebar_right[] = {MINIMIZE, MAXIMIZE, CLOSE};
2001-12-11 20:47:02 +00:00
2002-08-13 21:19:00 +00:00
Fluxbox::Fluxbox(int m_argc, char **m_argv, const char *dpy_name, const char *rc)
2002-12-01 13:42:15 +00:00
: BaseDisplay(m_argv[0], dpy_name), FbAtoms(getXDisplay()),
m_resourcemanager(), m_screen_rm(),
m_rc_tabs(m_resourcemanager, true, "session.tabs", "Session.Tabs"),
m_rc_iconbar(m_resourcemanager, true, "session.iconbar", "Session.Iconbar"),
m_rc_colors_per_channel(m_resourcemanager, 4, "session.colorsPerChannel", "Session.ColorsPerChannel"),
m_rc_numlayers(m_resourcemanager, 13, "session.numLayers", "Session.NumLayers"),
2002-12-01 13:42:15 +00:00
m_rc_stylefile(m_resourcemanager, "", "session.styleFile", "Session.StyleFile"),
m_rc_menufile(m_resourcemanager, DEFAULTMENU, "session.menuFile", "Session.MenuFile"),
m_rc_keyfile(m_resourcemanager, DEFAULTKEYSFILE, "session.keyFile", "Session.KeyFile"),
m_rc_slitlistfile(m_resourcemanager, "", "session.slitlistFile", "Session.SlitlistFile"),
m_rc_groupfile(m_resourcemanager, "", "session.groupFile", "Session.GroupFile"),
m_rc_titlebar_left(m_resourcemanager, TitlebarList(&m_titlebar_left[0], &m_titlebar_left[1]), "session.titlebar.left", "Session.Titlebar.Left"),
m_rc_titlebar_right(m_resourcemanager, TitlebarList(&m_titlebar_right[0], &m_titlebar_right[3]), "session.titlebar.right", "Session.Titlebar.Right"),
m_rc_cache_life(m_resourcemanager, 5, "session.cacheLife", "Session.CacheLife"),
m_rc_cache_max(m_resourcemanager, 200, "session.cacheMax", "Session.CacheMax"),
focused_window(0), masked_window(0),
timer(this),
watching_screen(0), watch_keyrelease(0),
2002-12-01 13:42:15 +00:00
no_focus(false),
rc_file(rc ? rc : ""),
argv(m_argv), argc(m_argc),
key(0)
2001-12-11 20:47:02 +00:00
{
2002-12-01 13:42:15 +00:00
if (singleton != 0) {
cerr<<"Fatal! There can only one instance of fluxbox class."<<endl;
abort();
}
2002-12-01 13:42:15 +00:00
//catch system signals
SignalHandler *sigh = SignalHandler::instance();
2002-12-01 13:42:15 +00:00
sigh->registerHandler(SIGSEGV, this);
sigh->registerHandler(SIGFPE, this);
sigh->registerHandler(SIGTERM, this);
sigh->registerHandler(SIGINT, this);
sigh->registerHandler(SIGCHLD, this);
sigh->registerHandler(SIGHUP, this);
sigh->registerHandler(SIGUSR1, this);
sigh->registerHandler(SIGUSR2, this);
//setup cursor bitmaps
cursor.session = XCreateFontCursor(getXDisplay(), XC_left_ptr);
cursor.move = XCreateFontCursor(getXDisplay(), XC_fleur);
cursor.ll_angle = XCreateFontCursor(getXDisplay(), XC_ll_angle);
cursor.lr_angle = XCreateFontCursor(getXDisplay(), XC_lr_angle);
//singleton pointer
singleton = this;
// setup atom handlers
#ifdef USE_GNOME
2002-12-01 13:42:15 +00:00
m_atomhandler.push_back(new Gnome()); // for gnome 1 atom support
#endif //USE_GNOME
#ifdef USE_NEWWMSPEC
2002-12-01 13:42:15 +00:00
m_atomhandler.push_back(new Ewmh()); // for Extended window manager atom support
#endif // USE_NEWWMSPEC
2002-08-18 11:01:52 +00:00
2002-12-01 13:42:15 +00:00
grab();
2002-12-01 13:42:15 +00:00
setupConfigFiles();
2002-12-01 13:42:15 +00:00
if (! XSupportsLocale())
cerr<<"Warning: X server does not support locale"<<endl;
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
if (XSetLocaleModifiers("") == 0)
cerr<<"Warning: cannot set locale modifiers"<<endl;
2001-12-11 20:47:02 +00:00
// Set default values to member variables
2002-12-01 13:42:15 +00:00
resource.auto_raise_delay.tv_sec = resource.auto_raise_delay.tv_usec = 0;
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
masked = None;
2001-12-11 20:47:02 +00:00
#ifdef HAVE_GETPID
2002-12-01 13:42:15 +00:00
fluxbox_pid = XInternAtom(getXDisplay(), "_BLACKBOX_PID", False);
#endif // HAVE_GETPID
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
int i;
load_rc();
//allocate screens
for (i = 0; i < getNumberOfScreens(); i++) {
char scrname[128], altscrname[128];
sprintf(scrname, "session.screen%d", i);
sprintf(altscrname, "session.Screen%d", i);
BScreen *screen = new BScreen(m_screen_rm, scrname, altscrname, i, getNumberOfLayers());
2002-12-01 13:42:15 +00:00
if (! screen->isScreenManaged()) {
delete screen;
continue;
}
screenList.push_back(screen);
2003-03-03 21:51:13 +00:00
m_atomhandler.push_back(&screen->getToolbarHandler());
2002-12-01 13:42:15 +00:00
// attach screen signals to this
screen->currentWorkspaceSig().attach(this);
screen->workspaceCountSig().attach(this);
screen->workspaceNamesSig().attach(this);
screen->clientListSig().attach(this);
2002-12-01 13:42:15 +00:00
// initiate atomhandler for screen specific stuff
for (size_t atomh=0; atomh<m_atomhandler.size(); ++atomh) {
m_atomhandler[atomh]->initForScreen(*screen);
}
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
}
I18n *i18n = I18n::instance();
if (screenList.size() == 0) {
2002-12-02 23:49:56 +00:00
throw string(
2002-12-01 13:42:15 +00:00
i18n->
getMessage(
FBNLS::blackboxSet, FBNLS::blackboxNoManagableScreens,
2002-12-02 23:49:56 +00:00
"Fluxbox::Fluxbox: no managable screens found, aborting."));
2002-12-01 13:42:15 +00:00
}
2002-08-18 11:01:52 +00:00
2002-12-01 13:42:15 +00:00
XSynchronize(getXDisplay(), False);
XSync(getXDisplay(), False);
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
reconfigure_wait = reread_menu_wait = false;
2002-03-19 00:16:44 +00:00
2002-12-01 13:42:15 +00:00
timer.setTimeout(0);
timer.fireOnce(True);
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
//create keybindings handler and load keys file
2003-03-01 07:30:42 +00:00
key.reset(new Keys(StringUtil::expandFilename(*m_rc_keyfile).c_str()));
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
ungrab();
2001-12-11 20:47:02 +00:00
}
Fluxbox::~Fluxbox() {
2002-12-01 13:42:15 +00:00
// destroy atomhandlers
while (!m_atomhandler.empty()) {
delete m_atomhandler.back();
m_atomhandler.pop_back();
}
2002-12-01 13:42:15 +00:00
std::list<MenuTimestamp *>::iterator it = menuTimestamps.begin();
std::list<MenuTimestamp *>::iterator it_end = menuTimestamps.end();
for (; it != it_end; ++it) {
MenuTimestamp *ts = *it;
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
if (ts->filename)
delete [] ts->filename;
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
delete ts;
}
2001-12-11 20:47:02 +00:00
}
2003-04-14 15:28:52 +00:00
/**
setup the configutation files in
home directory
*/
void Fluxbox::setupConfigFiles() {
2002-12-01 13:42:15 +00:00
bool createInit, createKeys, createMenu;
createInit = createKeys = createMenu = false;
string dirname = getenv("HOME")+string("/.")+string(RC_PATH) + "/";
string initFile, keysFile, menuFile, slitlistFile;
initFile = dirname+RC_INIT_FILE;
keysFile = dirname+"keys";
menuFile = dirname+"menu";
struct stat buf;
// is file/dir already there?
if (! stat(dirname.c_str(), &buf)) {
/*TODO: this
if (! (buf.st_mode & S_IFDIR)) {
cerr << dirname.c_str() << "!" << endl;
return 1;
}
*/
2002-12-01 13:42:15 +00:00
// check if anything with those name exists, if not create new
if (stat(initFile.c_str(), &buf))
createInit = true;
if (stat(keysFile.c_str(), &buf))
createKeys = true;
if (stat(menuFile.c_str(), &buf))
createMenu = true;
} else {
#ifdef DEBUG
2002-12-01 13:42:15 +00:00
cerr <<__FILE__<<"("<<__LINE__<<"): Creating dir: " << dirname.c_str() << endl;
#endif // DEBUG
2002-12-01 13:42:15 +00:00
// create directory with perm 700
if (mkdir(dirname.c_str(), 0700)) {
cerr << "Can't create " << dirname << " directory!" << endl;
return;
}
2002-12-01 13:42:15 +00:00
//mark creation of files
createInit = createKeys = createMenu = true;
}
// should we copy key configuraion?
if (createKeys) {
ifstream from(DEFAULTKEYSFILE);
ofstream to(keysFile.c_str());
if (! to.good()) {
cerr << "Can't write file" << endl;
} else if (from.good()) {
#ifdef DEBUG
cerr << "Copying file: " << DEFAULTKEYSFILE << endl;
#endif // DEBUG
to<<from.rdbuf(); //copy file
2002-12-01 13:42:15 +00:00
} else {
cerr<<"Can't copy default keys file."<<endl;
}
}
// should we copy menu configuraion?
if (createMenu) {
ifstream from(DEFAULTMENU);
ofstream to(menuFile.c_str());
if (! to.good()) {
cerr << "Can't open " << menuFile.c_str() << "for writing" << endl;
} else if (from.good()) {
#ifdef DEBUG
cerr << "Copying file: " << DEFAULTMENU << endl;
#endif // DEBUG
to<<from.rdbuf(); //copy file
} else {
cerr<<"Can't copy default menu file."<<endl;
}
}
// should we copy default init file?
if (createInit) {
ifstream from(DEFAULT_INITFILE);
ofstream to(initFile.c_str());
if (! to.good()) {
cerr << "Can't open " << initFile.c_str() << "for writing" << endl;
} else if (from.good()) {
#ifdef DEBUG
cerr << "Copying file: " << DEFAULT_INITFILE << endl;
#endif // DEBUG
to<<from.rdbuf(); //copy file
} else {
cerr<<"Can't copy default init file."<<endl;
}
}
}
2001-12-11 20:47:02 +00:00
void Fluxbox::handleEvent(XEvent * const e) {
2001-12-11 20:47:02 +00:00
2003-03-22 05:13:08 +00:00
// it is possible (e.g. during moving) for a window
// to mask all events to go to it
if ((masked == e->xany.window) && masked_window) {
if (e->type == MotionNotify) {
last_time = e->xmotion.time;
masked_window->motionNotifyEvent(e->xmotion);
return;
} else if (e->type == ButtonRelease) {
e->xbutton.window = masked_window->getFbWindow().window();
}
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
}
2002-12-03 23:58:06 +00:00
// try FbTk::EventHandler first
FbTk::EventManager::instance()->handleEvent(*e);
2002-12-01 13:42:15 +00:00
switch (e->type) {
case ButtonRelease:
case ButtonPress:
handleButtonEvent(e->xbutton);
break;
2002-12-01 13:42:15 +00:00
case ConfigureRequest:
2002-12-02 23:49:56 +00:00
{
FluxboxWindow *win = (FluxboxWindow *) 0;
2001-12-11 20:47:02 +00:00
2002-12-02 23:49:56 +00:00
if ((win = searchWindow(e->xconfigurerequest.window))) {
win->configureRequestEvent(e->xconfigurerequest);
2001-12-11 20:47:02 +00:00
} else {
2002-12-02 23:49:56 +00:00
grab();
if (validateWindow(e->xconfigurerequest.window)) {
XWindowChanges xwc;
2001-12-11 20:47:02 +00:00
2002-12-02 23:49:56 +00:00
xwc.x = e->xconfigurerequest.x;
xwc.y = e->xconfigurerequest.y;
xwc.width = e->xconfigurerequest.width;
xwc.height = e->xconfigurerequest.height;
xwc.border_width = e->xconfigurerequest.border_width;
xwc.sibling = e->xconfigurerequest.above;
xwc.stack_mode = e->xconfigurerequest.detail;
2001-12-11 20:47:02 +00:00
2002-12-02 23:49:56 +00:00
XConfigureWindow(getXDisplay(), e->xconfigurerequest.window,
e->xconfigurerequest.value_mask, &xwc);
}
2001-12-11 20:47:02 +00:00
2002-12-02 23:49:56 +00:00
ungrab();
2002-12-01 13:42:15 +00:00
}
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
}
2002-12-02 23:49:56 +00:00
break;
case MapRequest: {
#ifdef DEBUG
cerr<<"MapRequest for 0x"<<hex<<e->xmaprequest.window<<dec<<endl;
2002-08-04 15:00:50 +00:00
#endif // DEBUG
2002-12-02 23:49:56 +00:00
FluxboxWindow *win = searchWindow(e->xmaprequest.window);
if (! win) {
//!!! TODO
BScreen *scr = searchScreen(e->xmaprequest.parent);
cerr<<"screen = "<<scr<<endl;
if (scr != 0)
scr->createWindow(e->xmaprequest.window);
else
cerr<<"Fluxbox Warning! Could not find screen to map window on!"<<endl;
}
2002-12-01 13:42:15 +00:00
if ((win = searchWindow(e->xmaprequest.window)))
win->mapRequestEvent(e->xmaprequest);
2002-12-01 13:42:15 +00:00
}
2002-12-02 23:49:56 +00:00
break;
2002-12-01 13:42:15 +00:00
case MapNotify:
2002-12-02 23:49:56 +00:00
{
FluxboxWindow *win = searchWindow(e->xmap.window);
if (win != 0)
win->mapNotifyEvent(e->xmap);
2002-12-01 13:42:15 +00:00
2002-12-02 23:49:56 +00:00
}
break;
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
case UnmapNotify:
handleUnmapNotify(e->xunmap);
break;
case MappingNotify:
// Update stored modifier mapping
#ifdef DEBUG
cerr<<__FILE__<<"("<<__FUNCTION__<<"): MappingNotify"<<endl;
#endif // DEBUG
if (key.get()) {
key->loadModmap();
}
break;
2002-12-01 13:42:15 +00:00
case CreateNotify:
break;
2002-12-01 13:42:15 +00:00
case DestroyNotify: {
2003-04-14 15:28:52 +00:00
#ifdef DEBUG
cerr<<__FILE__<<"("<<__FUNCTION__<<"): DestroyNotify"<<endl;
#endif // DEBUG
FluxboxWindow *win = searchWindow(e->xdestroywindow.window);
if (win != 0) {
WinClient *client = win->findClient(e->xdestroywindow.window);
if (client != 0) {
win->destroyNotifyEvent(e->xdestroywindow);
delete client;
if (win->numClients() == 0 ||
&win->winClient() == client && win->numClients() == 1) {
delete win;
}
2001-12-11 20:47:02 +00:00
2003-04-14 15:28:52 +00:00
}
2002-12-01 13:42:15 +00:00
}
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
}
2002-12-02 23:49:56 +00:00
break;
case MotionNotify:
2002-12-02 23:49:56 +00:00
break;
2002-12-01 13:42:15 +00:00
case PropertyNotify: {
2002-02-17 18:43:30 +00:00
2002-12-01 13:42:15 +00:00
last_time = e->xproperty.time;
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
if (e->xproperty.state != PropertyDelete) {
FluxboxWindow *win = searchWindow(e->xproperty.window);
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
if (win)
win->propertyNotifyEvent(e->xproperty.atom);
}
2002-02-17 18:43:30 +00:00
2002-12-01 13:42:15 +00:00
}
2002-12-02 23:49:56 +00:00
break;
2002-12-01 13:42:15 +00:00
case EnterNotify: {
last_time = e->xcrossing.time;
2002-12-03 23:58:06 +00:00
BScreen *screen = 0;
2002-12-01 13:42:15 +00:00
if (e->xcrossing.mode == NotifyGrab)
break;
if ((e->xcrossing.window == e->xcrossing.root) &&
(screen = searchScreen(e->xcrossing.window))) {
screen->getImageControl()->installRootColormap();
2001-12-11 20:47:02 +00:00
}
2002-12-01 13:42:15 +00:00
}
2002-12-02 23:49:56 +00:00
break;
2002-12-01 13:42:15 +00:00
case LeaveNotify:
2002-12-02 23:49:56 +00:00
{
last_time = e->xcrossing.time;
}
break;
2002-12-01 13:42:15 +00:00
case Expose:
2002-12-02 23:49:56 +00:00
{
FluxboxWindow *win = (FluxboxWindow *) 0;
2001-12-11 20:47:02 +00:00
2002-12-02 23:49:56 +00:00
if ((win = searchWindow(e->xexpose.window)))
win->exposeEvent(e->xexpose);
2003-04-14 15:28:52 +00:00
2002-12-02 23:49:56 +00:00
}
break;
case KeyRelease:
2002-12-01 13:42:15 +00:00
case KeyPress:
handleKeyEvent(e->xkey);
break;
2002-12-01 13:42:15 +00:00
case ColormapNotify: {
BScreen *screen = searchScreen(e->xcolormap.window);
if (screen != 0) {
screen->setRootColormapInstalled((e->xcolormap.state ==
ColormapInstalled) ? True : False);
}
}
2002-12-02 23:49:56 +00:00
break;
2002-12-01 13:42:15 +00:00
case FocusIn: {
if (e->xfocus.mode == NotifyUngrab ||
e->xfocus.detail == NotifyPointer)
break;
FluxboxWindow *win = searchWindow(e->xfocus.window);
if (win && ! win->isFocused())
setFocusedWindow(win);
2002-12-01 13:42:15 +00:00
} break;
case FocusOut:
break;
2002-12-01 13:42:15 +00:00
case ClientMessage:
handleClientMessage(e->xclient);
break;
2002-12-01 13:42:15 +00:00
default: {
2002-02-04 06:57:26 +00:00
2002-12-01 13:42:15 +00:00
#ifdef SHAPE
2002-12-02 23:49:56 +00:00
if (e->type == getShapeEventBase()) {
XShapeEvent *shape_event = (XShapeEvent *) e;
FluxboxWindow *win = (FluxboxWindow *) 0;
2001-12-11 20:47:02 +00:00
2002-12-02 23:49:56 +00:00
if ((win = searchWindow(e->xany.window)) ||
(shape_event->kind != ShapeBounding))
win->shapeEvent(shape_event);
2002-12-01 13:42:15 +00:00
}
2002-12-02 23:49:56 +00:00
#endif // SHAPE
}
2002-12-01 13:42:15 +00:00
}
}
2001-12-11 20:47:02 +00:00
void Fluxbox::handleButtonEvent(XButtonEvent &be) {
2002-12-01 13:42:15 +00:00
switch (be.type) {
case ButtonPress:
2003-04-14 15:28:52 +00:00
{
last_time = be.time;
2002-12-01 13:42:15 +00:00
ScreenList::iterator it = screenList.begin();
ScreenList::iterator it_end = screenList.end();
2002-12-01 13:42:15 +00:00
for (; it != it_end; ++it) {
2002-02-04 06:57:26 +00:00
2002-12-01 13:42:15 +00:00
BScreen *screen = *it;
if (be.window != screen->getRootWindow())
continue;
2002-12-01 13:42:15 +00:00
if (be.button == 1) {
if (! screen->isRootColormapInstalled())
screen->getImageControl()->installRootColormap();
if (screen->getWorkspacemenu()->isVisible())
screen->getWorkspacemenu()->hide();
if (screen->getRootmenu()->isVisible())
screen->getRootmenu()->hide();
2002-02-04 06:57:26 +00:00
2002-12-01 13:42:15 +00:00
} else if (be.button == 2) {
int mx = be.x_root -
(screen->getWorkspacemenu()->width() / 2);
int my = be.y_root -
(screen->getWorkspacemenu()->titleHeight() / 2);
2002-12-01 13:42:15 +00:00
if (mx < 0) mx = 0;
if (my < 0) my = 0;
if (mx + screen->getWorkspacemenu()->width() >
screen->getWidth()) {
mx = screen->getWidth() -
screen->getWorkspacemenu()->width() -
screen->getBorderWidth();
}
if (my + screen->getWorkspacemenu()->height() >
screen->getHeight()) {
my = screen->getHeight() -
screen->getWorkspacemenu()->height() -
screen->getBorderWidth();
}
screen->getWorkspacemenu()->move(mx, my);
if (! screen->getWorkspacemenu()->isVisible()) {
screen->getWorkspacemenu()->removeParent();
screen->getWorkspacemenu()->show();
}
} else if (be.button == 3) {
2003-04-14 15:28:52 +00:00
//calculate placement of workspace menu
//and show/hide it
2002-12-01 13:42:15 +00:00
int mx = be.x_root -
(screen->getRootmenu()->width() / 2);
int my = be.y_root -
(screen->getRootmenu()->titleHeight() / 2);
if (mx < 0) mx = 0;
if (my < 0) my = 0;
if (mx + screen->getRootmenu()->width() > screen->getWidth()) {
mx = screen->getWidth() -
screen->getRootmenu()->width() -
screen->getBorderWidth();
}
if (my + screen->getRootmenu()->height() >
screen->getHeight()) {
my = screen->getHeight() -
screen->getRootmenu()->height() -
screen->getBorderWidth();
}
screen->getRootmenu()->move(mx, my);
if (! screen->getRootmenu()->isVisible()) {
checkMenu();
screen->getRootmenu()->show();
}
} else if (screen->isDesktopWheeling() && be.button == 4) {
screen->nextWorkspace(1);
} else if (screen->isDesktopWheeling() && be.button == 5) {
screen->prevWorkspace(1);
}
2003-04-14 15:28:52 +00:00
} // end for
2002-12-01 13:42:15 +00:00
}
2003-04-14 15:28:52 +00:00
break;
2002-12-01 13:42:15 +00:00
case ButtonRelease:
2003-04-14 15:28:52 +00:00
{
last_time = be.time;
FluxboxWindow *win = (FluxboxWindow *) 0;
2003-04-14 15:28:52 +00:00
if ((win = searchWindow(be.window)))
win->buttonReleaseEvent(be);
2003-04-14 15:28:52 +00:00
}
break;
2002-12-01 13:42:15 +00:00
default:
break;
2002-12-01 13:42:15 +00:00
}
}
2001-12-11 20:47:02 +00:00
2002-02-17 18:43:30 +00:00
void Fluxbox::handleUnmapNotify(XUnmapEvent &ue) {
2002-12-01 13:42:15 +00:00
FluxboxWindow *win = 0;
2002-02-17 18:43:30 +00:00
2002-12-01 13:42:15 +00:00
BScreen *screen = searchScreen(ue.event);
2002-02-17 18:43:30 +00:00
2003-04-14 15:28:52 +00:00
if ( ue.event != ue.window && (screen != 0 || !ue.send_event))
2002-12-01 13:42:15 +00:00
return;
2002-02-17 18:43:30 +00:00
2002-12-01 13:42:15 +00:00
if ((win = searchWindow(ue.window)) != 0) {
2003-04-14 15:28:52 +00:00
WinClient *client = win->findClient(ue.window);
if (client != 0) {
win->unmapNotifyEvent(ue);
client = 0; // it's invalid now when win destroyed the client
2002-12-01 13:42:15 +00:00
if (win == focused_window)
2002-12-01 13:42:15 +00:00
focused_window = 0;
2003-04-14 15:28:52 +00:00
// finaly destroy window if empty
if (win->numClients() == 0) {
delete win;
win = 0;
}
}
2002-12-01 13:42:15 +00:00
}
2002-02-17 18:43:30 +00:00
}
2003-04-14 15:28:52 +00:00
/**
* Handles XClientMessageEvent
*/
void Fluxbox::handleClientMessage(XClientMessageEvent &ce) {
2002-08-04 15:00:50 +00:00
#ifdef DEBUG
2002-12-01 13:42:15 +00:00
cerr<<__FILE__<<"("<<__LINE__<<"): ClientMessage. data.l[0]=0x"<<hex<<ce.data.l[0]<<
2002-08-04 15:00:50 +00:00
" message_type=0x"<<ce.message_type<<dec<<endl;
#endif // DEBUG
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
if (ce.format != 32)
return;
2002-12-01 13:42:15 +00:00
if (ce.message_type == getWMChangeStateAtom()) {
FluxboxWindow *win = searchWindow(ce.window);
if (! win || ! win->validateClient())
return;
if (ce.data.l[0] == IconicState)
win->iconify();
if (ce.data.l[0] == NormalState)
win->deiconify();
} else if (ce.message_type == getFluxboxChangeWorkspaceAtom()) {
BScreen *screen = searchScreen(ce.window);
if (screen && ce.data.l[0] >= 0 &&
ce.data.l[0] < (signed)screen->getCount())
screen->changeWorkspaceID(ce.data.l[0]);
2002-12-01 13:42:15 +00:00
} else if (ce.message_type == getFluxboxChangeWindowFocusAtom()) {
FluxboxWindow *win = searchWindow(ce.window);
if (win && win->isVisible() && win->setInputFocus())
win->installColormap(True);
} else if (ce.message_type == getFluxboxCycleWindowFocusAtom()) {
BScreen *screen = searchScreen(ce.window);
if (screen) {
if (! ce.data.l[0])
screen->prevFocus();
else
screen->nextFocus();
}
} else if (ce.message_type == getFluxboxChangeAttributesAtom()) {
2002-12-01 13:42:15 +00:00
FluxboxWindow *win = searchWindow(ce.window);
if (win && win->validateClient()) {
BlackboxHints net;
net.flags = ce.data.l[0];
net.attrib = ce.data.l[1];
net.workspace = ce.data.l[2];
net.stack = ce.data.l[3];
net.decoration = static_cast<int>(ce.data.l[4]);
win->changeBlackboxHints(net);
2002-12-01 13:42:15 +00:00
}
} else {
FluxboxWindow *win = searchWindow(ce.window);
BScreen *screen = searchScreen(ce.window);
2002-12-01 13:42:15 +00:00
for (size_t i=0; i<m_atomhandler.size(); ++i) {
m_atomhandler[i]->checkClientMessage(ce, screen, win);
}
}
2001-12-11 20:47:02 +00:00
}
2003-04-14 15:28:52 +00:00
/**
Handles KeyRelease and KeyPress events
*/
void Fluxbox::handleKeyEvent(XKeyEvent &ke) {
2002-12-01 13:42:15 +00:00
switch (ke.type) {
case KeyPress:
2002-12-02 23:49:56 +00:00
{
BScreen *screen = searchScreen(ke.window);
2002-12-02 23:49:56 +00:00
2003-04-14 15:28:52 +00:00
if (screen == 0)
break;
2002-12-01 13:42:15 +00:00
#ifdef DEBUG
2003-04-14 15:28:52 +00:00
cerr<<"KeyEvent"<<endl;
2002-12-01 13:42:15 +00:00
#endif
2003-04-14 15:28:52 +00:00
//find action
Keys::KeyAction action = key->getAction(&ke);
2002-12-01 13:42:15 +00:00
#ifdef DEBUG
2003-04-14 15:28:52 +00:00
const char *actionstr = key->getActionStr(action);
if (actionstr)
cerr<<"KeyAction("<<actionstr<<")"<<endl;
2002-12-01 13:42:15 +00:00
#endif
2003-04-14 15:28:52 +00:00
if (action==Keys::LASTKEYGRAB) //if action not found end case
break;
2002-12-02 23:49:56 +00:00
2003-04-14 15:28:52 +00:00
// what to allow if moving
if (focused_window && focused_window->isMoving()) {
int allowed = false;
switch (action) {
2002-12-01 13:42:15 +00:00
case Keys::WORKSPACE:
case Keys::SENDTOWORKSPACE:
case Keys::WORKSPACE1:
case Keys::WORKSPACE2:
case Keys::WORKSPACE3:
case Keys::WORKSPACE4:
case Keys::WORKSPACE5:
case Keys::WORKSPACE6:
case Keys::WORKSPACE7:
case Keys::WORKSPACE8:
case Keys::WORKSPACE9:
case Keys::WORKSPACE10:
case Keys::WORKSPACE11:
case Keys::WORKSPACE12:
case Keys::NEXTWORKSPACE:
case Keys::PREVWORKSPACE:
case Keys::LEFTWORKSPACE:
case Keys::RIGHTWORKSPACE:
2003-04-14 15:28:52 +00:00
allowed = true;
2002-12-01 13:42:15 +00:00
break;
2003-04-14 15:28:52 +00:00
default:
allowed = false;
}
if (!allowed) break;
}
switch (action) {
case Keys::WORKSPACE:
// Workspace1 has id 0, hence -1
screen->changeWorkspaceID(key->getParam()-1);
break;
case Keys::SENDTOWORKSPACE:
// Workspace1 has id 0, hence -1
screen->sendToWorkspace(key->getParam()-1);
break;
// NOTE!!! The WORKSPACEn commands are not needed anymore
case Keys::WORKSPACE1:
screen->changeWorkspaceID(0);
break;
case Keys::WORKSPACE2:
screen->changeWorkspaceID(1);
break;
case Keys::WORKSPACE3:
screen->changeWorkspaceID(2);
break;
case Keys::WORKSPACE4:
screen->changeWorkspaceID(3);
break;
case Keys::WORKSPACE5:
screen->changeWorkspaceID(4);
break;
case Keys::WORKSPACE6:
screen->changeWorkspaceID(5);
break;
case Keys::WORKSPACE7:
screen->changeWorkspaceID(6);
break;
case Keys::WORKSPACE8:
screen->changeWorkspaceID(7);
break;
case Keys::WORKSPACE9:
screen->changeWorkspaceID(8);
break;
case Keys::WORKSPACE10:
screen->changeWorkspaceID(9);
break;
case Keys::WORKSPACE11:
screen->changeWorkspaceID(10);
break;
case Keys::WORKSPACE12:
screen->changeWorkspaceID(11);
break;
case Keys::NEXTWORKSPACE:
screen->nextWorkspace(key->getParam());
break;
case Keys::PREVWORKSPACE:
screen->prevWorkspace(key->getParam());
break;
case Keys::LEFTWORKSPACE:
screen->leftWorkspace(key->getParam());
break;
case Keys::RIGHTWORKSPACE:
screen->rightWorkspace(key->getParam());
break;
case Keys::KILLWINDOW: //kill the current window
if (focused_window) {
XKillClient(screen->getBaseDisplay()->getXDisplay(),
focused_window->getClientWindow());
}
break;
case Keys::NEXTWINDOW: //activate next window
if (!watching_screen && !(key->getParam() & BScreen::CYCLELINEAR)) {
// if stacked cycling, then set a watch for
// the release of exactly these modifiers
watchKeyRelease(screen, Keys::cleanMods(ke.state));
}
2003-04-14 15:28:52 +00:00
screen->nextFocus(key->getParam());
break;
case Keys::PREVWINDOW: //activate prev window
if (!watching_screen && !(key->getParam() & BScreen::CYCLELINEAR)) {
// if stacked cycling, then set a watch for
// the release of exactly these modifiers
watchKeyRelease(screen, Keys::cleanMods(ke.state));
}
2003-04-14 15:28:52 +00:00
screen->prevFocus(key->getParam());
break;
case Keys::NEXTTAB:
if (focused_window && focused_window->numClients() > 1)
focused_window->nextClient();
break;
case Keys::PREVTAB:
if (focused_window && focused_window->numClients() > 1)
focused_window->prevClient();
break;
case Keys::FIRSTTAB:
cerr<<"FIRSTTAB TODO!"<<endl;
break;
case Keys::LASTTAB:
cerr<<"LASTTAB TODO!"<<endl;
break;
case Keys::MOVETABPREV:
cerr<<"MOVETABPREV TODO!"<<endl;
break;
case Keys::MOVETABNEXT:
cerr<<"MOVETABNEXT TODO!"<<endl;
break;
case Keys::ATTACHLAST:
//!! just attach last window to focused window
if (focused_window) {
Workspace *space = screen->getCurrentWorkspace();
Workspace::Windows &wins = space->getWindowList();
if (wins.size() == 1)
break;
Workspace::Windows::iterator it = wins.begin();
for (; it != wins.end(); ++it) {
if ((*it) != focused_window) {
focused_window->attachClient((*it)->winClient());
break;
2002-12-02 23:49:56 +00:00
}
}
2003-04-14 15:28:52 +00:00
}
break;
case Keys::DETACHCLIENT:
if (focused_window) {
focused_window->detachClient(focused_window->winClient());
}
break;
case Keys::EXECUTE: //execute command on keypress
{
FbCommands::ExecuteCmd cmd(key->getExecCommand());
cmd.execute();
}
break;
case Keys::QUIT:
{
shutdown();
}
break;
case Keys::ROOTMENU: //show root menu
{
ScreenList::iterator it = screenList.begin();
ScreenList::iterator it_end = screenList.end();
2002-12-01 13:42:15 +00:00
2003-04-14 15:28:52 +00:00
for (; it != it_end; ++it) {
2002-12-01 13:42:15 +00:00
2003-04-14 15:28:52 +00:00
BScreen *screen = (*it);
if (ke.window != screen->getRootWindow())
continue;
2002-12-02 23:49:56 +00:00
2003-04-14 15:28:52 +00:00
//calculate placement of workspace menu
//and show/hide it
int mx = ke.x_root -
(screen->getRootmenu()->width() / 2);
int my = ke.y_root -
(screen->getRootmenu()->titleHeight() / 2);
if (mx < 0) mx = 0;
if (my < 0) my = 0;
if (mx + screen->getRootmenu()->width() > screen->getWidth()) {
mx = screen->getWidth() -
screen->getRootmenu()->width() -
screen->getBorderWidth();
}
if (my + screen->getRootmenu()->height() >
screen->getHeight()) {
my = screen->getHeight() -
screen->getRootmenu()->height() -
screen->getBorderWidth();
}
screen->getRootmenu()->move(mx, my);
if (! screen->getRootmenu()->isVisible()) {
checkMenu();
screen->getRootmenu()->show();
2002-12-02 23:49:56 +00:00
}
2002-12-01 13:42:15 +00:00
}
}
2003-04-14 15:28:52 +00:00
break;
default: //try to see if its a window action
doWindowAction(action, key->getParam());
2002-12-01 13:42:15 +00:00
}
2003-04-14 15:28:52 +00:00
2002-12-01 13:42:15 +00:00
break;
}
case KeyRelease:
{
// we ignore most key releases unless we need to use
// a release to stop something (e.g. window cycling).
// we notify if _all_ of the watched modifiers are released
if (watching_screen && watch_keyrelease) {
// mask the mod of the released key out
// won't mask anything if it isn't a mod
ke.state &= ~key->keycodeToModmask(ke.keycode);
if ((watch_keyrelease & ke.state) == 0) {
watching_screen->notifyReleasedKeys(ke);
XUngrabKeyboard(getXDisplay(), CurrentTime);
// once they are released, we drop the watch
watching_screen = 0;
watch_keyrelease = 0;
}
}
break;
}
2002-12-01 13:42:15 +00:00
default:
2003-04-14 15:28:52 +00:00
break;
2002-12-01 13:42:15 +00:00
}
}
2002-02-20 23:12:07 +00:00
void Fluxbox::doWindowAction(Keys::KeyAction action, const int param) {
2002-12-01 13:42:15 +00:00
if (!focused_window)
return;
2002-01-11 09:26:33 +00:00
2002-12-01 13:42:15 +00:00
switch (action) {
case Keys::ICONIFY:
focused_window->iconify();
break;
case Keys::RAISE:
focused_window->raise();
2002-12-01 13:42:15 +00:00
break;
case Keys::LOWER:
focused_window->lower();
break;
case Keys::RAISELAYER:
2003-02-09 14:11:14 +00:00
focused_window->raiseLayer();
break;
case Keys::LOWERLAYER:
2003-02-09 14:11:14 +00:00
focused_window->lowerLayer();
break;
case Keys::TOPLAYER:
2003-02-09 14:11:14 +00:00
focused_window->moveToLayer(getBottomLayer());
break;
case Keys::BOTTOMLAYER:
2003-02-09 14:11:14 +00:00
focused_window->moveToLayer(getTopLayer());
2002-12-01 13:42:15 +00:00
break;
case Keys::CLOSE:
focused_window->close();
break;
case Keys::SHADE:
focused_window->shade(); // this has to be done in THIS order
break;
case Keys::MAXIMIZE:
focused_window->maximize();
2002-12-01 13:42:15 +00:00
break;
case Keys::STICK:
focused_window->stick();
break;
case Keys::VERTMAX:
if (focused_window->isResizable())
focused_window->maximizeVertical();
2002-12-01 13:42:15 +00:00
break;
case Keys::HORIZMAX:
if (focused_window->isResizable())
focused_window->maximizeHorizontal();
2002-12-01 13:42:15 +00:00
break;
case Keys::NUDGERIGHT:
focused_window->moveResize(
2002-12-01 13:42:15 +00:00
focused_window->getXFrame()+param, focused_window->getYFrame(),
focused_window->getWidth(), focused_window->getHeight());
break;
case Keys::NUDGELEFT:
focused_window->moveResize(
2002-12-01 13:42:15 +00:00
focused_window->getXFrame()-param, focused_window->getYFrame(),
focused_window->getWidth(), focused_window->getHeight());
break;
case Keys::NUDGEUP:
focused_window->moveResize(
2002-12-01 13:42:15 +00:00
focused_window->getXFrame(), focused_window->getYFrame()-param,
focused_window->getWidth(), focused_window->getHeight());
break;
case Keys::NUDGEDOWN:
focused_window->moveResize(
2002-12-01 13:42:15 +00:00
focused_window->getXFrame(), focused_window->getYFrame()+param,
focused_window->getWidth(), focused_window->getHeight());
break;
// NOTE !!! BIGNUDGExxxx is not needed, just use 10 as a parameter
case Keys::BIGNUDGERIGHT:
focused_window->moveResize(
2002-12-01 13:42:15 +00:00
focused_window->getXFrame()+10, focused_window->getYFrame(),
focused_window->getWidth(), focused_window->getHeight());
break;
case Keys::BIGNUDGELEFT:
focused_window->moveResize(
2002-12-01 13:42:15 +00:00
focused_window->getXFrame()-10, focused_window->getYFrame(),
focused_window->getWidth(), focused_window->getHeight());
break;
case Keys::BIGNUDGEUP:
focused_window->moveResize(
2002-12-01 13:42:15 +00:00
focused_window->getXFrame(), focused_window->getYFrame()-10,
focused_window->getWidth(), focused_window->getHeight());
break;
case Keys::BIGNUDGEDOWN:
focused_window->moveResize(
2002-12-01 13:42:15 +00:00
focused_window->getXFrame(), focused_window->getYFrame()+10,
focused_window->getWidth(), focused_window->getHeight());
break;
case Keys::HORIZINC:
focused_window->moveResize(
2002-12-01 13:42:15 +00:00
focused_window->getXFrame(), focused_window->getYFrame(),
focused_window->getWidth()+10, focused_window->getHeight());
break;
case Keys::VERTINC:
focused_window->moveResize(
2002-12-01 13:42:15 +00:00
focused_window->getXFrame(), focused_window->getYFrame(),
focused_window->getWidth(), focused_window->getHeight()+10);
break;
case Keys::HORIZDEC:
focused_window->moveResize(
2002-12-01 13:42:15 +00:00
focused_window->getXFrame(), focused_window->getYFrame(),
focused_window->getWidth()-10, focused_window->getHeight());
break;
case Keys::VERTDEC:
focused_window->moveResize(
2002-12-01 13:42:15 +00:00
focused_window->getXFrame(), focused_window->getYFrame(),
focused_window->getWidth(), focused_window->getHeight()-10);
break;
case Keys::TOGGLEDECOR:
focused_window->toggleDecoration();
break;
case Keys::TOGGLETAB:
2003-04-14 15:28:52 +00:00
cerr<<"TOGGLETAB TODO!"<<endl;
2002-12-01 13:42:15 +00:00
break;
default: //do nothing
break;
}
2001-12-11 20:47:02 +00:00
}
2003-04-14 15:28:52 +00:00
/// handle system signals
2002-11-27 22:00:19 +00:00
void Fluxbox::handleSignal(int signum) {
2002-12-01 13:42:15 +00:00
I18n *i18n = I18n::instance();
static int re_enter = 0;
switch (signum) {
case SIGCHLD: // we don't want the child process to kill us
waitpid(-1, 0, WNOHANG | WUNTRACED);
break;
case SIGHUP:
load_rc();
break;
case SIGUSR1:
reload_rc();
break;
case SIGUSR2:
rereadMenu();
break;
case SIGSEGV:
abort();
break;
case SIGFPE:
case SIGINT:
case SIGTERM:
shutdown();
break;
default:
fprintf(stderr,
i18n->getMessage(
FBNLS::BaseDisplaySet, FBNLS::BaseDisplaySignalCaught,
"%s: signal %d caught\n"),
getApplicationName(), signum);
if (! isStartup() && ! re_enter) {
re_enter = 1;
fprintf(stderr,
i18n->getMessage(
FBNLS::BaseDisplaySet, FBNLS::BaseDisplayShuttingDown,
"shutting down\n"));
shutdown();
}
2002-12-01 13:42:15 +00:00
fprintf(stderr,
i18n->getMessage(
FBNLS::BaseDisplaySet, FBNLS::BaseDisplayAborting,
"aborting... dumping core\n"));
abort();
break;
}
}
void Fluxbox::update(FbTk::Subject *changedsub) {
2003-04-14 15:28:52 +00:00
//TODO: fix signaling, this does not look good
2003-03-03 21:51:13 +00:00
if (typeid(*changedsub) == typeid(FluxboxWindow::WinSubject)) {
2002-12-01 13:42:15 +00:00
FluxboxWindow::WinSubject *winsub = dynamic_cast<FluxboxWindow::WinSubject *>(changedsub);
FluxboxWindow &win = winsub->win();
if ((&(win.hintSig())) == changedsub) { // hint signal
for (size_t i=0; i<m_atomhandler.size(); ++i) {
if (m_atomhandler[i]->update())
m_atomhandler[i]->updateHints(win);
}
} else if ((&(win.stateSig())) == changedsub) { // state signal
for (size_t i=0; i<m_atomhandler.size(); ++i) {
if (m_atomhandler[i]->update())
m_atomhandler[i]->updateState(win);
}
2003-04-14 15:28:52 +00:00
// if window changed to iconic state
// add to icon list
if (win.isIconic()) {
Workspace *space = win.getScreen().getWorkspace(win.getWorkspaceNumber());
if (space != 0)
space->removeWindow(&win);
win.getScreen().addIcon(&win);
}
if (win.isStuck()) {
// if we're sticky then reassociate window
// to all workspaces
BScreen &scr = win.getScreen();
if (scr.getCurrentWorkspaceID() != win.getWorkspaceNumber()) {
scr.reassociateWindow(&win,
scr.getCurrentWorkspaceID(),
true);
}
}
} else if ((&(win.layerSig())) == changedsub) { // layer signal
2003-04-14 15:28:52 +00:00
for (size_t i=0; i<m_atomhandler.size(); ++i) {
if (m_atomhandler[i]->update())
m_atomhandler[i]->updateLayer(win);
}
2003-03-03 21:51:13 +00:00
} else if ((&(win.dieSig())) == changedsub) { // window death signal
for (size_t i=0; i<m_atomhandler.size(); ++i) {
if (m_atomhandler[i]->update())
m_atomhandler[i]->updateWindowClose(win);
}
2003-04-14 15:28:52 +00:00
// make sure each workspace get this
BScreen &scr = win.getScreen();
scr.removeWindow(&win);
2003-04-14 15:28:52 +00:00
2002-12-01 13:42:15 +00:00
} else if ((&(win.workspaceSig())) == changedsub) { // workspace signal
for (size_t i=0; i<m_atomhandler.size(); ++i) {
if (m_atomhandler[i]->update())
m_atomhandler[i]->updateWorkspace(win);
2003-04-14 15:28:52 +00:00
}
2002-12-01 13:42:15 +00:00
} else {
#ifdef DEBUG
2002-12-01 13:42:15 +00:00
cerr<<__FILE__<<"("<<__LINE__<<"): WINDOW uncought signal from "<<&win<<endl;
#endif // DEBUG
2002-12-01 13:42:15 +00:00
}
2002-12-01 13:42:15 +00:00
} else if (typeid(*changedsub) == typeid(BScreen::ScreenSubject)) {
BScreen::ScreenSubject *subj = dynamic_cast<BScreen::ScreenSubject *>(changedsub);
BScreen &screen = subj->screen();
if ((&(screen.workspaceCountSig())) == changedsub) {
for (size_t i=0; i<m_atomhandler.size(); ++i) {
if (m_atomhandler[i]->update())
m_atomhandler[i]->updateWorkspaceCount(screen);
}
} else if ((&(screen.workspaceNamesSig())) == changedsub) {
for (size_t i=0; i<m_atomhandler.size(); ++i) {
if (m_atomhandler[i]->update())
m_atomhandler[i]->updateWorkspaceNames(screen);
}
} else if ((&(screen.currentWorkspaceSig())) == changedsub) {
for (size_t i=0; i<m_atomhandler.size(); ++i) {
if (m_atomhandler[i]->update())
m_atomhandler[i]->updateCurrentWorkspace(screen);
}
} else if ((&(screen.clientListSig())) == changedsub) {
for (size_t i=0; i<m_atomhandler.size(); ++i) {
if (m_atomhandler[i]->update())
m_atomhandler[i]->updateClientList(screen);
}
}
2003-04-14 15:28:52 +00:00
} else if (typeid(*changedsub) == typeid(WinClient::WinClientSubj)) {
WinClient::WinClientSubj *subj = dynamic_cast<WinClient::WinClientSubj *>(changedsub);
WinClient &client = subj->winClient();
if (client.fbwindow()) {
BScreen &screen = client.fbwindow()->getScreen();
screen.updateNetizenWindowDel(client.window());
screen.removeClient(client);
}
2003-04-14 15:28:52 +00:00
removeWindowSearch(client.window());
//!! TODO
#ifdef DEBUG
cerr<<__FILE__<<"("<<__FUNCTION__<<") TODO: signal stuff for client death!!"<<endl;
#endif // DEBUG
2002-12-01 13:42:15 +00:00
}
}
void Fluxbox::attachSignals(FluxboxWindow &win) {
2002-12-01 13:42:15 +00:00
win.hintSig().attach(this);
win.stateSig().attach(this);
win.workspaceSig().attach(this);
win.layerSig().attach(this);
2003-04-14 15:28:52 +00:00
win.winClient().dieSig().attach(this);
2003-03-03 21:51:13 +00:00
win.dieSig().attach(this);
2002-12-01 13:42:15 +00:00
for (size_t i=0; i<m_atomhandler.size(); ++i) {
m_atomhandler[i]->setupWindow(win);
}
2001-12-11 20:47:02 +00:00
}
BScreen *Fluxbox::searchScreen(Window window) {
2003-04-14 15:28:52 +00:00
BScreen *screen = 0;
2002-12-01 13:42:15 +00:00
ScreenList::iterator it = screenList.begin();
ScreenList::iterator it_end = screenList.end();
for (; it != it_end; ++it) {
if (*it) {
if ((*it)->getRootWindow() == window) {
screen = (*it);
return screen;
}
}
}
2003-04-14 15:28:52 +00:00
return 0;
2001-12-11 20:47:02 +00:00
}
FluxboxWindow *Fluxbox::searchWindow(Window window) {
2002-12-01 13:42:15 +00:00
std::map<Window, FluxboxWindow *>::iterator it = windowSearch.find(window);
return it == windowSearch.end() ? 0 : it->second;
2001-12-11 20:47:02 +00:00
}
FluxboxWindow *Fluxbox::searchGroup(Window window, FluxboxWindow *win) {
2002-12-01 13:42:15 +00:00
std::map<Window, FluxboxWindow *>::iterator it = groupSearch.find(window);
return it == groupSearch.end() ? 0 : it->second;
2001-12-11 20:47:02 +00:00
}
void Fluxbox::saveWindowSearch(Window window, FluxboxWindow *data) {
2002-12-01 13:42:15 +00:00
windowSearch[window] = data;
2001-12-11 20:47:02 +00:00
}
void Fluxbox::saveGroupSearch(Window window, FluxboxWindow *data) {
2002-12-01 13:42:15 +00:00
groupSearch[window] = data;
2001-12-11 20:47:02 +00:00
}
void Fluxbox::removeWindowSearch(Window window) {
2002-12-01 13:42:15 +00:00
windowSearch.erase(window);
2001-12-11 20:47:02 +00:00
}
void Fluxbox::removeGroupSearch(Window window) {
2002-12-01 13:42:15 +00:00
groupSearch.erase(window);
2001-12-11 20:47:02 +00:00
}
void Fluxbox::restart(const char *prog) {
2002-12-01 13:42:15 +00:00
shutdown();
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
if (prog) {
execlp(prog, prog, NULL);
perror(prog);
}
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
// fall back in case the above execlp doesn't work
execvp(argv[0], argv);
execvp(basename(argv[0]), argv);
2001-12-11 20:47:02 +00:00
}
void Fluxbox::shutdown() {
2002-12-01 13:42:15 +00:00
BaseDisplay::shutdown();
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
XSetInputFocus(getXDisplay(), PointerRoot, None, CurrentTime);
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
//send shutdown to all screens
ScreenList::iterator it = screenList.begin();
ScreenList::iterator it_end = screenList.end();
for (; it != it_end; ++it) {
if(*it)
(*it)->shutdown();
}
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
XSync(getXDisplay(), False);
2001-12-11 20:47:02 +00:00
}
//------ save_rc --------
2001-12-11 20:47:02 +00:00
//saves resources
//----------------------
void Fluxbox::save_rc() {
2002-02-11 11:33:14 +00:00
2002-12-01 13:42:15 +00:00
XrmDatabase new_blackboxrc = 0;
2002-01-20 02:19:16 +00:00
2002-12-01 13:42:15 +00:00
char rc_string[1024];
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
string dbfile(getRcFilename());
2002-01-20 02:19:16 +00:00
2002-12-01 13:42:15 +00:00
if (dbfile.size() != 0) {
m_resourcemanager.save(dbfile.c_str(), dbfile.c_str());
m_screen_rm.save(dbfile.c_str(), dbfile.c_str());
} else
cerr<<"database filename is invalid!"<<endl;
2002-01-20 02:19:16 +00:00
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
sprintf(rc_string, "session.doubleClickInterval: %lu",
resource.double_click_interval);
XrmPutLineResource(&new_blackboxrc, rc_string);
sprintf(rc_string, "session.autoRaiseDelay: %lu",
((resource.auto_raise_delay.tv_sec * 1000) +
(resource.auto_raise_delay.tv_usec / 1000)));
XrmPutLineResource(&new_blackboxrc, rc_string);
ScreenList::iterator it = screenList.begin();
ScreenList::iterator it_end = screenList.end();
//Save screen resources
for (; it != it_end; ++it) {
BScreen *screen = *it;
int screen_number = screen->getScreenNumber();
#ifdef SLIT
string slit_placement;
switch (screen->getSlitPlacement()) {
case Slit::TOPLEFT: slit_placement = "TopLeft"; break;
case Slit::CENTERLEFT: slit_placement = "CenterLeft"; break;
case Slit::BOTTOMLEFT: slit_placement = "BottomLeft"; break;
case Slit::TOPCENTER: slit_placement = "TopCenter"; break;
case Slit::BOTTOMCENTER: slit_placement = "BottomCenter"; break;
case Slit::TOPRIGHT: slit_placement = "TopRight"; break;
case Slit::BOTTOMRIGHT: slit_placement = "BottomRight"; break;
case Slit::CENTERRIGHT: default: slit_placement = "CenterRight"; break;
}
2002-12-01 13:42:15 +00:00
sprintf(rc_string, "session.screen%d.slit.placement: %s", screen_number,
slit_placement.c_str());
XrmPutLineResource(&new_blackboxrc, rc_string);
2002-12-01 13:42:15 +00:00
sprintf(rc_string, "session.screen%d.slit.direction: %s", screen_number,
((screen->getSlitDirection() == Slit::HORIZONTAL) ? "Horizontal" :
"Vertical"));
XrmPutLineResource(&new_blackboxrc, rc_string);
2002-12-01 13:42:15 +00:00
sprintf(rc_string, "session.screen%d.slit.autoHide: %s", screen_number,
((screen->getSlit()->doAutoHide()) ? "True" : "False"));
XrmPutLineResource(&new_blackboxrc, rc_string);
/*
#ifdef XINERAMA
sprintf(rc_string, "session.screen%d.slit.onHead: %d", screen_number,
screen->getSlitOnHead());
XrmPutLineResource(&new_blackboxrc, rc_string);
#endif // XINERAMA
*/
#endif // SLIT
2002-12-01 13:42:15 +00:00
sprintf(rc_string, "session.screen%d.rowPlacementDirection: %s", screen_number,
((screen->getRowPlacementDirection() == BScreen::LEFTRIGHT) ?
"LeftToRight" : "RightToLeft"));
XrmPutLineResource(&new_blackboxrc, rc_string);
sprintf(rc_string, "session.screen%d.colPlacementDirection: %s", screen_number,
((screen->getColPlacementDirection() == BScreen::TOPBOTTOM) ?
"TopToBottom" : "BottomToTop"));
XrmPutLineResource(&new_blackboxrc, rc_string);
string placement;
2002-01-05 10:57:31 +00:00
2002-12-01 13:42:15 +00:00
switch (screen->getPlacementPolicy()) {
case BScreen::CASCADEPLACEMENT:
placement = "CascadePlacement";
break;
case BScreen::COLSMARTPLACEMENT:
placement = "ColSmartPlacement";
break;
default:
case BScreen::ROWSMARTPLACEMENT:
placement = "RowSmartPlacement";
break;
}
2002-01-21 02:04:23 +00:00
2002-12-01 13:42:15 +00:00
sprintf(rc_string, "session.screen%d.windowPlacement: %s", screen_number,
placement.c_str());
XrmPutLineResource(&new_blackboxrc, rc_string);
// load_rc(screen);
2002-12-01 13:42:15 +00:00
// these are static, but may not be saved in the users resource file,
// writing these resources will allow the user to edit them at a later
// time... but loading the defaults before saving allows us to rewrite the
// users changes...
2001-12-11 20:47:02 +00:00
#ifdef HAVE_STRFTIME
2002-12-01 13:42:15 +00:00
sprintf(rc_string, "session.screen%d.strftimeFormat: %s", screen_number,
screen->getStrftimeFormat());
XrmPutLineResource(&new_blackboxrc, rc_string);
2001-12-11 20:47:02 +00:00
#else // !HAVE_STRFTIME
2002-12-01 13:42:15 +00:00
sprintf(rc_string, "session.screen%d.dateFormat: %s", screen_number,
((screen->getDateFormat() == B_EUROPEANDATE) ?
2002-12-01 13:42:15 +00:00
"European" : "American"));
XrmPutLineResource(&new_blackboxrc, rc_string);
sprintf(rc_string, "session.screen%d.clockFormat: %d", screen_number,
((screen->isClock24Hour()) ? 24 : 12));
XrmPutLineResource(&new_blackboxrc, rc_string);
2001-12-11 20:47:02 +00:00
#endif // HAVE_STRFTIME
2002-12-01 13:42:15 +00:00
// write out the users workspace names
sprintf(rc_string, "session.screen%d.workspaceNames: ", screen_number);
string workspaces_string(rc_string);
2002-02-17 18:43:30 +00:00
2002-12-01 13:42:15 +00:00
for (unsigned int workspace=0; workspace < screen->getCount(); workspace++) {
if (screen->getWorkspace(workspace)->name().size()!=0)
workspaces_string.append(screen->getWorkspace(workspace)->name());
else
workspaces_string.append("Null");
workspaces_string.append(",");
}
2002-01-21 02:04:23 +00:00
2002-12-01 13:42:15 +00:00
XrmPutLineResource(&new_blackboxrc, workspaces_string.c_str());
2002-01-20 02:19:16 +00:00
2002-12-01 13:42:15 +00:00
}
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
XrmDatabase old_blackboxrc = XrmGetFileDatabase(dbfile.c_str());
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
XrmMergeDatabases(new_blackboxrc, &old_blackboxrc); //merge database together
XrmPutFileDatabase(old_blackboxrc, dbfile.c_str());
XrmDestroyDatabase(old_blackboxrc);
2002-08-13 21:19:00 +00:00
#ifdef DEBUG
2002-12-01 13:42:15 +00:00
cerr<<__FILE__<<"("<<__LINE__<<"): ------------ SAVING DONE"<<endl;
2002-08-13 21:19:00 +00:00
#endif // DEBUG
2001-12-11 20:47:02 +00:00
}
//-------- getRcFilename -------------
// Returns filename of resource file
//------------------------------------
string Fluxbox::getRcFilename() {
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
if (rc_file.size() == 0) { // set default filename
string defaultfile(getenv("HOME")+string("/.")+RC_PATH+string("/")+RC_INIT_FILE);
return defaultfile;
}
2002-01-11 09:26:33 +00:00
2002-12-01 13:42:15 +00:00
return rc_file;
2001-12-11 20:47:02 +00:00
}
2002-05-29 06:22:31 +00:00
//-------- getDefaultDataFilename -------------
// Provides default filename of data file
//---------------------------------------------
void Fluxbox::getDefaultDataFilename(char *name, string &filename) {
2002-12-01 13:42:15 +00:00
filename = string(getenv("HOME")+string("/.")+RC_PATH+string("/")+name);
2002-05-29 06:22:31 +00:00
}
void Fluxbox::load_rc() {
2002-12-01 13:42:15 +00:00
XrmDatabaseHelper database;
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
//get resource filename
string dbfile(getRcFilename());
2002-12-01 13:42:15 +00:00
if (dbfile.size() != 0) {
if (!m_resourcemanager.load(dbfile.c_str())) {
cerr<<"Faild to load database:"<<dbfile<<endl;
cerr<<"Trying with: "<<DEFAULT_INITFILE<<endl;
if (!m_resourcemanager.load(DEFAULT_INITFILE))
cerr<<"Faild to load database: "<<DEFAULT_INITFILE<<endl;
}
} else {
if (!m_resourcemanager.load(DEFAULT_INITFILE))
cerr<<"Faild to load database: "<<DEFAULT_INITFILE<<endl;
}
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
XrmValue value;
char *value_type;
if (m_rc_menufile->size()) {
*m_rc_menufile = StringUtil::expandFilename(*m_rc_menufile);
if (!m_rc_menufile->size())
m_rc_menufile.setDefaultValue();
} else
m_rc_menufile.setDefaultValue();
2002-05-29 06:22:31 +00:00
2002-12-01 13:42:15 +00:00
if (m_rc_slitlistfile->size() != 0) {
*m_rc_slitlistfile = StringUtil::expandFilename(*m_rc_slitlistfile);
} else {
string filename;
getDefaultDataFilename("slitlist", filename);
m_rc_slitlistfile.setFromString(filename.c_str());
}
if (*m_rc_colors_per_channel < 2)
*m_rc_colors_per_channel = 2;
else if (*m_rc_colors_per_channel > 6)
*m_rc_colors_per_channel = 6;
if (m_rc_stylefile->size() == 0)
*m_rc_stylefile = DEFAULTSTYLE;
else // expand tilde
*m_rc_stylefile = StringUtil::expandFilename(*m_rc_stylefile);
//load file
database = XrmGetFileDatabase(dbfile.c_str());
if (database==0) {
cerr<<"Fluxbox: Cant open "<<dbfile<<" !"<<endl;
cerr<<"Using: "<<DEFAULT_INITFILE<<endl;
database = XrmGetFileDatabase(DEFAULT_INITFILE);
}
if (XrmGetResource(*database, "session.doubleClickInterval",
"Session.DoubleClickInterval", &value_type, &value)) {
if (sscanf(value.addr, "%lu", &resource.double_click_interval) != 1)
resource.double_click_interval = 250;
} else
resource.double_click_interval = 250;
if (XrmGetResource(*database, "session.autoRaiseDelay", "Session.AutoRaiseDelay",
&value_type, &value)) {
if (sscanf(value.addr, "%lu", &resource.auto_raise_delay.tv_usec) != 1)
resource.auto_raise_delay.tv_usec = 250;
} else
resource.auto_raise_delay.tv_usec = 250;
resource.auto_raise_delay.tv_sec = resource.auto_raise_delay.tv_usec / 1000;
resource.auto_raise_delay.tv_usec -=
(resource.auto_raise_delay.tv_sec * 1000);
resource.auto_raise_delay.tv_usec *= 1000;
// expand tilde
*m_rc_groupfile = StringUtil::expandFilename(*m_rc_groupfile);
2002-08-11 20:38:23 +00:00
#ifdef DEBUG
2002-12-01 13:42:15 +00:00
cerr<<__FILE__<<": Loading groups ("<<*m_rc_groupfile<<")"<<endl;
2002-08-11 20:38:23 +00:00
#endif // DEBUG
2002-12-01 13:42:15 +00:00
if (!Workspace::loadGroups(*m_rc_groupfile)) {
cerr<<"Faild to load groupfile: "<<*m_rc_groupfile<<endl;
}
}
void Fluxbox::load_rc(BScreen *screen) {
2002-12-01 13:42:15 +00:00
//get resource filename
string dbfile(getRcFilename());
if (dbfile.size() != 0) {
if (!m_screen_rm.load(dbfile.c_str())) {
cerr<<"Faild to load database:"<<dbfile<<endl;
cerr<<"Trying with: "<<DEFAULT_INITFILE<<endl;
if (!m_screen_rm.load(DEFAULT_INITFILE))
cerr<<"Faild to load database: "<<DEFAULT_INITFILE<<endl;
}
} else {
if (!m_screen_rm.load(DEFAULT_INITFILE))
cerr<<"Faild to load database: "<<DEFAULT_INITFILE<<endl;
}
2002-01-20 02:19:16 +00:00
2002-12-01 13:42:15 +00:00
XrmDatabaseHelper database;
2002-12-01 13:42:15 +00:00
database = XrmGetFileDatabase(dbfile.c_str());
if (database==0)
database = XrmGetFileDatabase(DEFAULT_INITFILE);
2002-12-01 13:42:15 +00:00
XrmValue value;
char *value_type, name_lookup[1024], class_lookup[1024];
int screen_number = screen->getScreenNumber();
sprintf(name_lookup, "session.screen%d.rowPlacementDirection", screen_number);
sprintf(class_lookup, "Session.Screen%d.RowPlacementDirection", screen_number);
if (XrmGetResource(*database, name_lookup, class_lookup, &value_type,
&value)) {
if (! strncasecmp(value.addr, "righttoleft", value.size))
screen->saveRowPlacementDirection(BScreen::RIGHTLEFT);
else
screen->saveRowPlacementDirection(BScreen::LEFTRIGHT);
} else
screen->saveRowPlacementDirection(BScreen::LEFTRIGHT);
sprintf(name_lookup, "session.screen%d.colPlacementDirection", screen_number);
sprintf(class_lookup, "Session.Screen%d.ColPlacementDirection", screen_number);
if (XrmGetResource(*database, name_lookup, class_lookup, &value_type,
&value)) {
if (! strncasecmp(value.addr, "bottomtotop", value.size))
screen->saveColPlacementDirection(BScreen::BOTTOMTOP);
else
screen->saveColPlacementDirection(BScreen::TOPBOTTOM);
} else
screen->saveColPlacementDirection(BScreen::TOPBOTTOM);
screen->removeWorkspaceNames();
sprintf(name_lookup, "session.screen%d.workspaceNames", screen_number);
sprintf(class_lookup, "Session.Screen%d.WorkspaceNames", screen_number);
if (XrmGetResource(*database, name_lookup, class_lookup, &value_type,
&value)) {
#ifdef DEBUG
2002-12-01 13:42:15 +00:00
cerr<<__FILE__<<"("<<__LINE__<<"): Workspaces="<<screen->getNumberOfWorkspaces()<<endl;
#endif // DEBUG
2002-12-01 13:42:15 +00:00
char *search = StringUtil::strdup(value.addr);
2002-12-01 13:42:15 +00:00
int i;
for (i = 0; i < screen->getNumberOfWorkspaces(); i++) {
char *nn;
2002-12-01 13:42:15 +00:00
if (! i) nn = strtok(search, ",");
else nn = strtok(0, ",");
2002-12-01 13:42:15 +00:00
if (nn)
screen->addWorkspaceName(nn);
else break;
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
}
delete [] search;
}
sprintf(name_lookup, "session.screen%d.windowPlacement", screen_number);
sprintf(class_lookup, "Session.Screen%d.WindowPlacement", screen_number);
if (XrmGetResource(*database, name_lookup, class_lookup, &value_type,
&value)) {
if (! strncasecmp(value.addr, "RowSmartPlacement", value.size))
screen->savePlacementPolicy(BScreen::ROWSMARTPLACEMENT);
else if (! strncasecmp(value.addr, "ColSmartPlacement", value.size))
screen->savePlacementPolicy(BScreen::COLSMARTPLACEMENT);
else
screen->savePlacementPolicy(BScreen::CASCADEPLACEMENT);
} else
screen->savePlacementPolicy(BScreen::ROWSMARTPLACEMENT);
#ifdef SLIT
sprintf(name_lookup, "session.screen%d.slit.placement", screen_number);
sprintf(class_lookup, "Session.Screen%d.Slit.Placement", screen_number);
if (XrmGetResource(*database, name_lookup, class_lookup, &value_type,
&value)) {
if (! strncasecmp(value.addr, "TopLeft", value.size))
screen->saveSlitPlacement(Slit::TOPLEFT);
else if (! strncasecmp(value.addr, "CenterLeft", value.size))
screen->saveSlitPlacement(Slit::CENTERLEFT);
else if (! strncasecmp(value.addr, "BottomLeft", value.size))
screen->saveSlitPlacement(Slit::BOTTOMLEFT);
else if (! strncasecmp(value.addr, "TopCenter", value.size))
screen->saveSlitPlacement(Slit::TOPCENTER);
else if (! strncasecmp(value.addr, "BottomCenter", value.size))
screen->saveSlitPlacement(Slit::BOTTOMCENTER);
else if (! strncasecmp(value.addr, "TopRight", value.size))
screen->saveSlitPlacement(Slit::TOPRIGHT);
else if (! strncasecmp(value.addr, "BottomRight", value.size))
screen->saveSlitPlacement(Slit::BOTTOMRIGHT);
else
screen->saveSlitPlacement(Slit::CENTERRIGHT);
} else
screen->saveSlitPlacement(Slit::CENTERRIGHT);
sprintf(name_lookup, "session.screen%d.slit.direction", screen_number);
sprintf(class_lookup, "Session.Screen%d.Slit.Direction", screen_number);
if (XrmGetResource(*database, name_lookup, class_lookup, &value_type,
&value)) {
if (! strncasecmp(value.addr, "Horizontal", value.size))
screen->saveSlitDirection(Slit::HORIZONTAL);
else
screen->saveSlitDirection(Slit::VERTICAL);
} else
screen->saveSlitDirection(Slit::VERTICAL);
sprintf(name_lookup, "session.screen%d.slit.autoHide", screen_number);
sprintf(class_lookup, "Session.Screen%d.Slit.AutoHide", screen_number);
if (XrmGetResource(*database, name_lookup, class_lookup, &value_type,
&value)) {
if (! strncasecmp(value.addr, "True", value.size))
screen->saveSlitAutoHide(True);
else
screen->saveSlitAutoHide(False);
} else
screen->saveSlitAutoHide(False);
/*
#ifdef XINERAMA
int tmp_head;
sprintf(name_lookup, "session.screen%d.slit.onHead", screen_number);
sprintf(class_lookup, "Session.Screen%d.Slit.OnHead", screen_number);
if (XrmGetResource(*database, name_lookup, class_lookup, &value_type,
&value)) {
if (sscanf(value.addr, "%d", &tmp_head) != 1)
tmp_head = 0;
} else
tmp_head = 0;
screen->saveSlitOnHead(tmp_head);
#endif // XINERAMA
*/
#endif // SLIT
#ifdef HAVE_STRFTIME
2002-12-01 13:42:15 +00:00
sprintf(name_lookup, "session.screen%d.strftimeFormat", screen_number);
sprintf(class_lookup, "Session.Screen%d.StrftimeFormat", screen_number);
if (XrmGetResource(*database, name_lookup, class_lookup, &value_type,
&value))
screen->saveStrftimeFormat(value.addr);
else
screen->saveStrftimeFormat("%I:%M %p");
#else // HAVE_STRFTIME
2002-12-01 13:42:15 +00:00
sprintf(name_lookup, "session.screen%d.dateFormat", screen_number);
sprintf(class_lookup, "Session.Screen%d.DateFormat", screen_number);
if (XrmGetResource(*database, name_lookup, class_lookup, &value_type,
&value)) {
if (strncasecmp(value.addr, "european", value.size))
screen->saveDateFormat(B_AMERICANDATE);
2002-12-01 13:42:15 +00:00
else
screen->saveDateFormat(B_EUROPEANDATE);
2002-12-01 13:42:15 +00:00
} else
screen->saveDateFormat(B_AMERICANDATE);
2002-12-01 13:42:15 +00:00
sprintf(name_lookup, "session.screen%d.clockFormat", screen_number);
sprintf(class_lookup, "Session.Screen%d.ClockFormat", screen_number);
if (XrmGetResource(*database, name_lookup, class_lookup, &value_type,
&value)) {
int clock;
if (sscanf(value.addr, "%d", &clock) != 1)
screen->saveClock24Hour(False);
else if (clock == 24)
screen->saveClock24Hour(True);
else
screen->saveClock24Hour(False);
} else
screen->saveClock24Hour(False);
2001-12-11 20:47:02 +00:00
#endif // HAVE_STRFTIME
2002-12-01 13:42:15 +00:00
//check size on toolbarwidth percent
if (screen->getToolbarWidthPercent() <= 0 ||
screen->getToolbarWidthPercent() > 100)
screen->saveToolbarWidthPercent(66);
2003-04-14 15:28:52 +00:00
2001-12-11 20:47:02 +00:00
}
void Fluxbox::loadRootCommand(BScreen *screen) {
2002-01-11 09:26:33 +00:00
2002-12-01 13:42:15 +00:00
string dbfile(getRcFilename());
2002-12-02 23:49:56 +00:00
XrmDatabaseHelper database(dbfile.c_str());
if (!*database)
2002-12-01 13:42:15 +00:00
database = XrmGetFileDatabase(DEFAULT_INITFILE);
XrmValue value;
char *value_type, name_lookup[1024], class_lookup[1024];
sprintf(name_lookup, "session.screen%d.rootCommand", screen->getScreenNumber());
sprintf(class_lookup, "Session.Screen%d.RootCommand", screen->getScreenNumber());
2002-12-02 23:49:56 +00:00
if (XrmGetResource(*database, name_lookup, class_lookup, &value_type,
2002-12-01 13:42:15 +00:00
&value)) {
screen->saveRootCommand(value.addr==0 ? "": value.addr);
} else
screen->saveRootCommand("");
}
2002-01-11 09:26:33 +00:00
void Fluxbox::reload_rc() {
2002-12-01 13:42:15 +00:00
load_rc();
reconfigure();
2001-12-11 20:47:02 +00:00
}
void Fluxbox::reconfigure() {
2002-12-01 13:42:15 +00:00
reconfigure_wait = true;
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
if (! timer.isTiming())
timer.start();
2001-12-11 20:47:02 +00:00
}
void Fluxbox::real_reconfigure() {
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
XrmDatabase new_blackboxrc = (XrmDatabase) 0;
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
string dbfile(getRcFilename());
XrmDatabase old_blackboxrc = XrmGetFileDatabase(dbfile.c_str());
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
XrmMergeDatabases(new_blackboxrc, &old_blackboxrc);
XrmPutFileDatabase(old_blackboxrc, dbfile.c_str());
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
if (old_blackboxrc)
XrmDestroyDatabase(old_blackboxrc);
std::list<MenuTimestamp *>::iterator it = menuTimestamps.begin();
std::list<MenuTimestamp *>::iterator it_end = menuTimestamps.end();
for (; it != it_end; ++it) {
MenuTimestamp *ts = *it;
if (ts) {
if (ts->filename)
delete [] ts->filename;
delete ts;
}
}
menuTimestamps.erase(menuTimestamps.begin(), menuTimestamps.end());
ScreenList::iterator sit = screenList.begin();
ScreenList::iterator sit_end = screenList.end();
for (; sit != sit_end; ++sit)
(*sit)->reconfigure();
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
//reconfigure keys
key->reconfigure(StringUtil::expandFilename(*m_rc_keyfile).c_str());
2001-12-11 20:47:02 +00:00
}
void Fluxbox::checkMenu() {
2002-12-01 13:42:15 +00:00
Bool reread = False;
std::list<MenuTimestamp *>::iterator it = menuTimestamps.begin();
std::list<MenuTimestamp *>::iterator it_end = menuTimestamps.end();
for (; it != it_end && (! reread); ++it) {
struct stat buf;
if (! stat((*it)->filename, &buf)) {
if ((*it)->timestamp != buf.st_ctime)
reread = True;
} else
reread = True;
}
if (reread) rereadMenu();
2001-12-11 20:47:02 +00:00
}
void Fluxbox::rereadMenu() {
2002-12-01 13:42:15 +00:00
reread_menu_wait = True;
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
if (! timer.isTiming()) timer.start();
2001-12-11 20:47:02 +00:00
}
void Fluxbox::real_rereadMenu() {
2002-12-01 13:42:15 +00:00
std::list<MenuTimestamp *>::iterator it = menuTimestamps.begin();
std::list<MenuTimestamp *>::iterator it_end = menuTimestamps.end();
for (; it != it_end; ++it) {
MenuTimestamp *ts = *it;
if (ts) {
if (ts->filename)
delete [] ts->filename;
delete ts;
}
}
menuTimestamps.erase(menuTimestamps.begin(), menuTimestamps.end());
ScreenList::iterator sit = screenList.begin();
ScreenList::iterator sit_end = screenList.end();
for (; sit != sit_end; ++sit) {
(*sit)->rereadMenu();
}
2001-12-11 20:47:02 +00:00
}
void Fluxbox::saveMenuFilename(const char *filename) {
2002-12-01 13:42:15 +00:00
Bool found = False;
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
std::list<MenuTimestamp *>::iterator it = menuTimestamps.begin();
std::list<MenuTimestamp *>::iterator it_end = menuTimestamps.end();
for (; it != it_end; ++it) {
if (! strcmp((*it)->filename, filename)) found = True;
}
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
if (! found) {
struct stat buf;
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
if (! stat(filename, &buf)) {
MenuTimestamp *ts = new MenuTimestamp;
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
ts->filename = StringUtil::strdup(filename);
ts->timestamp = buf.st_ctime;
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
menuTimestamps.push_back(ts);
}
}
2001-12-11 20:47:02 +00:00
}
void Fluxbox::timeout() {
2002-12-01 13:42:15 +00:00
if (reconfigure_wait)
real_reconfigure();
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
if (reread_menu_wait)
real_rereadMenu();
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
reconfigure_wait = reread_menu_wait = false;
2001-12-11 20:47:02 +00:00
}
// set focused window
2001-12-11 20:47:02 +00:00
void Fluxbox::setFocusedWindow(FluxboxWindow *win) {
2002-12-01 13:42:15 +00:00
BScreen *old_screen = 0, *screen = 0;
FluxboxWindow *old_win = 0;
Toolbar *old_tbar = 0, *tbar = 0;
Workspace *old_wkspc = 0, *wkspc = 0;
if (focused_window != 0) {
old_win = focused_window;
2003-04-14 15:28:52 +00:00
old_screen = &old_win->getScreen();
2002-12-01 13:42:15 +00:00
old_tbar = old_screen->getToolbar();
old_wkspc = old_screen->getWorkspace(old_win->getWorkspaceNumber());
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
old_win->setFocusFlag(False);
old_wkspc->menu().setItemSelected(old_win->getWindowNumber(), false);
}
if (win && ! win->isIconic()) {
// make sure we have a valid win pointer with a valid screen
ScreenList::iterator winscreen =
std::find(screenList.begin(), screenList.end(),
2003-04-14 15:28:52 +00:00
&win->getScreen());
2002-12-01 13:42:15 +00:00
if (winscreen == screenList.end()) {
focused_window = 0; // the window pointer wasn't valid, mark no window focused
} else {
screen = *winscreen;
tbar = screen->getToolbar();
wkspc = screen->getWorkspace(win->getWorkspaceNumber());
focused_window = win; // update focused window
win->setFocusFlag(True); // set focus flag
// select this window in workspace menu
2003-04-14 15:28:52 +00:00
if (wkspc != 0)
wkspc->menu().setItemSelected(win->getWindowNumber(), true);
2002-12-01 13:42:15 +00:00
}
} else
focused_window = 0;
if (tbar != 0)
tbar->redrawWindowLabel(True);
if (screen != 0)
screen->updateNetizenWindowFocus();
if (old_tbar && old_tbar != tbar)
old_tbar->redrawWindowLabel(True);
if (old_screen && old_screen != screen)
old_screen->updateNetizenWindowFocus();
2001-12-11 20:47:02 +00:00
}
void Fluxbox::watchKeyRelease(BScreen *screen, unsigned int mods) {
watching_screen = screen;
watch_keyrelease = mods;
XGrabKeyboard(getXDisplay(),screen->getRootWindow(), True,
GrabModeAsync, GrabModeAsync, CurrentTime);
}