2002-01-09 14:07:09 +00:00
|
|
|
// 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)
|
2002-01-08 00:29:12 +00:00
|
|
|
//
|
2001-12-11 20:47:02 +00:00
|
|
|
// blackbox.cc for blackbox - an X11 Window manager
|
2003-01-09 18:32:09 +00:00
|
|
|
// Copyright (c) 1997 - 2000 Brad Hughes (bhughes at tcac.net)
|
2001-12-11 20:47:02 +00:00
|
|
|
//
|
|
|
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
|
|
|
// copy of this software and associated documentation files (the "Software"),
|
|
|
|
// to deal in the Software without restriction, including without limitation
|
|
|
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
|
|
// and/or sell copies of the Software, and to permit persons to whom the
|
|
|
|
// Software is furnished to do so, subject to the following conditions:
|
|
|
|
//
|
|
|
|
// The above copyright notice and this permission notice shall be included in
|
|
|
|
// all copies or substantial portions of the Software.
|
|
|
|
//
|
|
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
2003-01-09 18:32:09 +00:00
|
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
2001-12-11 20:47:02 +00:00
|
|
|
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
|
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
|
|
// DEALINGS IN THE SOFTWARE.
|
|
|
|
|
2003-08-10 12:50:04 +00:00
|
|
|
// $Id: fluxbox.cc,v 1.179 2003/08/10 12:50:04 rathnor Exp $
|
2002-01-09 14:07:09 +00:00
|
|
|
|
2002-08-13 21:19:00 +00:00
|
|
|
#include "fluxbox.hh"
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2003-06-12 14:32:08 +00:00
|
|
|
#include "I18n.hh"
|
2001-12-11 20:47:02 +00:00
|
|
|
#include "Screen.hh"
|
|
|
|
#include "Window.hh"
|
|
|
|
#include "Workspace.hh"
|
2002-01-06 11:07:42 +00:00
|
|
|
#include "StringUtil.hh"
|
2002-01-18 01:23:54 +00:00
|
|
|
#include "Resource.hh"
|
2002-01-20 02:19:16 +00:00
|
|
|
#include "XrmDatabaseHelper.hh"
|
2002-09-07 20:25:39 +00:00
|
|
|
#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"
|
2003-04-15 12:22:52 +00:00
|
|
|
#include "Keys.hh"
|
|
|
|
#include "FbAtoms.hh"
|
2003-06-30 20:37:57 +00:00
|
|
|
#include "defaults.hh"
|
2003-05-12 04:23:31 +00:00
|
|
|
|
2002-08-13 21:19:00 +00:00
|
|
|
//Use GNU extensions
|
|
|
|
#ifndef _GNU_SOURCE
|
|
|
|
#define _GNU_SOURCE
|
|
|
|
#endif // _GNU_SOURCE
|
|
|
|
|
2003-01-09 18:32:09 +00:00
|
|
|
#ifdef HAVE_CONFIG_H
|
2003-05-07 23:17:38 +00:00
|
|
|
#include "config.h"
|
2002-08-13 21:19:00 +00:00
|
|
|
#endif // HAVE_CONFIG_H
|
|
|
|
|
2002-10-25 21:17:15 +00:00
|
|
|
#ifdef SLIT
|
|
|
|
#include "Slit.hh"
|
|
|
|
#endif // SLIT
|
|
|
|
#ifdef USE_GNOME
|
|
|
|
#include "Gnome.hh"
|
|
|
|
#endif // USE_GNOME
|
|
|
|
#ifdef USE_NEWWMSPEC
|
|
|
|
#include "Ewmh.hh"
|
2003-04-26 05:42:36 +00:00
|
|
|
#endif // USE_NEWWMSPEC
|
|
|
|
#ifdef REMEMBER
|
|
|
|
#include "Remember.hh"
|
|
|
|
#endif // REMEMBER
|
2003-06-25 13:07:34 +00:00
|
|
|
#ifdef USE_TOOLBAR
|
|
|
|
#include "Toolbar.hh"
|
|
|
|
#include "ToolbarHandler.hh"
|
|
|
|
#endif // USE_TOOLBAR
|
2002-10-25 21:17:15 +00:00
|
|
|
|
2002-08-17 22:14:00 +00:00
|
|
|
// X headers
|
2002-01-06 11:07:42 +00:00
|
|
|
#include <X11/Xlib.h>
|
|
|
|
#include <X11/Xutil.h>
|
|
|
|
#include <X11/Xresource.h>
|
|
|
|
#include <X11/Xatom.h>
|
|
|
|
#include <X11/keysym.h>
|
2003-06-12 14:32:08 +00:00
|
|
|
|
2003-05-12 04:23:31 +00:00
|
|
|
// X extensions
|
2002-08-02 13:00:23 +00:00
|
|
|
#ifdef SHAPE
|
2002-01-06 11:07:42 +00:00
|
|
|
#include <X11/extensions/shape.h>
|
|
|
|
#endif // SHAPE
|
2003-05-12 04:23:31 +00:00
|
|
|
#ifdef HAVE_RANDR
|
|
|
|
#include <X11/extensions/Xrandr.h>
|
|
|
|
#endif // HAVE_RANDR
|
|
|
|
|
|
|
|
// system headers
|
2002-01-06 11:07:42 +00:00
|
|
|
|
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
|
|
|
|
|
2002-08-02 13:00:23 +00:00
|
|
|
#ifdef HAVE_SYS_SELECT_H
|
|
|
|
#include <sys/select.h>
|
2001-12-11 20:47:02 +00:00
|
|
|
#endif // HAVE_SYS_SELECT_H
|
|
|
|
|
2003-05-11 22:19:17 +00:00
|
|
|
#ifdef HAVE_SYS_STAT_H
|
2002-10-25 21:17:15 +00:00
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
2001-12-11 20:47:02 +00:00
|
|
|
#endif // HAVE_SYS_STAT_H
|
|
|
|
|
2003-05-11 22:19:17 +00:00
|
|
|
#ifdef TIME_WITH_SYS_TIME
|
2002-10-25 21:17:15 +00:00
|
|
|
#include <sys/time.h>
|
|
|
|
#include <time.h>
|
2001-12-11 20:47:02 +00:00
|
|
|
#else // !TIME_WITH_SYS_TIME
|
2003-05-11 22:19:17 +00:00
|
|
|
#ifdef HAVE_SYS_TIME_H
|
2002-10-25 21:17:15 +00:00
|
|
|
#include <sys/time.h>
|
|
|
|
#else // !HAVE_SYS_TIME_H
|
|
|
|
#include <time.h>
|
|
|
|
#endif // HAVE_SYS_TIME_H
|
2001-12-11 20:47:02 +00:00
|
|
|
#endif // TIME_WITH_SYS_TIME
|
|
|
|
|
2003-05-11 22:19:17 +00:00
|
|
|
#ifdef HAVE_LIBGEN_H
|
|
|
|
#include <libgen.h>
|
2001-12-11 20:47:02 +00:00
|
|
|
#endif // HAVE_LIBGEN_H
|
|
|
|
|
2002-08-14 00:01:10 +00:00
|
|
|
#include <sys/wait.h>
|
|
|
|
|
2001-12-11 20:47:02 +00:00
|
|
|
#include <iostream>
|
|
|
|
#include <string>
|
2002-01-09 15:08:22 +00:00
|
|
|
#include <memory>
|
2002-07-14 01:00:23 +00:00
|
|
|
#include <algorithm>
|
2002-09-07 20:25:39 +00:00
|
|
|
#include <typeinfo>
|
2002-01-20 02:19:16 +00:00
|
|
|
|
2002-01-08 00:29:12 +00:00
|
|
|
using namespace std;
|
2002-08-14 00:01:10 +00:00
|
|
|
using namespace FbTk;
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2002-01-18 01:23:54 +00:00
|
|
|
#ifndef HAVE_BASENAME
|
2002-08-02 13:00:23 +00:00
|
|
|
namespace {
|
|
|
|
|
2003-06-18 13:51:37 +00:00
|
|
|
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
|
|
|
}
|
2002-08-14 23:03:07 +00:00
|
|
|
|
|
|
|
}; // end anonymous namespace
|
2002-08-02 13:00:23 +00:00
|
|
|
|
2001-12-11 20:47:02 +00:00
|
|
|
#endif // HAVE_BASENAME
|
|
|
|
|
2002-01-18 01:23:54 +00:00
|
|
|
//-----------------------------------------------------------------
|
|
|
|
//---- accessors for int, bool, and some enums with Resource ------
|
|
|
|
//-----------------------------------------------------------------
|
2003-05-18 22:04:06 +00:00
|
|
|
|
2002-01-18 01:23:54 +00:00
|
|
|
template<>
|
2003-05-18 22:04:06 +00:00
|
|
|
void FbTk::Resource<int>::
|
2002-01-18 01:23:54 +00:00
|
|
|
setFromString(const char* strval) {
|
2002-12-01 13:42:15 +00:00
|
|
|
int val;
|
|
|
|
if (sscanf(strval, "%d", &val)==1)
|
|
|
|
*this = val;
|
2002-01-18 01:23:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template<>
|
2003-05-18 22:04:06 +00:00
|
|
|
void FbTk::Resource<std::string>::
|
2002-01-18 01:23:54 +00:00
|
|
|
setFromString(const char *strval) {
|
2002-12-01 13:42:15 +00:00
|
|
|
*this = strval;
|
2002-01-18 01:23:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template<>
|
2003-05-18 22:04:06 +00:00
|
|
|
void FbTk::Resource<bool>::
|
2002-01-18 01:23:54 +00:00
|
|
|
setFromString(char const *strval) {
|
2002-12-01 13:42:15 +00:00
|
|
|
if (strcasecmp(strval, "true")==0)
|
|
|
|
*this = true;
|
|
|
|
else
|
|
|
|
*this = false;
|
2002-01-18 01:23:54 +00:00
|
|
|
}
|
|
|
|
|
2003-02-22 15:10:43 +00:00
|
|
|
template<>
|
2003-05-18 22:04:06 +00:00
|
|
|
void FbTk::Resource<Fluxbox::FocusModel>::
|
2003-02-22 15:10:43 +00:00
|
|
|
setFromString(char const *strval) {
|
2003-02-22 16:09:44 +00:00
|
|
|
// 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)
|
2003-02-22 15:10:43 +00:00
|
|
|
m_value = Fluxbox::SLOPPYFOCUS;
|
2003-02-22 16:09:44 +00:00
|
|
|
else if (strcasecmp(strval, "SemiSloppyFocus") == 0
|
|
|
|
|| strcasecmp(strval, "AutoRaiseSemiSloppyFocus") == 0)
|
2003-02-22 15:10:43 +00:00
|
|
|
m_value = Fluxbox::SEMISLOPPYFOCUS;
|
|
|
|
else if (strcasecmp(strval, "ClickToFocus") == 0)
|
|
|
|
m_value = Fluxbox::CLICKTOFOCUS;
|
|
|
|
else
|
|
|
|
setDefaultValue();
|
|
|
|
}
|
|
|
|
|
2002-01-18 01:23:54 +00:00
|
|
|
template<>
|
2003-05-18 22:04:06 +00:00
|
|
|
void FbTk::Resource<Fluxbox::TitlebarList>::
|
2002-01-18 01:23:54 +00:00
|
|
|
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-01-18 01:23:54 +00:00
|
|
|
|
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);
|
|
|
|
}
|
2002-01-18 01:23:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template<>
|
2003-05-18 22:04:06 +00:00
|
|
|
void FbTk::Resource<unsigned int>::
|
2002-01-18 01:23:54 +00:00
|
|
|
setFromString(const char *strval) {
|
2002-12-01 13:42:15 +00:00
|
|
|
if (sscanf(strval, "%ul", &m_value) != 1)
|
|
|
|
setDefaultValue();
|
2002-01-18 01:23:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------
|
|
|
|
//---- manipulators for int, bool, and some enums with Resource ---
|
|
|
|
//-----------------------------------------------------------------
|
|
|
|
template<>
|
2003-05-18 22:04:06 +00:00
|
|
|
std::string FbTk::Resource<bool>::
|
2002-01-18 01:23:54 +00:00
|
|
|
getString() {
|
2002-12-01 13:42:15 +00:00
|
|
|
return std::string(**this == true ? "true" : "false");
|
2002-01-18 01:23:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template<>
|
2003-05-18 22:04:06 +00:00
|
|
|
std::string FbTk::Resource<int>::
|
2002-01-18 01:23:54 +00:00
|
|
|
getString() {
|
2002-12-01 13:42:15 +00:00
|
|
|
char strval[256];
|
|
|
|
sprintf(strval, "%d", **this);
|
|
|
|
return std::string(strval);
|
2002-01-18 01:23:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template<>
|
2003-05-18 22:04:06 +00:00
|
|
|
std::string FbTk::Resource<std::string>::
|
2002-01-18 01:23:54 +00:00
|
|
|
getString() { return **this; }
|
|
|
|
|
2003-02-22 15:10:43 +00:00
|
|
|
template<>
|
2003-05-18 22:04:06 +00:00
|
|
|
std::string FbTk::Resource<Fluxbox::FocusModel>::
|
2003-02-22 15:10:43 +00:00
|
|
|
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");
|
|
|
|
}
|
|
|
|
|
2002-01-18 01:23:54 +00:00
|
|
|
template<>
|
2003-05-18 22:04:06 +00:00
|
|
|
std::string FbTk::Resource<Fluxbox::TitlebarList>::
|
2002-01-18 01:23:54 +00:00
|
|
|
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
|
|
|
}
|
|
|
|
|
2002-01-18 01:23:54 +00:00
|
|
|
template<>
|
2003-05-18 22:04:06 +00:00
|
|
|
string FbTk::Resource<unsigned int>::
|
2002-01-18 01:23:54 +00:00
|
|
|
getString() {
|
2002-12-01 13:42:15 +00:00
|
|
|
char tmpstr[128];
|
|
|
|
sprintf(tmpstr, "%ul", m_value);
|
|
|
|
return string(tmpstr);
|
2002-01-18 01:23:54 +00:00
|
|
|
}
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2003-02-18 15:11:12 +00:00
|
|
|
template<>
|
2003-05-18 22:04:06 +00:00
|
|
|
void FbTk::Resource<Fluxbox::Layer>::
|
2003-02-18 15:11:12 +00:00
|
|
|
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<>
|
2003-05-18 22:04:06 +00:00
|
|
|
string FbTk::Resource<Fluxbox::Layer>::
|
2003-02-18 15:11:12 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-05-10 14:32:35 +00:00
|
|
|
static Window last_bad_window = None;
|
|
|
|
|
|
|
|
|
|
|
|
static int handleXErrors(Display *d, XErrorEvent *e) {
|
|
|
|
#ifdef DEBUG
|
2003-05-14 12:10:54 +00:00
|
|
|
/*
|
2003-05-10 14:32:35 +00:00
|
|
|
char errtxt[128];
|
2003-05-11 15:24:09 +00:00
|
|
|
|
2003-05-10 14:32:35 +00:00
|
|
|
XGetErrorText(d, e->error_code, errtxt, 128);
|
2003-05-11 15:24:09 +00:00
|
|
|
cerr<<"Fluxbox: X Error: "<<errtxt<<"("<<(int)e->error_code<<") opcodes "<<
|
|
|
|
(int)e->request_code<<"/"<<(int)e->minor_code<<" resource 0x"<<hex<<(int)e->resourceid<<dec<<endl;
|
2003-05-14 12:10:54 +00:00
|
|
|
*/
|
2003-05-10 14:32:35 +00:00
|
|
|
#endif // !DEBUG
|
|
|
|
|
|
|
|
if (e->error_code == BadWindow)
|
|
|
|
last_bad_window = e->resourceid;
|
|
|
|
|
|
|
|
return False;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-12-11 20:47:02 +00:00
|
|
|
//static singleton var
|
2003-04-25 16:00:03 +00:00
|
|
|
Fluxbox *Fluxbox::s_singleton=0;
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2002-03-01 15:28:56 +00:00
|
|
|
//default values for titlebar left and right
|
|
|
|
//don't forget to change last value in m_rc_titlebar_* if you add more to these
|
2003-04-25 16:00:03 +00:00
|
|
|
Fluxbox::Titlebar Fluxbox::s_titlebar_left[] = {STICK};
|
|
|
|
Fluxbox::Titlebar Fluxbox::s_titlebar_right[] = {MINIMIZE, MAXIMIZE, CLOSE};
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2003-04-25 16:00:03 +00:00
|
|
|
Fluxbox::Fluxbox(int argc, char **argv, const char *dpy_name, const char *rcfilename)
|
2003-05-10 14:32:35 +00:00
|
|
|
: FbTk::App(dpy_name),
|
2003-04-15 12:22:52 +00:00
|
|
|
m_fbatoms(new FbAtoms()),
|
2003-07-18 15:40:55 +00:00
|
|
|
m_resourcemanager(rcfilename, true),
|
|
|
|
// TODO: shouldn't need a separate one for screen
|
|
|
|
m_screen_rm(m_resourcemanager),
|
2002-12-01 13:42:15 +00:00
|
|
|
m_rc_tabs(m_resourcemanager, true, "session.tabs", "Session.Tabs"),
|
2003-05-04 16:55:40 +00:00
|
|
|
m_rc_ignoreborder(m_resourcemanager, false, "session.ignoreBorder", "Session.IgnoreBorder"),
|
2003-04-25 16:00:03 +00:00
|
|
|
m_rc_colors_per_channel(m_resourcemanager, 4,
|
|
|
|
"session.colorsPerChannel", "Session.ColorsPerChannel"),
|
2003-02-02 16:32:41 +00:00
|
|
|
m_rc_numlayers(m_resourcemanager, 13, "session.numLayers", "Session.NumLayers"),
|
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"),
|
2003-04-25 16:00:03 +00:00
|
|
|
m_rc_titlebar_left(m_resourcemanager,
|
|
|
|
TitlebarList(&s_titlebar_left[0], &s_titlebar_left[1]),
|
|
|
|
"session.titlebar.left", "Session.Titlebar.Left"),
|
|
|
|
m_rc_titlebar_right(m_resourcemanager,
|
|
|
|
TitlebarList(&s_titlebar_right[0], &s_titlebar_right[3]),
|
|
|
|
"session.titlebar.right", "Session.Titlebar.Right"),
|
2002-12-01 13:42:15 +00:00
|
|
|
m_rc_cache_life(m_resourcemanager, 5, "session.cacheLife", "Session.CacheLife"),
|
|
|
|
m_rc_cache_max(m_resourcemanager, 200, "session.cacheMax", "Session.CacheMax"),
|
2003-04-25 16:00:03 +00:00
|
|
|
m_focused_window(0), m_masked_window(0),
|
|
|
|
m_timer(this),
|
2003-06-30 15:05:26 +00:00
|
|
|
m_mousescreen(0),
|
|
|
|
m_keyscreen(0),
|
2003-04-25 16:00:03 +00:00
|
|
|
m_watching_screen(0), m_watch_keyrelease(0),
|
|
|
|
m_last_time(0),
|
|
|
|
m_masked(0),
|
|
|
|
m_rc_file(rcfilename ? rcfilename : ""),
|
2003-05-10 14:32:35 +00:00
|
|
|
m_argv(argv), m_argc(argc),
|
|
|
|
m_starting(true),
|
|
|
|
m_shutdown(false),
|
2003-05-11 22:19:17 +00:00
|
|
|
m_server_grabs(0),
|
2003-05-12 04:23:31 +00:00
|
|
|
m_randr_event_type(0),
|
2003-05-11 22:19:17 +00:00
|
|
|
m_RC_PATH("fluxbox"),
|
2003-07-27 13:53:34 +00:00
|
|
|
m_RC_INIT_FILE("init") {
|
2003-04-25 16:00:03 +00:00
|
|
|
|
|
|
|
|
2003-05-13 11:43:44 +00:00
|
|
|
if (s_singleton != 0)
|
|
|
|
throw string("Fatal! There can only one instance of fluxbox class.");
|
|
|
|
|
|
|
|
if (display() == 0) {
|
|
|
|
//!! TODO: NLS
|
|
|
|
throw string("Can not connect to X server.\n"
|
|
|
|
"Make sure you started X before you start Fluxbox.");
|
2002-12-01 13:42:15 +00:00
|
|
|
}
|
2003-07-27 13:53:34 +00:00
|
|
|
// For KDE dock applets
|
|
|
|
// KDE v1.x
|
|
|
|
m_kwm1_dockwindow = XInternAtom(FbTk::App::instance()->display(),
|
|
|
|
"KWM_DOCKWINDOW", False);
|
|
|
|
// KDE v2.x
|
|
|
|
m_kwm2_dockwindow = XInternAtom(FbTk::App::instance()->display(),
|
|
|
|
"_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR", False);
|
2003-05-10 14:32:35 +00:00
|
|
|
// setup X error handler
|
|
|
|
XSetErrorHandler((XErrorHandler) handleXErrors);
|
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
//catch system signals
|
2003-06-11 14:53:54 +00:00
|
|
|
SignalHandler &sigh = SignalHandler::instance();
|
2003-05-13 11:43:44 +00:00
|
|
|
sigh.registerHandler(SIGSEGV, this);
|
|
|
|
sigh.registerHandler(SIGFPE, this);
|
|
|
|
sigh.registerHandler(SIGTERM, this);
|
|
|
|
sigh.registerHandler(SIGINT, this);
|
|
|
|
sigh.registerHandler(SIGCHLD, this);
|
|
|
|
sigh.registerHandler(SIGHUP, this);
|
|
|
|
sigh.registerHandler(SIGUSR1, this);
|
|
|
|
sigh.registerHandler(SIGUSR2, this);
|
|
|
|
|
2003-04-25 16:00:03 +00:00
|
|
|
Display *disp = FbTk::App::instance()->display();
|
2002-12-01 13:42:15 +00:00
|
|
|
|
2003-04-25 16:00:03 +00:00
|
|
|
s_singleton = this;
|
2003-05-14 14:37:06 +00:00
|
|
|
m_have_shape = false;
|
|
|
|
m_shape_eventbase = 0;
|
|
|
|
#ifdef SHAPE
|
|
|
|
int shape_err;
|
|
|
|
m_have_shape = XShapeQueryExtension(disp, &m_shape_eventbase, &shape_err);
|
|
|
|
#endif // SHAPE
|
2002-12-01 13:42:15 +00:00
|
|
|
|
2003-05-12 04:23:31 +00:00
|
|
|
#ifdef HAVE_RANDR
|
|
|
|
// get randr event type
|
|
|
|
int error_base;
|
|
|
|
XRRQueryExtension(disp, &m_randr_event_type, &error_base);
|
|
|
|
#endif // HAVE_RANDR
|
|
|
|
|
2003-07-18 15:40:55 +00:00
|
|
|
load_rc();
|
|
|
|
|
2003-04-25 16:00:03 +00:00
|
|
|
// setup atom handlers before we create any windows
|
2002-10-25 21:17:15 +00:00
|
|
|
#ifdef USE_GNOME
|
2003-04-25 16:00:03 +00:00
|
|
|
addAtomHandler(new Gnome()); // for gnome 1 atom support
|
2002-10-25 21:17:15 +00:00
|
|
|
#endif //USE_GNOME
|
2003-04-25 16:00:03 +00:00
|
|
|
|
2002-10-25 21:17:15 +00:00
|
|
|
#ifdef USE_NEWWMSPEC
|
2003-04-25 16:00:03 +00:00
|
|
|
addAtomHandler(new Ewmh()); // for Extended window manager atom support
|
2002-10-25 21:17:15 +00:00
|
|
|
#endif // USE_NEWWMSPEC
|
2003-05-12 04:23:31 +00:00
|
|
|
|
2003-04-26 05:42:36 +00:00
|
|
|
#ifdef REMEMBER
|
2003-04-28 13:34:38 +00:00
|
|
|
addAtomHandler(new Remember()); // for remembering window attribs
|
2003-04-26 05:42:36 +00:00
|
|
|
#endif // REMEMBER
|
2002-08-18 11:01:52 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
grab();
|
2002-02-26 22:42:23 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
setupConfigFiles();
|
2002-02-26 22:42:23 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
if (! XSupportsLocale())
|
|
|
|
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
|
|
|
|
|
|
|
|
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-08-14 23:03:07 +00:00
|
|
|
#ifdef HAVE_GETPID
|
2003-04-25 16:00:03 +00:00
|
|
|
m_fluxbox_pid = XInternAtom(disp, "_BLACKBOX_PID", False);
|
2002-08-14 23:03:07 +00:00
|
|
|
#endif // HAVE_GETPID
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2003-05-10 14:32:35 +00:00
|
|
|
// Allocate screens
|
|
|
|
for (int i = 0; i < ScreenCount(display()); i++) {
|
2002-12-01 13:42:15 +00:00
|
|
|
char scrname[128], altscrname[128];
|
|
|
|
sprintf(scrname, "session.screen%d", i);
|
|
|
|
sprintf(altscrname, "session.Screen%d", i);
|
2003-07-18 15:40:55 +00:00
|
|
|
BScreen *screen = new BScreen(m_screen_rm.lock(),
|
2003-05-12 04:28:05 +00:00
|
|
|
scrname, altscrname,
|
|
|
|
i, getNumberOfLayers());
|
2002-12-01 13:42:15 +00:00
|
|
|
if (! screen->isScreenManaged()) {
|
|
|
|
delete screen;
|
|
|
|
continue;
|
|
|
|
}
|
2003-06-12 14:32:08 +00:00
|
|
|
|
|
|
|
#ifdef HAVE_GETPID
|
|
|
|
pid_t bpid = getpid();
|
|
|
|
|
|
|
|
screen->rootWindow().changeProperty(getFluxboxPidAtom(), XA_CARDINAL,
|
|
|
|
sizeof(pid_t) * 8, PropModeReplace,
|
|
|
|
(unsigned char *) &bpid, 1);
|
|
|
|
#endif // HAVE_GETPID
|
|
|
|
|
2003-05-12 04:28:05 +00:00
|
|
|
#ifdef HAVE_RANDR
|
2003-06-11 14:53:54 +00:00
|
|
|
// setup RANDR for this screens root window
|
|
|
|
// we need to determine if we should use old randr select input function or not
|
2003-05-12 11:14:47 +00:00
|
|
|
#ifdef X_RRScreenChangeSelectInput
|
|
|
|
// use old set randr event
|
|
|
|
XRRScreenChangeSelectInput(disp, screen->rootWindow().window(), True);
|
|
|
|
#else
|
2003-05-12 04:28:05 +00:00
|
|
|
XRRSelectInput(disp, screen->rootWindow().window(),
|
|
|
|
RRScreenChangeNotifyMask);
|
2003-05-12 11:14:47 +00:00
|
|
|
#endif // X_RRScreenChangeSelectInput
|
|
|
|
|
2003-05-12 04:28:05 +00:00
|
|
|
#endif // HAVE_RANDR
|
|
|
|
|
2003-06-24 18:34:52 +00:00
|
|
|
m_screen_list.push_back(screen);
|
2003-06-25 13:07:34 +00:00
|
|
|
#ifdef USE_TOOLBAR
|
2003-06-25 06:02:53 +00:00
|
|
|
m_atomhandler.push_back(new ToolbarHandler(*screen));
|
2003-06-25 13:07:34 +00:00
|
|
|
#endif // USE_TOOLBAR
|
2003-03-03 21:51:13 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
// attach screen signals to this
|
|
|
|
screen->currentWorkspaceSig().attach(this);
|
|
|
|
screen->workspaceCountSig().attach(this);
|
|
|
|
screen->workspaceNamesSig().attach(this);
|
|
|
|
screen->clientListSig().attach(this);
|
2002-09-07 20:25:39 +00:00
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
2003-06-30 15:05:26 +00:00
|
|
|
m_keyscreen = m_mousescreen = m_screen_list.front();
|
2002-12-01 13:42:15 +00:00
|
|
|
|
2003-04-25 16:00:03 +00:00
|
|
|
if (m_screen_list.size() == 0) {
|
2003-05-13 11:43:44 +00:00
|
|
|
//!! TODO: NLS
|
|
|
|
throw string("Couldn't find screens to manage.\n"
|
|
|
|
"Make sure you don't have another window manager running.");
|
2002-12-01 13:42:15 +00:00
|
|
|
}
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2003-04-25 16:00:03 +00:00
|
|
|
XSynchronize(disp, False);
|
|
|
|
XSync(disp, False);
|
|
|
|
|
|
|
|
m_reconfigure_wait = m_reread_menu_wait = false;
|
2002-03-19 00:16:44 +00:00
|
|
|
|
2003-04-25 16:00:03 +00:00
|
|
|
m_timer.setTimeout(0);
|
|
|
|
m_timer.fireOnce(true);
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2003-05-13 11:43:44 +00:00
|
|
|
// Create keybindings handler and load keys file
|
2003-04-25 16:00:03 +00:00
|
|
|
m_key.reset(new Keys(StringUtil::expandFilename(*m_rc_keyfile).c_str()));
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2003-07-18 15:40:55 +00:00
|
|
|
m_resourcemanager.unlock();
|
2002-12-01 13:42:15 +00:00
|
|
|
ungrab();
|
2003-07-18 15:40:55 +00:00
|
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
if (m_resourcemanager.lockDepth() != 0)
|
|
|
|
cerr<<"--- resource manager lockdepth = "<<m_resourcemanager.lockDepth()<<endl;
|
|
|
|
#endif //DEBUG
|
2003-05-10 14:32:35 +00:00
|
|
|
m_starting = false;
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-09-07 20:25:39 +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();
|
|
|
|
}
|
2003-05-13 00:20:49 +00:00
|
|
|
|
|
|
|
clearMenuFilenames();
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
|
2003-05-10 14:32:35 +00:00
|
|
|
void Fluxbox::eventLoop() {
|
2003-05-10 14:43:45 +00:00
|
|
|
while (!m_shutdown) {
|
2003-05-10 14:32:35 +00:00
|
|
|
if (XPending(display())) {
|
|
|
|
XEvent e;
|
|
|
|
XNextEvent(display(), &e);
|
|
|
|
|
2003-06-08 00:13:41 +00:00
|
|
|
if (last_bad_window != None && e.xany.window == last_bad_window &&
|
|
|
|
e.type != DestroyNotify) { // we must let the actual destroys through
|
2003-05-10 14:32:35 +00:00
|
|
|
#ifdef DEBUG
|
2003-05-13 11:43:44 +00:00
|
|
|
cerr<<"Fluxbox::eventLoop(): removing bad window from event queue"<<endl;
|
2003-05-10 14:32:35 +00:00
|
|
|
#endif // DEBUG
|
|
|
|
} else {
|
|
|
|
last_bad_window = None;
|
|
|
|
handleEvent(&e);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
FbTk::Timer::updateTimers(ConnectionNumber(display())); //handle all timers
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Fluxbox::validateWindow(Window window) const {
|
|
|
|
XEvent event;
|
|
|
|
if (XCheckTypedWindowEvent(display(), window, DestroyNotify, &event)) {
|
|
|
|
XPutBackEvent(display(), &event);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Fluxbox::grab() {
|
|
|
|
if (! m_server_grabs++)
|
|
|
|
XGrabServer(display());
|
|
|
|
}
|
|
|
|
|
|
|
|
void Fluxbox::ungrab() {
|
|
|
|
if (! --m_server_grabs)
|
|
|
|
XUngrabServer(display());
|
|
|
|
if (m_server_grabs < 0)
|
|
|
|
m_server_grabs = 0;
|
|
|
|
}
|
|
|
|
|
2003-04-14 15:28:52 +00:00
|
|
|
/**
|
|
|
|
setup the configutation files in
|
|
|
|
home directory
|
|
|
|
*/
|
2002-02-26 22:42:23 +00:00
|
|
|
void Fluxbox::setupConfigFiles() {
|
|
|
|
|
2003-04-25 16:00:03 +00:00
|
|
|
bool create_init = false, create_keys = false, create_menu = false;
|
2002-12-01 13:42:15 +00:00
|
|
|
|
2003-05-11 22:19:17 +00:00
|
|
|
string dirname = getenv("HOME")+string("/.")+string(m_RC_PATH) + "/";
|
2003-04-25 16:00:03 +00:00
|
|
|
string init_file, keys_file, menu_file, slitlist_file;
|
2003-05-11 22:19:17 +00:00
|
|
|
init_file = dirname + m_RC_INIT_FILE;
|
|
|
|
keys_file = dirname + "keys";
|
|
|
|
menu_file = dirname + "menu";
|
2002-12-01 13:42:15 +00:00
|
|
|
|
|
|
|
struct stat buf;
|
|
|
|
|
|
|
|
// is file/dir already there?
|
|
|
|
if (! stat(dirname.c_str(), &buf)) {
|
2002-02-26 22:42:23 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
// check if anything with those name exists, if not create new
|
2003-04-25 16:00:03 +00:00
|
|
|
if (stat(init_file.c_str(), &buf))
|
|
|
|
create_init = true;
|
|
|
|
if (stat(keys_file.c_str(), &buf))
|
|
|
|
create_keys = true;
|
|
|
|
if (stat(menu_file.c_str(), &buf))
|
|
|
|
create_menu = true;
|
2002-12-01 13:42:15 +00:00
|
|
|
|
|
|
|
} else {
|
2002-10-15 20:41:08 +00:00
|
|
|
#ifdef DEBUG
|
2002-12-01 13:42:15 +00:00
|
|
|
cerr <<__FILE__<<"("<<__LINE__<<"): Creating dir: " << dirname.c_str() << endl;
|
2002-10-15 20:41:08 +00:00
|
|
|
#endif // DEBUG
|
2002-02-26 22:42:23 +00:00
|
|
|
|
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-02-26 22:42:23 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
//mark creation of files
|
2003-04-25 16:00:03 +00:00
|
|
|
create_init = create_keys = create_menu = true;
|
2002-12-01 13:42:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// should we copy key configuraion?
|
2003-04-25 16:00:03 +00:00
|
|
|
if (create_keys) {
|
2002-12-01 13:42:15 +00:00
|
|
|
ifstream from(DEFAULTKEYSFILE);
|
2003-04-25 16:00:03 +00:00
|
|
|
ofstream to(keys_file.c_str());
|
2002-12-01 13:42:15 +00:00
|
|
|
|
|
|
|
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-02-26 22:42:23 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
} else {
|
|
|
|
cerr<<"Can't copy default keys file."<<endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// should we copy menu configuraion?
|
2003-04-25 16:00:03 +00:00
|
|
|
if (create_menu) {
|
2002-12-01 13:42:15 +00:00
|
|
|
ifstream from(DEFAULTMENU);
|
2003-04-25 16:00:03 +00:00
|
|
|
ofstream to(menu_file.c_str());
|
2002-12-01 13:42:15 +00:00
|
|
|
|
|
|
|
if (! to.good()) {
|
2003-04-25 16:00:03 +00:00
|
|
|
cerr << "Can't open " << menu_file.c_str() << "for writing" << endl;
|
2002-12-01 13:42:15 +00:00
|
|
|
} 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?
|
2003-04-25 16:00:03 +00:00
|
|
|
if (create_init) {
|
2002-12-01 13:42:15 +00:00
|
|
|
ifstream from(DEFAULT_INITFILE);
|
2003-04-25 16:00:03 +00:00
|
|
|
ofstream to(init_file.c_str());
|
2002-12-01 13:42:15 +00:00
|
|
|
|
|
|
|
if (! to.good()) {
|
2003-04-25 16:00:03 +00:00
|
|
|
cerr << "Can't open " << init_file.c_str() << "for writing" << endl;
|
2002-12-01 13:42:15 +00:00
|
|
|
} 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;
|
|
|
|
}
|
|
|
|
}
|
2002-02-26 22:42:23 +00:00
|
|
|
}
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2002-08-17 22:14:00 +00:00
|
|
|
void Fluxbox::handleEvent(XEvent * const e) {
|
2003-06-30 15:05:26 +00:00
|
|
|
m_last_event = *e;
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2003-03-22 05:13:08 +00:00
|
|
|
// it is possible (e.g. during moving) for a window
|
|
|
|
// to mask all events to go to it
|
2003-04-25 16:00:03 +00:00
|
|
|
if ((m_masked == e->xany.window) && m_masked_window) {
|
2003-03-22 05:13:08 +00:00
|
|
|
if (e->type == MotionNotify) {
|
2003-04-25 16:00:03 +00:00
|
|
|
m_last_time = e->xmotion.time;
|
|
|
|
m_masked_window->motionNotifyEvent(e->xmotion);
|
2003-03-22 05:13:08 +00:00
|
|
|
return;
|
|
|
|
} else if (e->type == ButtonRelease) {
|
2003-05-15 11:17:29 +00:00
|
|
|
e->xbutton.window = m_masked_window->fbWindow().window();
|
2003-03-22 05:13:08 +00:00
|
|
|
}
|
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);
|
2002-02-06 17:12:09 +00:00
|
|
|
break;
|
2003-04-25 16:00:03 +00:00
|
|
|
case ConfigureRequest: {
|
2003-07-28 15:06:36 +00:00
|
|
|
WinClient *winclient = (WinClient *) 0;
|
2003-04-25 16:00:03 +00:00
|
|
|
|
2003-07-28 15:06:36 +00:00
|
|
|
if ((winclient = searchWindow(e->xconfigurerequest.window))) {
|
2003-04-25 16:00:03 +00:00
|
|
|
// already handled in FluxboxWindow::handleEvent
|
|
|
|
} else {
|
|
|
|
grab();
|
|
|
|
|
|
|
|
if (validateWindow(e->xconfigurerequest.window)) {
|
|
|
|
XWindowChanges xwc;
|
|
|
|
|
|
|
|
xwc.x = e->xconfigurerequest.x;
|
|
|
|
xwc.y = e->xconfigurerequest.y;
|
|
|
|
xwc.width = e->xconfigurerequest.width;
|
|
|
|
xwc.height = e->xconfigurerequest.height;
|
|
|
|
xwc.border_width = e->xconfigurerequest.border_width;
|
|
|
|
xwc.sibling = e->xconfigurerequest.above;
|
|
|
|
xwc.stack_mode = e->xconfigurerequest.detail;
|
|
|
|
|
|
|
|
XConfigureWindow(FbTk::App::instance()->display(),
|
|
|
|
e->xconfigurerequest.window,
|
|
|
|
e->xconfigurerequest.value_mask, &xwc);
|
2002-12-01 13:42:15 +00:00
|
|
|
}
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2003-04-25 16:00:03 +00:00
|
|
|
ungrab();
|
2002-12-01 13:42:15 +00:00
|
|
|
}
|
2003-04-25 16:00:03 +00:00
|
|
|
|
|
|
|
}
|
2002-12-02 23:49:56 +00:00
|
|
|
break;
|
2003-01-05 22:41:21 +00:00
|
|
|
case MapRequest: {
|
2003-07-23 10:43:30 +00:00
|
|
|
|
2002-08-16 11:09:25 +00:00
|
|
|
#ifdef DEBUG
|
2003-01-05 22:41:21 +00:00
|
|
|
cerr<<"MapRequest for 0x"<<hex<<e->xmaprequest.window<<dec<<endl;
|
2002-08-04 15:00:50 +00:00
|
|
|
#endif // DEBUG
|
2002-12-02 23:49:56 +00:00
|
|
|
|
2003-07-28 15:06:36 +00:00
|
|
|
WinClient *winclient = searchWindow(e->xmaprequest.window);
|
|
|
|
FluxboxWindow *win = 0;
|
2003-01-05 22:41:21 +00:00
|
|
|
|
2003-07-28 15:06:36 +00:00
|
|
|
if (! winclient) {
|
2003-01-05 22:41:21 +00:00
|
|
|
//!!! TODO
|
|
|
|
BScreen *scr = searchScreen(e->xmaprequest.parent);
|
|
|
|
if (scr != 0)
|
2003-04-16 10:49:59 +00:00
|
|
|
win = scr->createWindow(e->xmaprequest.window);
|
2003-01-05 22:41:21 +00:00
|
|
|
else
|
|
|
|
cerr<<"Fluxbox Warning! Could not find screen to map window on!"<<endl;
|
2003-05-11 15:24:09 +00:00
|
|
|
|
2003-07-28 15:06:36 +00:00
|
|
|
} else {
|
|
|
|
win = winclient->fbwindow();
|
2003-01-05 22:41:21 +00:00
|
|
|
}
|
2003-07-28 15:06:36 +00:00
|
|
|
|
2003-04-25 16:00:03 +00:00
|
|
|
// we don't handle MapRequest in FluxboxWindow::handleEvent
|
2003-04-16 14:43:06 +00:00
|
|
|
if (win)
|
2003-04-16 10:49:59 +00:00
|
|
|
win->mapRequestEvent(e->xmaprequest);
|
2003-01-05 22:41:21 +00:00
|
|
|
}
|
2002-12-02 23:49:56 +00:00
|
|
|
break;
|
2003-04-27 00:36:28 +00:00
|
|
|
case MapNotify: {
|
|
|
|
// handled directly in FluxboxWindow::handleEvent
|
|
|
|
} break;
|
2002-12-01 13:42:15 +00:00
|
|
|
case UnmapNotify:
|
|
|
|
handleUnmapNotify(e->xunmap);
|
2002-02-06 17:12:09 +00:00
|
|
|
break;
|
2003-04-15 00:50:25 +00:00
|
|
|
case MappingNotify:
|
|
|
|
// Update stored modifier mapping
|
|
|
|
#ifdef DEBUG
|
|
|
|
cerr<<__FILE__<<"("<<__FUNCTION__<<"): MappingNotify"<<endl;
|
|
|
|
#endif // DEBUG
|
2003-04-25 16:00:03 +00:00
|
|
|
if (m_key.get()) {
|
|
|
|
m_key->loadModmap();
|
2003-04-15 00:50:25 +00:00
|
|
|
}
|
|
|
|
break;
|
2002-12-01 13:42:15 +00:00
|
|
|
case CreateNotify:
|
2002-08-16 11:09:25 +00:00
|
|
|
break;
|
2002-12-01 13:42:15 +00:00
|
|
|
case DestroyNotify: {
|
2003-07-28 15:06:36 +00:00
|
|
|
WinClient *winclient = searchWindow(e->xdestroywindow.window);
|
|
|
|
if (winclient != 0) {
|
|
|
|
FluxboxWindow *win = winclient->fbwindow();
|
|
|
|
if (win)
|
2003-04-14 15:28:52 +00:00
|
|
|
win->destroyNotifyEvent(e->xdestroywindow);
|
|
|
|
|
2003-07-28 15:06:36 +00:00
|
|
|
delete winclient;
|
2003-04-14 15:28:52 +00:00
|
|
|
|
2003-07-28 15:06:36 +00:00
|
|
|
if (win && win->numClients() == 0)
|
|
|
|
delete win;
|
2002-12-01 13:42:15 +00:00
|
|
|
}
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
}
|
2002-12-02 23:49:56 +00:00
|
|
|
break;
|
2003-02-22 15:10:43 +00:00
|
|
|
case MotionNotify:
|
2002-12-02 23:49:56 +00:00
|
|
|
break;
|
2003-06-18 13:51:37 +00:00
|
|
|
case PropertyNotify: {
|
2003-04-25 16:00:03 +00:00
|
|
|
m_last_time = e->xproperty.time;
|
2003-07-28 15:06:36 +00:00
|
|
|
WinClient *winclient = searchWindow(e->xproperty.window);
|
|
|
|
if (winclient == 0)
|
2003-06-18 13:51:37 +00:00
|
|
|
break;
|
|
|
|
// most of them are handled in FluxboxWindow::handleEvent
|
|
|
|
// but some special cases like ewmh propertys needs to be checked
|
2003-06-23 13:35:45 +00:00
|
|
|
for (size_t i=0; i<m_atomhandler.size(); ++i) {
|
2003-07-28 15:06:36 +00:00
|
|
|
if (m_atomhandler[i]->propertyNotify(*winclient, e->xproperty.atom))
|
2003-06-18 13:51:37 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
} break;
|
2002-12-01 13:42:15 +00:00
|
|
|
case EnterNotify: {
|
2003-04-25 16:00:03 +00:00
|
|
|
m_last_time = e->xcrossing.time;
|
2002-12-03 23:58:06 +00:00
|
|
|
BScreen *screen = 0;
|
2002-12-01 13:42:15 +00:00
|
|
|
|
|
|
|
if (e->xcrossing.mode == NotifyGrab)
|
|
|
|
break;
|
|
|
|
|
|
|
|
if ((e->xcrossing.window == e->xcrossing.root) &&
|
|
|
|
(screen = searchScreen(e->xcrossing.window))) {
|
2003-05-15 23:30:07 +00:00
|
|
|
screen->imageControl().installRootColormap();
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2003-02-22 15:10:43 +00:00
|
|
|
}
|
2002-02-06 17:12:09 +00:00
|
|
|
|
2003-04-25 16:00:03 +00:00
|
|
|
} break;
|
2002-12-01 13:42:15 +00:00
|
|
|
case LeaveNotify:
|
2003-04-25 16:00:03 +00:00
|
|
|
m_last_time = e->xcrossing.time;
|
2002-12-02 23:49:56 +00:00
|
|
|
break;
|
2002-12-01 13:42:15 +00:00
|
|
|
case Expose:
|
2003-04-25 16:00:03 +00:00
|
|
|
// handled directly in FluxboxWindow::exposeEvent
|
2002-12-02 23:49:56 +00:00
|
|
|
break;
|
2003-04-15 00:50:25 +00:00
|
|
|
case KeyRelease:
|
2002-12-01 13:42:15 +00:00
|
|
|
case KeyPress:
|
|
|
|
handleKeyEvent(e->xkey);
|
2002-02-06 17:12:09 +00:00
|
|
|
break;
|
2002-12-01 13:42:15 +00:00
|
|
|
case ColormapNotify: {
|
|
|
|
BScreen *screen = searchScreen(e->xcolormap.window);
|
|
|
|
|
|
|
|
if (screen != 0) {
|
|
|
|
screen->setRootColormapInstalled((e->xcolormap.state ==
|
2003-04-25 16:00:03 +00:00
|
|
|
ColormapInstalled) ? true : false);
|
2002-12-01 13:42:15 +00:00
|
|
|
}
|
2003-04-25 16:00:03 +00:00
|
|
|
} break;
|
2002-12-01 13:42:15 +00:00
|
|
|
case FocusIn: {
|
|
|
|
if (e->xfocus.mode == NotifyUngrab ||
|
|
|
|
e->xfocus.detail == NotifyPointer)
|
|
|
|
break;
|
|
|
|
|
2003-07-28 15:06:36 +00:00
|
|
|
WinClient *winclient = searchWindow(e->xfocus.window);
|
|
|
|
if (winclient && !(m_focused_window == winclient))
|
|
|
|
setFocusedWindow(winclient);
|
2002-02-06 17:12:09 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
} break;
|
2003-07-01 20:29:44 +00:00
|
|
|
case FocusOut:{
|
2003-07-20 18:05:40 +00:00
|
|
|
|
2003-07-01 20:29:44 +00:00
|
|
|
if (e->xfocus.mode == NotifyUngrab ||
|
|
|
|
e->xfocus.detail == NotifyPointer)
|
|
|
|
break;
|
2003-07-28 15:06:36 +00:00
|
|
|
WinClient *winclient = searchWindow(e->xfocus.window);
|
|
|
|
if (winclient == 0 && FbTk::Menu::focused() == 0) {
|
2003-07-01 20:29:44 +00:00
|
|
|
#ifdef DEBUG
|
|
|
|
cerr<<__FILE__<<"("<<__FUNCTION__<<") Focus out is not a FluxboxWindow !!"<<endl;
|
|
|
|
#endif // DEBUG
|
2003-07-20 18:05:40 +00:00
|
|
|
|
2003-07-01 20:29:44 +00:00
|
|
|
}
|
|
|
|
}
|
2002-02-06 17:12:09 +00:00
|
|
|
break;
|
2002-12-01 13:42:15 +00:00
|
|
|
case ClientMessage:
|
|
|
|
handleClientMessage(e->xclient);
|
2002-02-06 17:12:09 +00:00
|
|
|
break;
|
2002-12-01 13:42:15 +00:00
|
|
|
default: {
|
2003-05-12 04:23:31 +00:00
|
|
|
#ifdef HAVE_RANDR
|
|
|
|
if (e->type == m_randr_event_type) {
|
|
|
|
// update root window size in screen
|
|
|
|
BScreen *scr = searchScreen(e->xany.window);
|
|
|
|
if (scr != 0)
|
|
|
|
scr->updateSize();
|
2003-05-14 14:37:06 +00:00
|
|
|
}
|
2003-05-12 04:23:31 +00:00
|
|
|
#endif // HAVE_RANDR
|
|
|
|
|
2002-12-02 23:49:56 +00:00
|
|
|
}
|
2003-05-10 14:32:35 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
}
|
2002-02-06 17:12:09 +00:00
|
|
|
}
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2002-02-06 17:12:09 +00:00
|
|
|
void Fluxbox::handleButtonEvent(XButtonEvent &be) {
|
2003-06-30 15:05:26 +00:00
|
|
|
m_mousescreen = searchScreen(be.root);
|
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
switch (be.type) {
|
2003-04-25 16:00:03 +00:00
|
|
|
case ButtonPress: {
|
|
|
|
m_last_time = be.time;
|
2003-04-14 15:28:52 +00:00
|
|
|
|
2003-04-25 16:00:03 +00:00
|
|
|
BScreen *screen = searchScreen(be.window);
|
|
|
|
if (screen == 0)
|
|
|
|
break; // end case
|
2003-06-11 14:53:54 +00:00
|
|
|
#ifdef SLIT
|
|
|
|
// hide slit menu
|
|
|
|
if (screen->slit())
|
|
|
|
screen->slit()->menu().hide();
|
|
|
|
#endif // SLIT
|
2002-02-06 17:12:09 +00:00
|
|
|
|
2003-04-25 16:00:03 +00:00
|
|
|
if (be.button == 1) {
|
|
|
|
if (! screen->isRootColormapInstalled())
|
2003-05-15 23:30:07 +00:00
|
|
|
screen->imageControl().installRootColormap();
|
2002-02-06 17:12:09 +00:00
|
|
|
|
2003-04-25 16:00:03 +00:00
|
|
|
if (screen->getWorkspacemenu()->isVisible())
|
|
|
|
screen->getWorkspacemenu()->hide();
|
|
|
|
if (screen->getRootmenu()->isVisible())
|
|
|
|
screen->getRootmenu()->hide();
|
2003-06-11 14:53:54 +00:00
|
|
|
|
2003-04-25 16:00:03 +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-02-06 17:12:09 +00:00
|
|
|
|
2003-04-25 16:00:03 +00:00
|
|
|
if (mx < 0) mx = 0;
|
|
|
|
if (my < 0) my = 0;
|
|
|
|
|
|
|
|
if (mx + screen->getWorkspacemenu()->width() >
|
2003-05-15 12:00:46 +00:00
|
|
|
screen->width()) {
|
|
|
|
mx = screen->width() -
|
2003-04-25 16:00:03 +00:00
|
|
|
screen->getWorkspacemenu()->width() -
|
|
|
|
screen->getWorkspacemenu()->fbwindow().borderWidth();
|
|
|
|
}
|
2002-12-01 13:42:15 +00:00
|
|
|
|
2003-04-25 16:00:03 +00:00
|
|
|
if (my + screen->getWorkspacemenu()->height() >
|
2003-05-15 12:00:46 +00:00
|
|
|
screen->height()) {
|
|
|
|
my = screen->height() -
|
2003-04-25 16:00:03 +00:00
|
|
|
screen->getWorkspacemenu()->height() -
|
|
|
|
screen->getWorkspacemenu()->fbwindow().borderWidth();
|
|
|
|
}
|
|
|
|
screen->getWorkspacemenu()->move(mx, my);
|
2002-12-01 13:42:15 +00:00
|
|
|
|
2003-04-25 16:00:03 +00:00
|
|
|
if (! screen->getWorkspacemenu()->isVisible()) {
|
|
|
|
screen->getWorkspacemenu()->removeParent();
|
|
|
|
screen->getWorkspacemenu()->show();
|
|
|
|
}
|
|
|
|
} else if (be.button == 3) {
|
|
|
|
//calculate placement of workspace menu
|
|
|
|
//and show/hide it
|
|
|
|
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;
|
|
|
|
|
2003-05-15 12:00:46 +00:00
|
|
|
if (mx + screen->getRootmenu()->width() > screen->width()) {
|
|
|
|
mx = screen->width() -
|
2003-04-25 16:00:03 +00:00
|
|
|
screen->getRootmenu()->width() -
|
|
|
|
screen->getRootmenu()->fbwindow().borderWidth();
|
|
|
|
}
|
2002-12-01 13:42:15 +00:00
|
|
|
|
2003-04-25 16:00:03 +00:00
|
|
|
if (my + screen->getRootmenu()->height() >
|
2003-05-15 12:00:46 +00:00
|
|
|
screen->height()) {
|
|
|
|
my = screen->height() -
|
2003-04-25 16:00:03 +00:00
|
|
|
screen->getRootmenu()->height() -
|
|
|
|
screen->getRootmenu()->fbwindow().borderWidth();
|
|
|
|
}
|
|
|
|
screen->getRootmenu()->move(mx, my);
|
2002-12-01 13:42:15 +00:00
|
|
|
|
2003-04-25 16:00:03 +00:00
|
|
|
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);
|
2002-12-01 13:42:15 +00:00
|
|
|
}
|
2003-04-25 16:00:03 +00:00
|
|
|
|
|
|
|
} break;
|
2002-12-01 13:42:15 +00:00
|
|
|
case ButtonRelease:
|
2003-04-14 15:28:52 +00:00
|
|
|
break;
|
2002-12-01 13:42:15 +00:00
|
|
|
default:
|
2003-04-25 16:00:03 +00:00
|
|
|
break;
|
2002-12-01 13:42:15 +00:00
|
|
|
}
|
2002-02-06 17:12:09 +00:00
|
|
|
}
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2002-02-17 18:43:30 +00:00
|
|
|
void Fluxbox::handleUnmapNotify(XUnmapEvent &ue) {
|
|
|
|
|
|
|
|
|
2003-07-28 15:06:36 +00:00
|
|
|
WinClient *winclient = 0;
|
2002-02-17 18:43:30 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
BScreen *screen = searchScreen(ue.event);
|
2002-02-17 18:43:30 +00:00
|
|
|
|
2003-04-14 15:28:52 +00:00
|
|
|
if ( ue.event != ue.window && (screen != 0 || !ue.send_event))
|
2002-12-01 13:42:15 +00:00
|
|
|
return;
|
2003-04-15 08:54:40 +00:00
|
|
|
|
2003-07-28 15:06:36 +00:00
|
|
|
if ((winclient = searchWindow(ue.window)) != 0) {
|
2003-04-14 15:28:52 +00:00
|
|
|
|
2003-07-28 15:06:36 +00:00
|
|
|
if (winclient != 0) {
|
|
|
|
FluxboxWindow *win = winclient->fbwindow();
|
2003-04-15 08:54:40 +00:00
|
|
|
|
2003-07-28 15:06:36 +00:00
|
|
|
if (!win) {
|
|
|
|
delete winclient;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// this should delete client and adjust m_focused_window if necessary
|
|
|
|
win->unmapNotifyEvent(ue);
|
2002-12-01 13:42:15 +00:00
|
|
|
|
2003-07-28 15:06:36 +00:00
|
|
|
winclient = 0; // it's invalid now when win destroyed the client
|
2003-04-14 15:28:52 +00:00
|
|
|
|
2003-07-28 15:06:36 +00:00
|
|
|
// finally destroy window if empty
|
2003-04-14 15:28:52 +00:00
|
|
|
if (win->numClients() == 0) {
|
|
|
|
delete win;
|
|
|
|
win = 0;
|
|
|
|
}
|
|
|
|
}
|
2002-12-01 13:42:15 +00:00
|
|
|
}
|
2002-02-17 18:43:30 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2003-04-14 15:28:52 +00:00
|
|
|
/**
|
|
|
|
* Handles XClientMessageEvent
|
|
|
|
*/
|
2002-02-06 17:12:09 +00:00
|
|
|
void Fluxbox::handleClientMessage(XClientMessageEvent &ce) {
|
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-02-06 17:12:09 +00:00
|
|
|
|
2003-04-15 12:22:52 +00:00
|
|
|
if (ce.message_type == m_fbatoms->getWMChangeStateAtom()) {
|
2003-07-28 15:06:36 +00:00
|
|
|
WinClient *winclient = searchWindow(ce.window);
|
|
|
|
if (! winclient || !winclient->fbwindow() || ! winclient->validateClient())
|
2002-12-01 13:42:15 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
if (ce.data.l[0] == IconicState)
|
2003-07-28 15:06:36 +00:00
|
|
|
winclient->fbwindow()->iconify();
|
2002-12-01 13:42:15 +00:00
|
|
|
if (ce.data.l[0] == NormalState)
|
2003-07-28 15:06:36 +00:00
|
|
|
winclient->fbwindow()->deiconify();
|
2003-04-15 12:22:52 +00:00
|
|
|
} else if (ce.message_type == m_fbatoms->getFluxboxChangeWorkspaceAtom()) {
|
2002-12-01 13:42:15 +00:00
|
|
|
BScreen *screen = searchScreen(ce.window);
|
|
|
|
|
|
|
|
if (screen && ce.data.l[0] >= 0 &&
|
|
|
|
ce.data.l[0] < (signed)screen->getCount())
|
|
|
|
screen->changeWorkspaceID(ce.data.l[0]);
|
2002-02-06 17:12:09 +00:00
|
|
|
|
2003-04-15 12:22:52 +00:00
|
|
|
} else if (ce.message_type == m_fbatoms->getFluxboxChangeWindowFocusAtom()) {
|
2003-07-28 15:06:36 +00:00
|
|
|
WinClient *winclient = searchWindow(ce.window);
|
|
|
|
if (winclient) {
|
|
|
|
FluxboxWindow *win = winclient->fbwindow();
|
|
|
|
if (win && win->isVisible())
|
|
|
|
win->setCurrentClient(*winclient, true);
|
|
|
|
}
|
2003-04-15 12:22:52 +00:00
|
|
|
} else if (ce.message_type == m_fbatoms->getFluxboxCycleWindowFocusAtom()) {
|
2002-12-01 13:42:15 +00:00
|
|
|
BScreen *screen = searchScreen(ce.window);
|
|
|
|
|
|
|
|
if (screen) {
|
|
|
|
if (! ce.data.l[0])
|
|
|
|
screen->prevFocus();
|
|
|
|
else
|
|
|
|
screen->nextFocus();
|
2003-07-28 15:06:36 +00:00
|
|
|
}
|
2003-04-15 12:22:52 +00:00
|
|
|
} else if (ce.message_type == m_fbatoms->getFluxboxChangeAttributesAtom()) {
|
2003-07-28 15:06:36 +00:00
|
|
|
WinClient *winclient = searchWindow(ce.window);
|
|
|
|
FluxboxWindow *win = 0;
|
|
|
|
if (winclient && (win = winclient->fbwindow()) && winclient->validateClient()) {
|
2003-05-10 14:32:35 +00:00
|
|
|
FluxboxWindow::BlackboxHints net;
|
2002-12-01 13:42:15 +00:00
|
|
|
net.flags = ce.data.l[0];
|
|
|
|
net.attrib = ce.data.l[1];
|
|
|
|
net.workspace = ce.data.l[2];
|
|
|
|
net.stack = ce.data.l[3];
|
|
|
|
net.decoration = static_cast<int>(ce.data.l[4]);
|
2003-01-05 22:41:21 +00:00
|
|
|
win->changeBlackboxHints(net);
|
2002-12-01 13:42:15 +00:00
|
|
|
}
|
|
|
|
} else {
|
2003-07-28 15:06:36 +00:00
|
|
|
WinClient *winclient = searchWindow(ce.window);
|
2002-12-01 13:42:15 +00:00
|
|
|
BScreen *screen = searchScreen(ce.window);
|
2003-07-28 15:06:36 +00:00
|
|
|
|
2003-08-04 18:16:22 +00:00
|
|
|
if (winclient || screen) {
|
2003-07-28 15:06:36 +00:00
|
|
|
for (size_t i=0; i<m_atomhandler.size(); ++i) {
|
2003-08-04 18:16:22 +00:00
|
|
|
m_atomhandler[i]->checkClientMessage(ce, screen, winclient);
|
2003-07-28 15:06:36 +00:00
|
|
|
}
|
2002-12-01 13:42:15 +00:00
|
|
|
}
|
|
|
|
}
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
2003-04-14 15:28:52 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
Handles KeyRelease and KeyPress events
|
|
|
|
*/
|
2002-02-06 17:12:09 +00:00
|
|
|
void Fluxbox::handleKeyEvent(XKeyEvent &ke) {
|
2003-06-30 15:05:26 +00:00
|
|
|
m_keyscreen = searchScreen(ke.window);
|
|
|
|
|
|
|
|
m_mousescreen = keyScreen();
|
|
|
|
Window root, ignorew;
|
|
|
|
int ignored;
|
|
|
|
if (!XQueryPointer(FbTk::App::instance()->display(),
|
|
|
|
ke.window, &root, &ignorew, &ignored, &ignored,
|
|
|
|
&ignored, &ignored, (unsigned int *)&ignored))
|
|
|
|
// pointer on different screen to ke.window
|
|
|
|
m_mousescreen = searchScreen(root);
|
|
|
|
|
|
|
|
if (keyScreen() == 0 || mouseScreen() == 0)
|
|
|
|
return;
|
2003-04-25 16:00:03 +00:00
|
|
|
|
2003-06-30 15:05:26 +00:00
|
|
|
|
|
|
|
switch (ke.type) {
|
|
|
|
case KeyPress:
|
|
|
|
m_key->doAction(ke);
|
|
|
|
break;
|
2003-04-25 16:00:03 +00:00
|
|
|
case KeyRelease: {
|
|
|
|
// we ignore most key releases unless we need to use
|
|
|
|
// a release to stop something (e.g. window cycling).
|
|
|
|
|
|
|
|
// we notify if _all_ of the watched modifiers are released
|
|
|
|
if (m_watching_screen && m_watch_keyrelease) {
|
|
|
|
// mask the mod of the released key out
|
|
|
|
// won't mask anything if it isn't a mod
|
|
|
|
ke.state &= ~m_key->keycodeToModmask(ke.keycode);
|
|
|
|
|
|
|
|
if ((m_watch_keyrelease & ke.state) == 0) {
|
2003-04-15 00:50:25 +00:00
|
|
|
|
2003-04-25 16:00:03 +00:00
|
|
|
m_watching_screen->notifyReleasedKeys(ke);
|
|
|
|
XUngrabKeyboard(FbTk::App::instance()->display(), CurrentTime);
|
2003-04-15 00:50:25 +00:00
|
|
|
|
2003-04-25 16:00:03 +00:00
|
|
|
// once they are released, we drop the watch
|
|
|
|
m_watching_screen = 0;
|
|
|
|
m_watch_keyrelease = 0;
|
2003-04-15 00:50:25 +00:00
|
|
|
}
|
2003-04-25 16:00:03 +00:00
|
|
|
}
|
2003-04-15 00:50:25 +00:00
|
|
|
|
2003-04-25 16:00:03 +00:00
|
|
|
break;
|
|
|
|
}
|
2002-12-01 13:42:15 +00:00
|
|
|
default:
|
2003-04-14 15:28:52 +00:00
|
|
|
break;
|
2002-12-01 13:42:15 +00:00
|
|
|
}
|
2002-02-06 17:12:09 +00:00
|
|
|
|
|
|
|
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
|
2003-04-14 15:28:52 +00:00
|
|
|
/// handle system signals
|
2002-11-27 22:00:19 +00:00
|
|
|
void Fluxbox::handleSignal(int signum) {
|
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"),
|
2003-05-10 14:32:35 +00:00
|
|
|
m_argv[0], signum);
|
2002-12-01 13:42:15 +00:00
|
|
|
|
2003-05-10 14:32:35 +00:00
|
|
|
if (! m_starting && ! re_enter) {
|
2002-12-01 13:42:15 +00:00
|
|
|
re_enter = 1;
|
|
|
|
fprintf(stderr,
|
|
|
|
i18n->getMessage(
|
|
|
|
FBNLS::BaseDisplaySet, FBNLS::BaseDisplayShuttingDown,
|
|
|
|
"shutting down\n"));
|
|
|
|
shutdown();
|
|
|
|
}
|
2002-01-18 01:23:54 +00:00
|
|
|
|
2002-08-14 00:01:10 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
fprintf(stderr,
|
|
|
|
i18n->getMessage(
|
|
|
|
FBNLS::BaseDisplaySet, FBNLS::BaseDisplayAborting,
|
|
|
|
"aborting... dumping core\n"));
|
|
|
|
abort();
|
|
|
|
break;
|
|
|
|
}
|
2002-09-07 20:25:39 +00:00
|
|
|
}
|
2002-01-18 01:23:54 +00:00
|
|
|
|
2002-08-14 00:01:10 +00:00
|
|
|
|
2002-09-07 20:25:39 +00:00
|
|
|
void Fluxbox::update(FbTk::Subject *changedsub) {
|
2003-04-14 15:28:52 +00:00
|
|
|
//TODO: fix signaling, this does not look good
|
2003-03-03 21:51:13 +00:00
|
|
|
if (typeid(*changedsub) == typeid(FluxboxWindow::WinSubject)) {
|
2002-12-01 13:42:15 +00:00
|
|
|
FluxboxWindow::WinSubject *winsub = dynamic_cast<FluxboxWindow::WinSubject *>(changedsub);
|
|
|
|
FluxboxWindow &win = winsub->win();
|
|
|
|
if ((&(win.hintSig())) == changedsub) { // hint signal
|
|
|
|
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()) {
|
2003-05-15 11:17:29 +00:00
|
|
|
Workspace *space = win.screen().getWorkspace(win.workspaceNumber());
|
2003-04-14 15:28:52 +00:00
|
|
|
if (space != 0)
|
|
|
|
space->removeWindow(&win);
|
2003-05-11 13:36:12 +00:00
|
|
|
win.screen().addIcon(&win);
|
2003-04-14 15:28:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (win.isStuck()) {
|
|
|
|
// if we're sticky then reassociate window
|
|
|
|
// to all workspaces
|
2003-05-11 13:36:12 +00:00
|
|
|
BScreen &scr = win.screen();
|
2003-05-15 12:00:46 +00:00
|
|
|
if (scr.currentWorkspaceID() != win.workspaceNumber()) {
|
2003-04-14 15:28:52 +00:00
|
|
|
scr.reassociateWindow(&win,
|
2003-05-15 12:00:46 +00:00
|
|
|
scr.currentWorkspaceID(),
|
2003-04-14 15:28:52 +00:00
|
|
|
true);
|
|
|
|
}
|
|
|
|
}
|
2003-02-02 16:32:41 +00:00
|
|
|
} else if ((&(win.layerSig())) == changedsub) { // layer signal
|
2003-04-14 15:28:52 +00:00
|
|
|
|
2003-02-02 16:32:41 +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())
|
2003-07-04 14:06:20 +00:00
|
|
|
m_atomhandler[i]->updateFrameClose(win);
|
2003-03-03 21:51:13 +00:00
|
|
|
}
|
2003-04-14 15:28:52 +00:00
|
|
|
// make sure each workspace get this
|
2003-05-11 13:36:12 +00:00
|
|
|
BScreen &scr = win.screen();
|
2003-04-15 00:50:25 +00:00
|
|
|
scr.removeWindow(&win);
|
2003-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 {
|
2002-09-08 19:31:27 +00:00
|
|
|
#ifdef DEBUG
|
2002-12-01 13:42:15 +00:00
|
|
|
cerr<<__FILE__<<"("<<__LINE__<<"): WINDOW uncought signal from "<<&win<<endl;
|
2002-09-07 20:25:39 +00:00
|
|
|
#endif // DEBUG
|
2002-12-01 13:42:15 +00:00
|
|
|
}
|
2002-09-07 20:25:39 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
} else if (typeid(*changedsub) == typeid(BScreen::ScreenSubject)) {
|
|
|
|
BScreen::ScreenSubject *subj = dynamic_cast<BScreen::ScreenSubject *>(changedsub);
|
|
|
|
BScreen &screen = subj->screen();
|
|
|
|
if ((&(screen.workspaceCountSig())) == changedsub) {
|
|
|
|
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();
|
|
|
|
|
2003-07-04 14:06:20 +00:00
|
|
|
// TODO: don't assume it is diesig (need to fix as soon as another signal appears)
|
|
|
|
for (size_t i=0; i<m_atomhandler.size(); ++i) {
|
|
|
|
if (m_atomhandler[i]->update())
|
|
|
|
m_atomhandler[i]->updateClientClose(client);
|
|
|
|
}
|
2003-07-28 15:06:36 +00:00
|
|
|
|
2003-05-14 12:10:54 +00:00
|
|
|
BScreen &screen = client.screen();
|
|
|
|
screen.updateNetizenWindowDel(client.window());
|
|
|
|
screen.removeClient(client);
|
2003-04-14 15:28:52 +00:00
|
|
|
|
2003-07-28 15:06:36 +00:00
|
|
|
if (m_focused_window == &client)
|
|
|
|
revertFocus(screen);
|
|
|
|
|
2003-04-14 15:28:52 +00:00
|
|
|
removeWindowSearch(client.window());
|
2002-12-01 13:42:15 +00:00
|
|
|
}
|
2002-09-07 20:25:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Fluxbox::attachSignals(FluxboxWindow &win) {
|
2002-12-01 13:42:15 +00:00
|
|
|
win.hintSig().attach(this);
|
|
|
|
win.stateSig().attach(this);
|
|
|
|
win.workspaceSig().attach(this);
|
2003-02-02 16:32:41 +00:00
|
|
|
win.layerSig().attach(this);
|
2003-03-03 21:51:13 +00:00
|
|
|
win.dieSig().attach(this);
|
2002-12-01 13:42:15 +00:00
|
|
|
for (size_t i=0; i<m_atomhandler.size(); ++i) {
|
2003-07-04 01:03:41 +00:00
|
|
|
m_atomhandler[i]->setupFrame(win);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Fluxbox::attachSignals(WinClient &winclient) {
|
|
|
|
winclient.dieSig().attach(this);
|
|
|
|
|
|
|
|
for (size_t i=0; i<m_atomhandler.size(); ++i) {
|
|
|
|
m_atomhandler[i]->setupClient(winclient);
|
2002-12-01 13:42:15 +00:00
|
|
|
}
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
BScreen *Fluxbox::searchScreen(Window window) {
|
2003-04-14 15:28:52 +00:00
|
|
|
BScreen *screen = 0;
|
2003-04-25 16:00:03 +00:00
|
|
|
ScreenList::iterator it = m_screen_list.begin();
|
|
|
|
ScreenList::iterator it_end = m_screen_list.end();
|
2002-12-01 13:42:15 +00:00
|
|
|
|
|
|
|
for (; it != it_end; ++it) {
|
|
|
|
if (*it) {
|
2003-05-10 23:07:42 +00:00
|
|
|
if ((*it)->rootWindow() == window) {
|
2002-12-01 13:42:15 +00:00
|
|
|
screen = (*it);
|
|
|
|
return screen;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-04-14 15:28:52 +00:00
|
|
|
return 0;
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
|
2003-04-25 16:00:03 +00:00
|
|
|
void Fluxbox::addAtomHandler(AtomHandler *atomh) {
|
|
|
|
for (unsigned int handler = 0; handler < m_atomhandler.size(); handler++) {
|
|
|
|
if (m_atomhandler[handler] == atomh)
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
m_atomhandler.push_back(atomh);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Fluxbox::removeAtomHandler(AtomHandler *atomh) {
|
|
|
|
std::vector<AtomHandler *>::iterator it = m_atomhandler.begin();
|
|
|
|
for (; it != m_atomhandler.end(); ++it) {
|
|
|
|
if (*it == atomh) {
|
|
|
|
m_atomhandler.erase(it);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2003-07-28 15:06:36 +00:00
|
|
|
WinClient *Fluxbox::searchWindow(Window window) {
|
|
|
|
std::map<Window, WinClient *>::iterator it = m_window_search.find(window);
|
|
|
|
if (it != m_window_search.end())
|
|
|
|
return it->second;
|
|
|
|
|
|
|
|
std::map<Window, FluxboxWindow *>::iterator git = m_window_search_group.find(window);
|
|
|
|
return git == m_window_search_group.end() ? 0 : &git->second->winClient();
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-07-28 15:06:36 +00:00
|
|
|
/* Not implemented until we know how it'll be used
|
|
|
|
* Recall that this refers to ICCCM groups, not fluxbox tabgroups
|
|
|
|
* See ICCCM 4.1.11 for details
|
|
|
|
*/
|
|
|
|
/*
|
|
|
|
WinClient *Fluxbox::searchGroup(Window window) {
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
2003-07-28 15:06:36 +00:00
|
|
|
*/
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2003-07-28 15:06:36 +00:00
|
|
|
void Fluxbox::saveWindowSearch(Window window, WinClient *data) {
|
2003-04-25 16:00:03 +00:00
|
|
|
m_window_search[window] = data;
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
|
2003-07-28 15:06:36 +00:00
|
|
|
/* some windows relate to the whole group */
|
|
|
|
void Fluxbox::saveWindowSearchGroup(Window window, FluxboxWindow *data) {
|
|
|
|
m_window_search_group[window] = data;
|
|
|
|
}
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2003-07-28 15:06:36 +00:00
|
|
|
void Fluxbox::saveGroupSearch(Window window, WinClient *data) {
|
|
|
|
m_group_search.insert(pair<Window, WinClient *>(window, data));
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Fluxbox::removeWindowSearch(Window window) {
|
2003-04-25 16:00:03 +00:00
|
|
|
m_window_search.erase(window);
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
|
2003-07-28 15:06:36 +00:00
|
|
|
void Fluxbox::removeWindowSearchGroup(Window window) {
|
|
|
|
m_window_search_group.erase(window);
|
|
|
|
}
|
|
|
|
|
2001-12-11 20:47:02 +00:00
|
|
|
void Fluxbox::removeGroupSearch(Window window) {
|
2003-04-25 16:00:03 +00:00
|
|
|
m_group_search.erase(window);
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
|
2003-04-25 16:00:03 +00:00
|
|
|
/// restarts fluxbox
|
2001-12-11 20:47:02 +00:00
|
|
|
void Fluxbox::restart(const char *prog) {
|
2002-12-01 13:42:15 +00:00
|
|
|
shutdown();
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
if (prog) {
|
2003-06-11 10:50:59 +00:00
|
|
|
execlp(prog, prog, 0);
|
2002-12-01 13:42:15 +00:00
|
|
|
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
|
2003-04-25 16:00:03 +00:00
|
|
|
execvp(m_argv[0], m_argv);
|
|
|
|
execvp(basename(m_argv[0]), m_argv);
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
|
2003-04-25 16:00:03 +00:00
|
|
|
/// prepares fluxbox for a shutdown
|
2002-10-15 20:41:08 +00:00
|
|
|
void Fluxbox::shutdown() {
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2003-04-25 16:00:03 +00:00
|
|
|
XSetInputFocus(FbTk::App::instance()->display(), PointerRoot, None, CurrentTime);
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
//send shutdown to all screens
|
2003-04-25 16:00:03 +00:00
|
|
|
ScreenList::iterator it = m_screen_list.begin();
|
|
|
|
ScreenList::iterator it_end = m_screen_list.end();
|
2002-12-01 13:42:15 +00:00
|
|
|
for (; it != it_end; ++it) {
|
|
|
|
if(*it)
|
|
|
|
(*it)->shutdown();
|
|
|
|
}
|
2003-05-10 14:32:35 +00:00
|
|
|
m_shutdown = true;
|
2003-04-25 16:00:03 +00:00
|
|
|
XSync(FbTk::App::instance()->display(), False);
|
2001-12-11 20:47:02 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2003-04-25 16:00:03 +00:00
|
|
|
/// saves resources
|
2002-10-15 20:41:08 +00:00
|
|
|
void Fluxbox::save_rc() {
|
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);
|
|
|
|
|
2003-04-25 16:00:03 +00:00
|
|
|
ScreenList::iterator it = m_screen_list.begin();
|
|
|
|
ScreenList::iterator it_end = m_screen_list.end();
|
2002-12-01 13:42:15 +00:00
|
|
|
|
|
|
|
//Save screen resources
|
|
|
|
|
|
|
|
for (; it != it_end; ++it) {
|
|
|
|
BScreen *screen = *it;
|
2003-05-15 12:00:46 +00:00
|
|
|
int screen_number = screen->screenNumber();
|
2003-04-26 05:42:36 +00:00
|
|
|
|
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;
|
|
|
|
|
2003-04-25 09:07:14 +00:00
|
|
|
case BScreen::UNDERMOUSEPLACEMENT:
|
|
|
|
placement = "UnderMousePlacement";
|
|
|
|
break;
|
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
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);
|
|
|
|
|
2003-01-12 18:11:12 +00:00
|
|
|
// 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
|
|
|
|
2002-01-18 01:23:54 +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,
|
2003-03-23 01:33:31 +00:00
|
|
|
((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
|
|
|
}
|
|
|
|
|
2003-04-25 16:00:03 +00:00
|
|
|
/// @return filename of resource file
|
2002-08-14 23:03:07 +00:00
|
|
|
string Fluxbox::getRcFilename() {
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2003-04-25 16:00:03 +00:00
|
|
|
if (m_rc_file.size() == 0) { // set default filename
|
2003-05-11 22:19:17 +00:00
|
|
|
string defaultfile(getenv("HOME") + string("/.") + m_RC_PATH + string("/") + m_RC_INIT_FILE);
|
2002-12-01 13:42:15 +00:00
|
|
|
return defaultfile;
|
|
|
|
}
|
2002-01-11 09:26:33 +00:00
|
|
|
|
2003-04-25 16:00:03 +00:00
|
|
|
return m_rc_file;
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
|
2003-04-25 16:00:03 +00:00
|
|
|
/// Provides default filename of data file
|
2002-05-29 06:22:31 +00:00
|
|
|
void Fluxbox::getDefaultDataFilename(char *name, string &filename) {
|
2003-05-11 22:19:17 +00:00
|
|
|
filename = string(getenv("HOME") + string("/.") + m_RC_PATH + string("/") + name);
|
2002-05-29 06:22:31 +00:00
|
|
|
}
|
|
|
|
|
2003-04-25 16:00:03 +00:00
|
|
|
/// loads resources
|
2002-10-15 20:41:08 +00:00
|
|
|
void Fluxbox::load_rc() {
|
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());
|
|
|
|
|
2003-01-12 18:11:12 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
if (dbfile.size() != 0) {
|
|
|
|
if (!m_resourcemanager.load(dbfile.c_str())) {
|
2003-05-10 15:22:28 +00:00
|
|
|
cerr<<"Failed to load database:"<<dbfile<<endl;
|
2002-12-01 13:42:15 +00:00
|
|
|
cerr<<"Trying with: "<<DEFAULT_INITFILE<<endl;
|
|
|
|
if (!m_resourcemanager.load(DEFAULT_INITFILE))
|
2003-05-10 15:22:28 +00:00
|
|
|
cerr<<"Failed to load database: "<<DEFAULT_INITFILE<<endl;
|
2002-12-01 13:42:15 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (!m_resourcemanager.load(DEFAULT_INITFILE))
|
2003-05-10 15:22:28 +00:00
|
|
|
cerr<<"Failed to load database: "<<DEFAULT_INITFILE<<endl;
|
2002-12-01 13:42:15 +00:00
|
|
|
}
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
XrmValue value;
|
|
|
|
char *value_type;
|
2003-08-10 12:50:04 +00:00
|
|
|
if (m_rc_menufile->size() == 0)
|
2002-12-01 13:42:15 +00:00
|
|
|
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-14 23:03:07 +00:00
|
|
|
|
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)) {
|
2003-05-10 15:22:28 +00:00
|
|
|
cerr<<"Failed to load groupfile: "<<*m_rc_groupfile<<endl;
|
2002-12-01 13:42:15 +00:00
|
|
|
}
|
2002-01-18 01:23:54 +00:00
|
|
|
}
|
|
|
|
|
2003-04-15 12:22:52 +00:00
|
|
|
void Fluxbox::load_rc(BScreen &screen) {
|
2002-12-01 13:42:15 +00:00
|
|
|
//get resource filename
|
|
|
|
string dbfile(getRcFilename());
|
|
|
|
if (dbfile.size() != 0) {
|
|
|
|
if (!m_screen_rm.load(dbfile.c_str())) {
|
2003-05-10 15:22:28 +00:00
|
|
|
cerr<<"Failed to load database:"<<dbfile<<endl;
|
2002-12-01 13:42:15 +00:00
|
|
|
cerr<<"Trying with: "<<DEFAULT_INITFILE<<endl;
|
|
|
|
if (!m_screen_rm.load(DEFAULT_INITFILE))
|
2003-05-10 15:22:28 +00:00
|
|
|
cerr<<"Failed to load database: "<<DEFAULT_INITFILE<<endl;
|
2002-12-01 13:42:15 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (!m_screen_rm.load(DEFAULT_INITFILE))
|
2003-05-10 15:22:28 +00:00
|
|
|
cerr<<"Failed to load database: "<<DEFAULT_INITFILE<<endl;
|
2002-12-01 13:42:15 +00:00
|
|
|
}
|
2002-01-20 02:19:16 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
XrmDatabaseHelper database;
|
2002-01-18 01:23:54 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
database = XrmGetFileDatabase(dbfile.c_str());
|
|
|
|
if (database==0)
|
|
|
|
database = XrmGetFileDatabase(DEFAULT_INITFILE);
|
2002-01-18 01:23:54 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
XrmValue value;
|
|
|
|
char *value_type, name_lookup[1024], class_lookup[1024];
|
2003-05-15 12:00:46 +00:00
|
|
|
int screen_number = screen.screenNumber();
|
2002-12-01 13:42:15 +00:00
|
|
|
|
|
|
|
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))
|
2003-04-15 12:22:52 +00:00
|
|
|
screen.saveRowPlacementDirection(BScreen::RIGHTLEFT);
|
2002-12-01 13:42:15 +00:00
|
|
|
else
|
2003-04-15 12:22:52 +00:00
|
|
|
screen.saveRowPlacementDirection(BScreen::LEFTRIGHT);
|
2002-12-01 13:42:15 +00:00
|
|
|
} else
|
2003-04-15 12:22:52 +00:00
|
|
|
screen.saveRowPlacementDirection(BScreen::LEFTRIGHT);
|
2002-12-01 13:42:15 +00:00
|
|
|
|
|
|
|
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))
|
2003-04-15 12:22:52 +00:00
|
|
|
screen.saveColPlacementDirection(BScreen::BOTTOMTOP);
|
2002-12-01 13:42:15 +00:00
|
|
|
else
|
2003-04-15 12:22:52 +00:00
|
|
|
screen.saveColPlacementDirection(BScreen::TOPBOTTOM);
|
2002-12-01 13:42:15 +00:00
|
|
|
} else
|
2003-04-15 12:22:52 +00:00
|
|
|
screen.saveColPlacementDirection(BScreen::TOPBOTTOM);
|
2002-12-01 13:42:15 +00:00
|
|
|
|
2003-04-15 12:22:52 +00:00
|
|
|
screen.removeWorkspaceNames();
|
2002-12-01 13:42:15 +00:00
|
|
|
|
|
|
|
sprintf(name_lookup, "session.screen%d.workspaceNames", screen_number);
|
|
|
|
sprintf(class_lookup, "Session.Screen%d.WorkspaceNames", screen_number);
|
|
|
|
if (XrmGetResource(*database, name_lookup, class_lookup, &value_type,
|
|
|
|
&value)) {
|
2002-08-14 23:03:07 +00:00
|
|
|
#ifdef DEBUG
|
2003-04-15 12:22:52 +00:00
|
|
|
cerr<<__FILE__<<"("<<__FUNCTION__<<"): Workspaces="<<
|
|
|
|
screen.getNumberOfWorkspaces()<<endl;
|
2002-08-14 23:03:07 +00:00
|
|
|
#endif // DEBUG
|
2002-12-01 13:42:15 +00:00
|
|
|
char *search = StringUtil::strdup(value.addr);
|
2002-01-18 01:23:54 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
int i;
|
2003-04-15 12:22:52 +00:00
|
|
|
for (i = 0; i < screen.getNumberOfWorkspaces(); i++) {
|
2002-12-01 13:42:15 +00:00
|
|
|
char *nn;
|
2002-01-18 01:23:54 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
if (! i) nn = strtok(search, ",");
|
|
|
|
else nn = strtok(0, ",");
|
2002-01-18 01:23:54 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
if (nn)
|
2003-04-15 12:22:52 +00:00
|
|
|
screen.addWorkspaceName(nn);
|
2002-12-01 13:42:15 +00:00
|
|
|
else break;
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
delete [] search;
|
|
|
|
}
|
|
|
|
|
|
|
|
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))
|
2003-04-15 12:22:52 +00:00
|
|
|
screen.savePlacementPolicy(BScreen::ROWSMARTPLACEMENT);
|
2002-12-01 13:42:15 +00:00
|
|
|
else if (! strncasecmp(value.addr, "ColSmartPlacement", value.size))
|
2003-04-15 12:22:52 +00:00
|
|
|
screen.savePlacementPolicy(BScreen::COLSMARTPLACEMENT);
|
2003-04-25 09:07:14 +00:00
|
|
|
else if (! strncasecmp(value.addr, "UnderMousePlacement", value.size))
|
|
|
|
screen.savePlacementPolicy(BScreen::UNDERMOUSEPLACEMENT);
|
2002-12-01 13:42:15 +00:00
|
|
|
else
|
2003-04-15 12:22:52 +00:00
|
|
|
screen.savePlacementPolicy(BScreen::CASCADEPLACEMENT);
|
2002-12-01 13:42:15 +00:00
|
|
|
} else
|
2003-04-15 12:22:52 +00:00
|
|
|
screen.savePlacementPolicy(BScreen::ROWSMARTPLACEMENT);
|
2003-02-23 00:53:31 +00:00
|
|
|
|
2002-01-18 01:23:54 +00:00
|
|
|
#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))
|
2003-04-15 12:22:52 +00:00
|
|
|
screen.saveStrftimeFormat(value.addr);
|
2002-12-01 13:42:15 +00:00
|
|
|
else
|
2003-04-15 12:22:52 +00:00
|
|
|
screen.saveStrftimeFormat("%I:%M %p");
|
2002-01-18 01:23:54 +00:00
|
|
|
#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))
|
2003-04-15 12:22:52 +00:00
|
|
|
screen.saveDateFormat(B_AMERICANDATE);
|
2002-12-01 13:42:15 +00:00
|
|
|
else
|
2003-04-15 12:22:52 +00:00
|
|
|
screen.saveDateFormat(B_EUROPEANDATE);
|
2002-12-01 13:42:15 +00:00
|
|
|
} else
|
2003-04-15 12:22:52 +00:00
|
|
|
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)
|
2003-04-25 16:00:03 +00:00
|
|
|
screen.saveClock24Hour(false);
|
2002-12-01 13:42:15 +00:00
|
|
|
else if (clock == 24)
|
2003-04-25 16:00:03 +00:00
|
|
|
screen.saveClock24Hour(true);
|
2002-12-01 13:42:15 +00:00
|
|
|
else
|
2003-04-25 16:00:03 +00:00
|
|
|
screen.saveClock24Hour(false);
|
2002-12-01 13:42:15 +00:00
|
|
|
} else
|
2003-04-25 16:00:03 +00:00
|
|
|
screen.saveClock24Hour(false);
|
2001-12-11 20:47:02 +00:00
|
|
|
#endif // HAVE_STRFTIME
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2003-04-15 12:22:52 +00:00
|
|
|
void Fluxbox::loadRootCommand(BScreen &screen) {
|
2002-01-11 09:26:33 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
string dbfile(getRcFilename());
|
|
|
|
|
2002-12-02 23:49:56 +00:00
|
|
|
XrmDatabaseHelper database(dbfile.c_str());
|
|
|
|
if (!*database)
|
2002-12-01 13:42:15 +00:00
|
|
|
database = XrmGetFileDatabase(DEFAULT_INITFILE);
|
|
|
|
|
|
|
|
XrmValue value;
|
|
|
|
char *value_type, name_lookup[1024], class_lookup[1024];
|
2003-05-15 12:00:46 +00:00
|
|
|
sprintf(name_lookup, "session.screen%d.rootCommand", screen.screenNumber());
|
|
|
|
sprintf(class_lookup, "Session.Screen%d.RootCommand", screen.screenNumber());
|
2002-12-02 23:49:56 +00:00
|
|
|
if (XrmGetResource(*database, name_lookup, class_lookup, &value_type,
|
2002-12-01 13:42:15 +00:00
|
|
|
&value)) {
|
2003-04-15 12:22:52 +00:00
|
|
|
screen.saveRootCommand(value.addr==0 ? "": value.addr);
|
2002-12-01 13:42:15 +00:00
|
|
|
} else
|
2003-04-15 12:22:52 +00:00
|
|
|
screen.saveRootCommand("");
|
2002-01-10 12:51:21 +00:00
|
|
|
|
|
|
|
}
|
2002-01-11 09:26:33 +00:00
|
|
|
|
2002-08-14 23:03:07 +00:00
|
|
|
void Fluxbox::reload_rc() {
|
2002-12-01 13:42:15 +00:00
|
|
|
load_rc();
|
|
|
|
reconfigure();
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-08-14 23:03:07 +00:00
|
|
|
void Fluxbox::reconfigure() {
|
2003-04-25 16:00:03 +00:00
|
|
|
m_reconfigure_wait = true;
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2003-04-25 16:00:03 +00:00
|
|
|
if (! m_timer.isTiming())
|
|
|
|
m_timer.start();
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-08-14 23:03:07 +00:00
|
|
|
void Fluxbox::real_reconfigure() {
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
XrmDatabase new_blackboxrc = (XrmDatabase) 0;
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
string dbfile(getRcFilename());
|
|
|
|
XrmDatabase old_blackboxrc = XrmGetFileDatabase(dbfile.c_str());
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
XrmMergeDatabases(new_blackboxrc, &old_blackboxrc);
|
|
|
|
XrmPutFileDatabase(old_blackboxrc, dbfile.c_str());
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
if (old_blackboxrc)
|
|
|
|
XrmDestroyDatabase(old_blackboxrc);
|
|
|
|
|
|
|
|
|
2003-04-25 16:00:03 +00:00
|
|
|
ScreenList::iterator sit = m_screen_list.begin();
|
|
|
|
ScreenList::iterator sit_end = m_screen_list.end();
|
2002-12-01 13:42:15 +00:00
|
|
|
for (; sit != sit_end; ++sit)
|
|
|
|
(*sit)->reconfigure();
|
2003-05-13 00:20:49 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
//reconfigure keys
|
2003-04-25 16:00:03 +00:00
|
|
|
m_key->reconfigure(StringUtil::expandFilename(*m_rc_keyfile).c_str());
|
2001-12-11 20:47:02 +00:00
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-05-13 00:20:49 +00:00
|
|
|
bool Fluxbox::menuTimestampsChanged() const {
|
|
|
|
std::list<MenuTimestamp *>::const_iterator it = m_menu_timestamps.begin();
|
|
|
|
std::list<MenuTimestamp *>::const_iterator it_end = m_menu_timestamps.end();
|
|
|
|
for (; it != it_end; ++it) {
|
2002-12-01 13:42:15 +00:00
|
|
|
struct stat buf;
|
|
|
|
|
2003-04-25 16:00:03 +00:00
|
|
|
if (! stat((*it)->filename.c_str(), &buf)) {
|
2002-12-01 13:42:15 +00:00
|
|
|
if ((*it)->timestamp != buf.st_ctime)
|
2003-05-13 00:20:49 +00:00
|
|
|
return true;
|
2002-12-01 13:42:15 +00:00
|
|
|
} else
|
2003-05-13 00:20:49 +00:00
|
|
|
return true;
|
2002-12-01 13:42:15 +00:00
|
|
|
}
|
|
|
|
|
2003-05-13 00:20:49 +00:00
|
|
|
// no timestamp changed
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Fluxbox::checkMenu() {
|
|
|
|
if (menuTimestampsChanged())
|
|
|
|
rereadMenu();
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-10-15 20:41:08 +00:00
|
|
|
void Fluxbox::rereadMenu() {
|
2003-04-25 16:00:03 +00:00
|
|
|
m_reread_menu_wait = true;
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2003-04-25 16:00:03 +00:00
|
|
|
if (! m_timer.isTiming())
|
|
|
|
m_timer.start();
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-10-15 20:41:08 +00:00
|
|
|
void Fluxbox::real_rereadMenu() {
|
2003-04-25 16:00:03 +00:00
|
|
|
std::list<MenuTimestamp *>::iterator it = m_menu_timestamps.begin();
|
|
|
|
std::list<MenuTimestamp *>::iterator it_end = m_menu_timestamps.end();
|
|
|
|
for (; it != it_end; ++it)
|
|
|
|
delete *it;
|
2002-12-01 13:42:15 +00:00
|
|
|
|
2003-04-25 16:00:03 +00:00
|
|
|
m_menu_timestamps.erase(m_menu_timestamps.begin(), m_menu_timestamps.end());
|
2002-12-01 13:42:15 +00:00
|
|
|
|
2003-04-25 16:00:03 +00:00
|
|
|
ScreenList::iterator sit = m_screen_list.begin();
|
|
|
|
ScreenList::iterator sit_end = m_screen_list.end();
|
2002-12-01 13:42:15 +00:00
|
|
|
for (; sit != sit_end; ++sit) {
|
|
|
|
(*sit)->rereadMenu();
|
|
|
|
}
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Fluxbox::saveMenuFilename(const char *filename) {
|
2003-04-25 16:00:03 +00:00
|
|
|
if (filename == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
bool found = false;
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2003-04-25 16:00:03 +00:00
|
|
|
std::list<MenuTimestamp *>::iterator it = m_menu_timestamps.begin();
|
|
|
|
std::list<MenuTimestamp *>::iterator it_end = m_menu_timestamps.end();
|
2002-12-01 13:42:15 +00:00
|
|
|
for (; it != it_end; ++it) {
|
2003-04-25 16:00:03 +00:00
|
|
|
if ((*it)->filename == filename) {
|
|
|
|
found = true;
|
|
|
|
break;
|
|
|
|
}
|
2002-12-01 13:42:15 +00:00
|
|
|
}
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
if (! found) {
|
|
|
|
struct stat buf;
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
if (! stat(filename, &buf)) {
|
|
|
|
MenuTimestamp *ts = new MenuTimestamp;
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2003-04-25 16:00:03 +00:00
|
|
|
ts->filename = filename;
|
2002-12-01 13:42:15 +00:00
|
|
|
ts->timestamp = buf.st_ctime;
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2003-04-25 16:00:03 +00:00
|
|
|
m_menu_timestamps.push_back(ts);
|
2002-12-01 13:42:15 +00:00
|
|
|
}
|
|
|
|
}
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
|
2003-05-13 00:20:49 +00:00
|
|
|
void Fluxbox::clearMenuFilenames() {
|
|
|
|
std::list<MenuTimestamp *>::iterator it = m_menu_timestamps.begin();
|
|
|
|
std::list<MenuTimestamp *>::iterator it_end = m_menu_timestamps.end();
|
|
|
|
for (; it != it_end; ++it)
|
|
|
|
delete *it;
|
|
|
|
|
|
|
|
m_menu_timestamps.erase(m_menu_timestamps.begin(), m_menu_timestamps.end());
|
|
|
|
}
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2002-10-15 20:41:08 +00:00
|
|
|
void Fluxbox::timeout() {
|
2003-04-25 16:00:03 +00:00
|
|
|
if (m_reconfigure_wait)
|
2002-12-01 13:42:15 +00:00
|
|
|
real_reconfigure();
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2003-04-25 16:00:03 +00:00
|
|
|
if (m_reread_menu_wait)
|
2002-12-01 13:42:15 +00:00
|
|
|
real_rereadMenu();
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2003-04-25 16:00:03 +00:00
|
|
|
m_reconfigure_wait = m_reread_menu_wait = false;
|
2001-12-11 20:47:02 +00:00
|
|
|
}
|
|
|
|
|
2002-07-13 14:04:46 +00:00
|
|
|
// set focused window
|
2003-07-28 15:06:36 +00:00
|
|
|
void Fluxbox::setFocusedWindow(WinClient *client) {
|
2003-04-29 12:39:45 +00:00
|
|
|
// already focused
|
2003-07-28 15:06:36 +00:00
|
|
|
if (m_focused_window == client) {
|
2003-05-11 15:24:09 +00:00
|
|
|
#ifdef DEBUG
|
|
|
|
cerr<<"Focused window already win"<<endl;
|
|
|
|
#endif // DEBUG
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
#ifdef DEBUG
|
|
|
|
cerr<<"-----------------"<<endl;
|
2003-07-28 15:06:36 +00:00
|
|
|
cerr<<"Setting Focused window = "<<client<<endl;
|
2003-05-11 15:24:09 +00:00
|
|
|
cerr<<"Current Focused window = "<<m_focused_window<<endl;
|
|
|
|
cerr<<"------------------"<<endl;
|
|
|
|
#endif // DEBUG
|
2002-12-01 13:42:15 +00:00
|
|
|
BScreen *old_screen = 0, *screen = 0;
|
2003-07-28 15:06:36 +00:00
|
|
|
WinClient *old_client = 0;
|
2002-12-01 13:42:15 +00:00
|
|
|
Workspace *old_wkspc = 0, *wkspc = 0;
|
|
|
|
|
2003-04-25 16:00:03 +00:00
|
|
|
if (m_focused_window != 0) {
|
2003-05-10 14:32:35 +00:00
|
|
|
// check if m_focused_window is valid
|
|
|
|
bool found = false;
|
2003-07-28 15:06:36 +00:00
|
|
|
std::map<Window, WinClient *>::iterator it = m_window_search.begin();
|
|
|
|
std::map<Window, WinClient *>::iterator it_end = m_window_search.end();
|
2003-05-10 14:32:35 +00:00
|
|
|
for (; it != it_end; ++it) {
|
|
|
|
if (it->second == m_focused_window) {
|
|
|
|
// we found it, end loop
|
|
|
|
found = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2003-04-15 00:50:25 +00:00
|
|
|
|
2003-05-10 14:32:35 +00:00
|
|
|
if (!found) {
|
|
|
|
m_focused_window = 0;
|
|
|
|
} else {
|
2003-07-28 15:06:36 +00:00
|
|
|
old_client = m_focused_window;
|
|
|
|
old_screen = &old_client->screen();
|
2001-12-11 20:47:02 +00:00
|
|
|
|
2003-07-28 15:06:36 +00:00
|
|
|
if (old_client->fbwindow()) {
|
|
|
|
FluxboxWindow *old_win = old_client->fbwindow();
|
|
|
|
old_wkspc = old_screen->getWorkspace(old_win->workspaceNumber());
|
2003-05-10 14:32:35 +00:00
|
|
|
|
2003-07-28 15:06:36 +00:00
|
|
|
if (!client || client->fbwindow() != old_win)
|
|
|
|
old_win->setFocusFlag(false);
|
|
|
|
}
|
2003-05-10 14:32:35 +00:00
|
|
|
}
|
2002-12-01 13:42:15 +00:00
|
|
|
}
|
|
|
|
|
2003-07-28 15:06:36 +00:00
|
|
|
if (client && client->fbwindow() && !client->fbwindow()->isIconic()) {
|
|
|
|
FluxboxWindow *win = client->fbwindow();
|
2002-12-01 13:42:15 +00:00
|
|
|
// make sure we have a valid win pointer with a valid screen
|
|
|
|
ScreenList::iterator winscreen =
|
2003-04-25 16:00:03 +00:00
|
|
|
std::find(m_screen_list.begin(), m_screen_list.end(),
|
2003-07-28 15:06:36 +00:00
|
|
|
&client->screen());
|
2003-04-25 16:00:03 +00:00
|
|
|
if (winscreen == m_screen_list.end()) {
|
|
|
|
m_focused_window = 0; // the window pointer wasn't valid, mark no window focused
|
2002-12-01 13:42:15 +00:00
|
|
|
} else {
|
|
|
|
screen = *winscreen;
|
2003-07-28 15:06:36 +00:00
|
|
|
wkspc = screen->getWorkspace(win->workspaceNumber());
|
|
|
|
m_focused_window = client; // update focused window
|
|
|
|
win->setCurrentClient(*client, false); // don't setinputfocus
|
2003-04-25 16:00:03 +00:00
|
|
|
win->setFocusFlag(true); // set focus flag
|
2002-12-01 13:42:15 +00:00
|
|
|
}
|
|
|
|
} else
|
2003-04-25 16:00:03 +00:00
|
|
|
m_focused_window = 0;
|
2002-12-01 13:42:15 +00:00
|
|
|
|
2003-06-25 06:02:53 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
if (screen != 0)
|
|
|
|
screen->updateNetizenWindowFocus();
|
|
|
|
|
|
|
|
if (old_screen && old_screen != screen)
|
|
|
|
old_screen->updateNetizenWindowFocus();
|
2001-12-11 20:47:02 +00:00
|
|
|
|
|
|
|
}
|
2003-04-15 00:50:25 +00:00
|
|
|
|
2003-05-04 23:38:06 +00:00
|
|
|
/**
|
|
|
|
* This function is called whenever we aren't quite sure what
|
|
|
|
* focus is meant to be, it'll make things right ;-)
|
|
|
|
* last_focused is set to something if we want to make use of the
|
|
|
|
* previously focused window (it must NOT be set focused now, it
|
|
|
|
* is probably dying).
|
|
|
|
*/
|
2003-05-11 15:24:09 +00:00
|
|
|
void Fluxbox::revertFocus(BScreen &screen) {
|
2003-05-04 23:38:06 +00:00
|
|
|
// Relevant resources:
|
|
|
|
// resource.focus_last = whether we focus last focused when changing workspace
|
|
|
|
// Fluxbox::FocusModel = sloppy, click, whatever
|
2003-05-15 12:00:46 +00:00
|
|
|
WinClient *next_focus = screen.getLastFocusedWindow(screen.currentWorkspaceID());
|
2003-05-04 23:38:06 +00:00
|
|
|
|
2003-05-11 23:44:09 +00:00
|
|
|
// if setting focus fails, or isn't possible, fallback correctly
|
|
|
|
if (!(next_focus && next_focus->fbwindow() &&
|
|
|
|
next_focus->fbwindow()->setCurrentClient(*next_focus, true))) {
|
2003-05-11 15:24:09 +00:00
|
|
|
setFocusedWindow(0); // so we don't get dangling m_focused_window pointer
|
|
|
|
switch (screen.getFocusModel()) {
|
2003-05-04 23:38:06 +00:00
|
|
|
case SLOPPYFOCUS:
|
|
|
|
case SEMISLOPPYFOCUS:
|
|
|
|
XSetInputFocus(FbTk::App::instance()->display(),
|
|
|
|
PointerRoot, None, CurrentTime);
|
|
|
|
break;
|
|
|
|
case CLICKTOFOCUS:
|
|
|
|
XSetInputFocus(FbTk::App::instance()->display(),
|
2003-05-11 15:24:09 +00:00
|
|
|
screen.rootWindow().window(),
|
2003-05-04 23:38:06 +00:00
|
|
|
RevertToPointerRoot, CurrentTime);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2003-05-10 14:32:35 +00:00
|
|
|
void Fluxbox::watchKeyRelease(BScreen &screen, unsigned int mods) {
|
2003-04-27 04:56:18 +00:00
|
|
|
if (mods == 0) {
|
|
|
|
cerr<<"WARNING: attempt to grab without modifiers!"<<endl;
|
|
|
|
return;
|
|
|
|
}
|
2003-05-10 14:32:35 +00:00
|
|
|
m_watching_screen = &screen;
|
2003-04-25 16:00:03 +00:00
|
|
|
m_watch_keyrelease = mods;
|
|
|
|
XGrabKeyboard(FbTk::App::instance()->display(),
|
2003-05-10 23:07:42 +00:00
|
|
|
screen.rootWindow().window(), True,
|
2003-04-15 00:50:25 +00:00
|
|
|
GrabModeAsync, GrabModeAsync, CurrentTime);
|
|
|
|
}
|