2003-04-26 07:57:00 +00:00
|
|
|
// Remember.cc for Fluxbox Window Manager
|
|
|
|
// Copyright (c) 2002 Xavier Brouckaert
|
|
|
|
// Copyright (c) 2003 Henrik Kinnunen (fluxgen at users.sourceforge.net)
|
2003-05-10 22:47:55 +00:00
|
|
|
// and Simon Bowden (rathnor at users.sourceforge.net)
|
2003-04-26 07:57:00 +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,
|
|
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
|
|
// 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-05-26 11:27:31 +00:00
|
|
|
// $Id: Remember.cc,v 1.18 2003/05/26 11:27:31 rathnor Exp $
|
2003-04-26 07:57:00 +00:00
|
|
|
|
|
|
|
#include "Remember.hh"
|
|
|
|
#include "StringUtil.hh"
|
2003-04-26 12:46:18 +00:00
|
|
|
#include "Screen.hh"
|
|
|
|
#include "Window.hh"
|
2003-04-26 07:57:00 +00:00
|
|
|
#include "WinClient.hh"
|
|
|
|
#include "FbMenu.hh"
|
|
|
|
#include "MenuItem.hh"
|
2003-04-26 12:46:18 +00:00
|
|
|
#include "App.hh"
|
2003-04-26 07:57:00 +00:00
|
|
|
|
|
|
|
// TODO get rid of these
|
|
|
|
#define RC_PATH "fluxbox"
|
|
|
|
#define RC_INIT_FILE "init"
|
|
|
|
|
2003-04-26 12:46:18 +00:00
|
|
|
#include <X11/Xlib.h>
|
|
|
|
|
2003-04-26 07:57:00 +00:00
|
|
|
//use GNU extensions
|
|
|
|
#ifndef _GNU_SOURCE
|
|
|
|
#define _GNU_SOURCE
|
|
|
|
#endif // _GNU_SOURCE
|
|
|
|
|
2003-04-26 12:46:18 +00:00
|
|
|
|
2003-04-26 07:57:00 +00:00
|
|
|
#include <iostream>
|
|
|
|
#include <sstream>
|
|
|
|
#include <fstream>
|
2003-04-26 11:24:55 +00:00
|
|
|
#include <string>
|
|
|
|
#include <memory>
|
2003-04-26 07:57:00 +00:00
|
|
|
|
2003-04-26 12:46:18 +00:00
|
|
|
using namespace std;
|
|
|
|
|
2003-04-26 07:57:00 +00:00
|
|
|
#ifndef MAXPATHLEN
|
|
|
|
#define MAXPATHLEN 255
|
|
|
|
#endif // MAXPATHLEN
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
class RememberMenuItem : public FbTk::MenuItem {
|
|
|
|
public:
|
|
|
|
RememberMenuItem(const char *label, Remember &remember,
|
|
|
|
FluxboxWindow &fbwin,
|
|
|
|
Remember::Attribute attrib) :
|
|
|
|
FbTk::MenuItem(label), m_remember(remember),
|
|
|
|
m_win(fbwin), m_attrib(attrib) {}
|
|
|
|
|
|
|
|
bool isSelected() const {
|
|
|
|
return m_remember.isRemembered(m_win.winClient(), m_attrib);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool isEnabled() const {
|
|
|
|
if (m_attrib != Remember::REM_JUMPWORKSPACE)
|
|
|
|
return true;
|
|
|
|
else
|
|
|
|
return (m_remember.isRemembered(m_win.winClient(), Remember::REM_WORKSPACE));
|
|
|
|
}
|
|
|
|
|
|
|
|
void click(int button, int time) {
|
|
|
|
if (isSelected()) {
|
|
|
|
m_remember.forgetAttrib(m_win.winClient(), m_attrib);
|
|
|
|
} else {
|
|
|
|
m_remember.rememberAttrib(m_win.winClient(), m_attrib);
|
|
|
|
}
|
|
|
|
m_remember.save();
|
|
|
|
FbTk::MenuItem::click(button, time);
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
// my remember manager
|
|
|
|
Remember &m_remember;
|
|
|
|
FluxboxWindow &m_win;
|
|
|
|
Remember::Attribute m_attrib;
|
|
|
|
};
|
|
|
|
|
|
|
|
FbTk::Menu *createRememberMenu(Remember &remember, FluxboxWindow &win) {
|
|
|
|
// each fluxboxwindow has its own windowmenu
|
|
|
|
// so we also create a remember menu just for it...
|
2003-05-11 13:36:12 +00:00
|
|
|
BScreen &screen = win.screen();
|
2003-04-26 07:57:00 +00:00
|
|
|
FbTk::Menu *menu = new FbMenu(*screen.menuTheme(),
|
2003-05-15 12:00:46 +00:00
|
|
|
screen.screenNumber(),
|
2003-05-15 23:30:07 +00:00
|
|
|
screen.imageControl(),
|
2003-04-26 07:57:00 +00:00
|
|
|
*screen.layerManager().getLayer(Fluxbox::instance()->getMenuLayer()));
|
2003-05-08 10:55:33 +00:00
|
|
|
menu->disableTitle();
|
2003-04-26 07:57:00 +00:00
|
|
|
// TODO: nls
|
|
|
|
menu->insert(new RememberMenuItem("Workspace", remember, win,
|
2003-04-26 12:46:18 +00:00
|
|
|
Remember::REM_WORKSPACE));
|
2003-04-26 07:57:00 +00:00
|
|
|
menu->insert(new RememberMenuItem("Jump to workspace", remember, win,
|
2003-04-26 12:46:18 +00:00
|
|
|
Remember::REM_JUMPWORKSPACE));
|
2003-04-26 07:57:00 +00:00
|
|
|
menu->insert(new RememberMenuItem("Dimensions", remember, win,
|
2003-04-26 12:46:18 +00:00
|
|
|
Remember::REM_DIMENSIONS));
|
2003-04-26 07:57:00 +00:00
|
|
|
menu->insert(new RememberMenuItem("Position", remember, win,
|
2003-04-26 12:46:18 +00:00
|
|
|
Remember::REM_POSITION));
|
2003-04-26 07:57:00 +00:00
|
|
|
menu->insert(new RememberMenuItem("Sticky", remember, win,
|
2003-04-26 12:46:18 +00:00
|
|
|
Remember::REM_STUCKSTATE));
|
2003-04-26 07:57:00 +00:00
|
|
|
menu->insert(new RememberMenuItem("Decorations", remember, win,
|
2003-04-26 12:46:18 +00:00
|
|
|
Remember::REM_DECOSTATE));
|
2003-04-26 07:57:00 +00:00
|
|
|
menu->insert(new RememberMenuItem("Shaded", remember, win,
|
2003-04-26 12:46:18 +00:00
|
|
|
Remember::REM_SHADEDSTATE));
|
2003-04-26 13:47:53 +00:00
|
|
|
menu->insert(new RememberMenuItem("Layer", remember, win,
|
|
|
|
Remember::REM_LAYER));
|
2003-04-26 12:46:18 +00:00
|
|
|
// menu->insert(new RememberMenuItem("Tab", remember, win,
|
|
|
|
// Remember::REM_TABSTATE));
|
2003-04-26 07:57:00 +00:00
|
|
|
menu->insert(new RememberMenuItem("Save on close", remember, win,
|
2003-04-26 12:46:18 +00:00
|
|
|
Remember::REM_SAVEONCLOSE));
|
2003-04-26 07:57:00 +00:00
|
|
|
|
|
|
|
menu->update();
|
|
|
|
return menu;
|
|
|
|
};
|
|
|
|
|
|
|
|
const char * getWMClass(Window w) {
|
|
|
|
XClassHint ch;
|
|
|
|
|
|
|
|
if (XGetClassHint(FbTk::App::instance()->display(), w, &ch) == 0) {
|
|
|
|
cerr<<"Failed to read class hint!"<<endl;
|
|
|
|
return 0;
|
|
|
|
} else {
|
2003-04-27 15:53:53 +00:00
|
|
|
string m_instance_name;
|
2003-04-26 07:57:00 +00:00
|
|
|
if (ch.res_name != 0) {
|
2003-04-27 15:53:53 +00:00
|
|
|
m_instance_name = const_cast<char *>(ch.res_name);
|
2003-04-26 07:57:00 +00:00
|
|
|
XFree(ch.res_name);
|
2003-04-27 15:53:53 +00:00
|
|
|
} else
|
|
|
|
m_instance_name = "";
|
2003-04-26 07:57:00 +00:00
|
|
|
|
|
|
|
if (ch.res_class != 0) {
|
2003-04-27 15:53:53 +00:00
|
|
|
//m_class_name = const_cast<char *>(ch.res_class);
|
2003-04-26 07:57:00 +00:00
|
|
|
XFree(ch.res_class);
|
|
|
|
} else {
|
2003-04-27 15:53:53 +00:00
|
|
|
//m_class_name = "";
|
2003-04-26 07:57:00 +00:00
|
|
|
}
|
2003-04-27 15:53:53 +00:00
|
|
|
return m_instance_name.c_str();
|
2003-04-26 07:57:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-04-26 12:46:18 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
Application::Application() {
|
|
|
|
workspace_remember =
|
|
|
|
dimensions_remember =
|
|
|
|
position_remember =
|
|
|
|
stuckstate_remember =
|
|
|
|
decostate_remember =
|
|
|
|
shadedstate_remember =
|
|
|
|
tabstate_remember =
|
|
|
|
jumpworkspace_remember =
|
2003-04-26 13:47:53 +00:00
|
|
|
layer_remember =
|
2003-04-26 12:46:18 +00:00
|
|
|
save_on_close_remember = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
Remember::Remember() {
|
|
|
|
load();
|
|
|
|
}
|
|
|
|
|
|
|
|
Application* Remember::add(const char* app_name) {
|
|
|
|
if (!app_name)
|
|
|
|
return 0;
|
|
|
|
Application* a = new Application();
|
|
|
|
apps[app_name] = a;
|
|
|
|
return a;
|
|
|
|
}
|
2003-04-26 07:57:00 +00:00
|
|
|
|
|
|
|
Application* Remember::find(WinClient &winclient) {
|
2003-04-26 12:46:18 +00:00
|
|
|
return find(getWMClass(winclient.window()));
|
2003-04-26 07:57:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Application* Remember::add(WinClient &winclient) {
|
2003-04-26 13:14:37 +00:00
|
|
|
return add(getWMClass(winclient.window()));
|
2003-04-26 07:57:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Application* Remember::find(const char* app_name) {
|
|
|
|
if (!app_name)
|
2003-04-26 12:46:18 +00:00
|
|
|
return 0;
|
2003-04-26 07:57:00 +00:00
|
|
|
Apps::iterator i = apps.find(app_name);
|
2003-05-10 22:47:55 +00:00
|
|
|
if (i != apps.end())
|
2003-04-26 07:57:00 +00:00
|
|
|
return i->second;
|
|
|
|
else
|
2003-04-26 12:46:18 +00:00
|
|
|
return 0;
|
2003-04-26 07:57:00 +00:00
|
|
|
}
|
|
|
|
|
2003-05-10 22:47:55 +00:00
|
|
|
int Remember::parseApp(ifstream &file, Application &app) {
|
2003-04-26 12:01:55 +00:00
|
|
|
string line;
|
2003-04-26 07:57:00 +00:00
|
|
|
int row = 0;
|
|
|
|
while (! file.eof()) {
|
|
|
|
if (getline(file, line)) {
|
|
|
|
row++;
|
|
|
|
if (line[0] != '#') { //the line is commented
|
|
|
|
int parse_pos = 0, err = 0;
|
2003-04-26 12:01:55 +00:00
|
|
|
string str_key, str_label;
|
2003-04-26 18:58:30 +00:00
|
|
|
err = FbTk::StringUtil::getStringBetween(str_key,
|
|
|
|
line.c_str(),
|
|
|
|
'[', ']');
|
2003-04-26 07:57:00 +00:00
|
|
|
if (err > 0 ) {
|
|
|
|
parse_pos += err;
|
2003-04-26 18:58:30 +00:00
|
|
|
err = FbTk::StringUtil::getStringBetween(str_label,
|
2003-04-26 12:46:18 +00:00
|
|
|
line.c_str() + parse_pos,
|
|
|
|
'{', '}');
|
2003-04-26 07:57:00 +00:00
|
|
|
if (err>0) {
|
|
|
|
parse_pos += err;
|
|
|
|
}
|
|
|
|
} else
|
|
|
|
continue; //read next line
|
2003-05-10 22:47:55 +00:00
|
|
|
|
2003-04-26 07:57:00 +00:00
|
|
|
if (!str_key.size())
|
|
|
|
continue; //read next line
|
|
|
|
if (str_key == "Workspace") {
|
|
|
|
unsigned int w;
|
2003-04-26 12:01:55 +00:00
|
|
|
istringstream iss(str_label.c_str());
|
2003-04-26 07:57:00 +00:00
|
|
|
iss >> w;
|
2003-05-10 22:47:55 +00:00
|
|
|
app.rememberWorkspace(w);
|
2003-04-26 13:47:53 +00:00
|
|
|
} else if (str_key == "Layer") {
|
|
|
|
unsigned int l;
|
|
|
|
istringstream iss(str_label.c_str());
|
|
|
|
iss >> l;
|
2003-05-10 22:47:55 +00:00
|
|
|
app.rememberLayer(l);
|
2003-04-26 07:57:00 +00:00
|
|
|
} else if (str_key == "Dimensions") {
|
|
|
|
unsigned int h,w;
|
2003-04-26 12:01:55 +00:00
|
|
|
istringstream iss(str_label.c_str());
|
2003-04-26 07:57:00 +00:00
|
|
|
iss >> w >> h;
|
2003-05-10 22:47:55 +00:00
|
|
|
app.rememberDimensions(w,h);
|
2003-04-26 07:57:00 +00:00
|
|
|
} else if (str_key == "Position") {
|
|
|
|
unsigned int x,y;
|
2003-04-26 12:01:55 +00:00
|
|
|
istringstream iss(str_label);
|
2003-04-26 07:57:00 +00:00
|
|
|
iss >> x >> y;
|
2003-05-10 22:47:55 +00:00
|
|
|
app.rememberPosition(x,y);
|
2003-04-26 07:57:00 +00:00
|
|
|
} else if (str_key == "Shaded") {
|
2003-05-10 22:47:55 +00:00
|
|
|
app.rememberShadedstate((str_label=="yes"));
|
2003-04-26 07:57:00 +00:00
|
|
|
} else if (str_key == "Tab") {
|
2003-05-10 22:47:55 +00:00
|
|
|
app.rememberTabstate((str_label=="yes"));
|
2003-04-26 07:57:00 +00:00
|
|
|
} else if (str_key == "Deco") {
|
|
|
|
if (str_label == "NONE") {
|
2003-05-10 22:47:55 +00:00
|
|
|
app.rememberDecostate((unsigned int) 0);
|
2003-04-26 07:57:00 +00:00
|
|
|
} else if (str_label == "NORMAL") {
|
2003-05-10 22:47:55 +00:00
|
|
|
app.rememberDecostate((unsigned int) 0xfffffff);
|
2003-04-26 07:57:00 +00:00
|
|
|
} else if (str_label == "TINY") {
|
2003-05-10 22:47:55 +00:00
|
|
|
app.rememberDecostate((unsigned int)
|
2003-04-26 12:46:18 +00:00
|
|
|
FluxboxWindow::DECORM_TITLEBAR
|
|
|
|
| FluxboxWindow::DECORM_ICONIFY
|
|
|
|
| FluxboxWindow::DECORM_MENU
|
|
|
|
);
|
2003-04-26 07:57:00 +00:00
|
|
|
} else if (str_label == "TOOL") {
|
2003-05-10 22:47:55 +00:00
|
|
|
app.rememberDecostate((unsigned int)
|
2003-04-26 12:46:18 +00:00
|
|
|
FluxboxWindow::DECORM_TITLEBAR
|
|
|
|
| FluxboxWindow::DECORM_MENU
|
|
|
|
);
|
2003-05-26 04:24:24 +00:00
|
|
|
} else if (str_label == "BORDER") {
|
|
|
|
app.rememberDecostate((unsigned int)
|
|
|
|
FluxboxWindow::DECORM_BORDER
|
|
|
|
| FluxboxWindow::DECORM_MENU
|
|
|
|
);
|
2003-04-26 07:57:00 +00:00
|
|
|
} else {
|
|
|
|
unsigned int mask;
|
|
|
|
const char * str = str_label.c_str();
|
|
|
|
// it'll have at least one char and \0, so this is safe
|
2003-04-26 12:01:55 +00:00
|
|
|
istringstream iss(str);
|
2003-04-26 07:57:00 +00:00
|
|
|
// check for hex
|
|
|
|
if (str[0] == '0' && str[1] == 'x') {
|
|
|
|
iss.seekg(2);
|
|
|
|
iss >> hex;
|
|
|
|
}
|
|
|
|
iss >> mask ;
|
2003-05-10 22:47:55 +00:00
|
|
|
app.rememberDecostate(mask);
|
2003-04-26 07:57:00 +00:00
|
|
|
}
|
|
|
|
} else if (str_key == "Sticky") {
|
2003-05-10 22:47:55 +00:00
|
|
|
app.rememberStuckstate((str_label=="yes"));
|
2003-04-26 07:57:00 +00:00
|
|
|
} else if (str_key == "Jump") {
|
2003-05-10 22:47:55 +00:00
|
|
|
app.rememberJumpworkspace((str_label=="yes"));
|
2003-04-26 07:57:00 +00:00
|
|
|
} else if (str_key == "Close") {
|
2003-05-10 22:47:55 +00:00
|
|
|
app.rememberSaveOnClose((str_label=="yes"));
|
2003-04-26 07:57:00 +00:00
|
|
|
} else if (str_key == "end") {
|
|
|
|
return row;
|
|
|
|
} else {
|
|
|
|
cerr << "Unsupported apps key = " << str_key << endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return row;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Remember::load() {
|
2003-04-26 12:46:18 +00:00
|
|
|
|
|
|
|
string apps_string = getenv("HOME")+string("/.")+RC_PATH+string("/")+"apps";
|
2003-04-26 07:57:00 +00:00
|
|
|
#ifdef DEBUG
|
2003-04-26 12:46:18 +00:00
|
|
|
cerr<<__FILE__<<"("<<__FUNCTION__<<"): Loading apps file ["<<apps_string<<"]"<<endl;
|
2003-04-26 07:57:00 +00:00
|
|
|
#endif // DEBUG
|
2003-04-26 12:01:55 +00:00
|
|
|
ifstream apps_file(apps_string.c_str());
|
2003-04-26 12:46:18 +00:00
|
|
|
|
2003-04-26 07:57:00 +00:00
|
|
|
if (!apps_file.fail()) {
|
|
|
|
if (!apps_file.eof()) {
|
2003-04-26 12:01:55 +00:00
|
|
|
string line;
|
2003-04-26 07:57:00 +00:00
|
|
|
int row = 0;
|
|
|
|
while (getline(apps_file, line) && ! apps_file.eof()) {
|
|
|
|
row++;
|
|
|
|
if (line[0] == '#')
|
|
|
|
continue;
|
2003-04-26 12:01:55 +00:00
|
|
|
string key;
|
2003-04-26 07:57:00 +00:00
|
|
|
int pos=0;
|
2003-04-26 18:58:30 +00:00
|
|
|
int err = FbTk::StringUtil::getStringBetween(key,
|
|
|
|
line.c_str(),
|
|
|
|
'[', ']');
|
2003-04-26 07:57:00 +00:00
|
|
|
|
2003-05-10 22:47:55 +00:00
|
|
|
if (err > 0 && key == "app") {
|
2003-04-26 07:57:00 +00:00
|
|
|
pos += err;
|
2003-04-26 12:01:55 +00:00
|
|
|
string label;
|
2003-04-26 18:58:30 +00:00
|
|
|
err = FbTk::StringUtil::getStringBetween(label,
|
|
|
|
line.c_str()+pos,
|
|
|
|
'(', ')');
|
2003-04-26 07:57:00 +00:00
|
|
|
if (err>0) {
|
2003-05-10 22:47:55 +00:00
|
|
|
Application *app = 0;
|
2003-04-26 07:57:00 +00:00
|
|
|
Apps::iterator i = apps.find(label);
|
2003-05-10 22:47:55 +00:00
|
|
|
if (i == apps.end()) {
|
|
|
|
app = new Application();
|
|
|
|
apps[label] = app;
|
2003-04-26 07:57:00 +00:00
|
|
|
} else
|
2003-05-10 22:47:55 +00:00
|
|
|
app = i->second;
|
|
|
|
row += parseApp(apps_file, *app);
|
2003-04-26 07:57:00 +00:00
|
|
|
} else
|
|
|
|
cerr<<"Error1 in apps file. Line("<<row<<")"<<endl;
|
|
|
|
} else
|
|
|
|
cerr<<"Error2 in apps file. Line("<<row<<")"<<endl;
|
|
|
|
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
#ifdef DEBUG
|
2003-04-26 12:46:18 +00:00
|
|
|
cerr<<__FILE__<<"("<<__FUNCTION__<< ") Empty apps file" << endl;
|
2003-04-26 07:57:00 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
cerr << "apps file failure" << endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Remember::save() {
|
|
|
|
#ifdef DEBUG
|
2003-04-26 12:46:18 +00:00
|
|
|
cerr<<__FILE__<<"("<<__FUNCTION__<<"): Saving apps file..."<<endl;
|
2003-04-26 07:57:00 +00:00
|
|
|
#endif // DEBUG
|
2003-04-26 12:01:55 +00:00
|
|
|
string apps_string = getenv("HOME")+string("/.")+RC_PATH+string("/")+"apps";
|
|
|
|
ofstream apps_file(apps_string.c_str());
|
2003-04-26 07:57:00 +00:00
|
|
|
Apps::iterator it = apps.begin();
|
|
|
|
Apps::iterator it_end = apps.end();
|
|
|
|
for (; it != it_end; ++it) {
|
|
|
|
apps_file << "[app] (" << it->first << ")" << endl;
|
|
|
|
Application *a = it->second;
|
|
|
|
if (a->workspace_remember) {
|
|
|
|
apps_file << " [Workspace]\t{" << a->workspace << "}" << endl;
|
|
|
|
}
|
|
|
|
if (a->dimensions_remember) {
|
|
|
|
apps_file << " [Dimensions]\t{" << a->w << " " << a->h << "}" << endl;
|
|
|
|
}
|
|
|
|
if (a->position_remember) {
|
|
|
|
apps_file << " [Position]\t{" << a->x << " " << a->y << "}" << endl;
|
|
|
|
}
|
|
|
|
if (a->shadedstate_remember) {
|
|
|
|
apps_file << " [Shaded]\t{" << ((a->shadedstate)?"yes":"no") << "}" << endl;
|
|
|
|
}
|
|
|
|
if (a->tabstate_remember) {
|
|
|
|
apps_file << " [Tab]\t\t{" << ((a->tabstate)?"yes":"no") << "}" << endl;
|
|
|
|
}
|
|
|
|
if (a->decostate_remember) {
|
|
|
|
switch (a->decostate) {
|
|
|
|
case (0) :
|
|
|
|
apps_file << " [Deco]\t{NONE}" << endl;
|
|
|
|
break;
|
|
|
|
case (0xffffffff):
|
|
|
|
case (FluxboxWindow::DECORM_LAST - 1):
|
|
|
|
apps_file << " [Deco]\t{NORMAL}" << endl;
|
|
|
|
break;
|
|
|
|
case (FluxboxWindow::DECORM_TITLEBAR
|
|
|
|
| FluxboxWindow::DECORM_ICONIFY
|
|
|
|
| FluxboxWindow::DECORM_MENU):
|
|
|
|
apps_file << " [Deco]\t{TOOL}" << endl;
|
|
|
|
break;
|
|
|
|
case (FluxboxWindow::DECORM_TITLEBAR
|
|
|
|
| FluxboxWindow::DECORM_MENU):
|
|
|
|
apps_file << " [Deco]\t{TINY}" << endl;
|
|
|
|
break;
|
2003-05-26 11:27:31 +00:00
|
|
|
case (FluxboxWindow::DECORM_BORDER
|
|
|
|
| FluxboxWindow::DECORM_MENU):
|
|
|
|
apps_file << " [Deco]\t{BORDER}" << endl;
|
|
|
|
break;
|
2003-04-26 07:57:00 +00:00
|
|
|
default:
|
|
|
|
apps_file << " [Deco]\t{0x"<<hex<<a->decostate<<dec<<"}"<<endl;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (a->stuckstate_remember) {
|
|
|
|
apps_file << " [Sticky]\t{" << ((a->stuckstate)?"yes":"no") << "}" << endl;
|
|
|
|
}
|
|
|
|
if (a->jumpworkspace_remember) {
|
|
|
|
apps_file << " [Jump]\t{" << ((a->jumpworkspace)?"yes":"no") << "}" << endl;
|
|
|
|
}
|
2003-04-26 13:47:53 +00:00
|
|
|
if (a->layer_remember) {
|
|
|
|
apps_file << " [Layer]\t{" << a->layer << "}" << endl;
|
|
|
|
}
|
2003-04-26 07:57:00 +00:00
|
|
|
if (a->save_on_close_remember) {
|
|
|
|
apps_file << " [Close]\t{" << ((a->save_on_close)?"yes":"no") << "}" << endl;
|
|
|
|
}
|
|
|
|
apps_file << "[end]" << endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Remember::isRemembered(WinClient &winclient, Attribute attrib) {
|
|
|
|
Application *app = find(winclient);
|
|
|
|
if (!app) return false;
|
|
|
|
switch (attrib) {
|
|
|
|
case REM_WORKSPACE:
|
|
|
|
return app->workspace_remember;
|
|
|
|
break;
|
|
|
|
case REM_DIMENSIONS:
|
|
|
|
return app->dimensions_remember;
|
|
|
|
break;
|
|
|
|
case REM_POSITION:
|
|
|
|
return app->position_remember;
|
|
|
|
break;
|
|
|
|
case REM_STUCKSTATE:
|
|
|
|
return app->stuckstate_remember;
|
|
|
|
break;
|
|
|
|
case REM_DECOSTATE:
|
|
|
|
return app->decostate_remember;
|
|
|
|
break;
|
|
|
|
case REM_SHADEDSTATE:
|
|
|
|
return app->shadedstate_remember;
|
|
|
|
break;
|
2003-04-26 12:46:18 +00:00
|
|
|
// case REM_TABSTATE:
|
|
|
|
// return app->tabstate_remember;
|
|
|
|
// break;
|
2003-04-26 07:57:00 +00:00
|
|
|
case REM_JUMPWORKSPACE:
|
|
|
|
return app->jumpworkspace_remember;
|
|
|
|
break;
|
2003-04-26 13:47:53 +00:00
|
|
|
case REM_LAYER:
|
|
|
|
return app->layer_remember;
|
|
|
|
break;
|
2003-04-26 07:57:00 +00:00
|
|
|
case REM_SAVEONCLOSE:
|
|
|
|
return app->save_on_close_remember;
|
|
|
|
break;
|
|
|
|
case REM_LASTATTRIB:
|
|
|
|
default:
|
|
|
|
return false; // should never get here
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Remember::rememberAttrib(WinClient &winclient, Attribute attrib) {
|
|
|
|
FluxboxWindow *win = winclient.fbwindow();
|
|
|
|
if (!win) return;
|
|
|
|
Application *app = find(winclient);
|
|
|
|
if (!app) {
|
|
|
|
app = add(winclient);
|
|
|
|
if (!app) return;
|
|
|
|
}
|
|
|
|
switch (attrib) {
|
|
|
|
case REM_WORKSPACE:
|
2003-05-15 11:17:29 +00:00
|
|
|
app->rememberWorkspace(win->workspaceNumber());
|
2003-04-26 07:57:00 +00:00
|
|
|
break;
|
|
|
|
case REM_DIMENSIONS:
|
2003-05-11 13:36:12 +00:00
|
|
|
app->rememberDimensions(win->width(), win->height());
|
2003-04-26 07:57:00 +00:00
|
|
|
break;
|
|
|
|
case REM_POSITION:
|
2003-05-15 11:17:29 +00:00
|
|
|
app->rememberPosition(win->x(), win->y());
|
2003-04-26 07:57:00 +00:00
|
|
|
break;
|
|
|
|
case REM_STUCKSTATE:
|
|
|
|
app->rememberShadedstate(win->isShaded());
|
|
|
|
break;
|
|
|
|
case REM_DECOSTATE:
|
2003-05-15 11:17:29 +00:00
|
|
|
app->rememberDecostate(win->decorationMask());
|
2003-04-26 07:57:00 +00:00
|
|
|
break;
|
|
|
|
case REM_SHADEDSTATE:
|
|
|
|
app->rememberStuckstate(win->isStuck());
|
|
|
|
break;
|
2003-04-26 12:46:18 +00:00
|
|
|
// case REM_TABSTATE:
|
|
|
|
// break;
|
2003-04-26 07:57:00 +00:00
|
|
|
case REM_JUMPWORKSPACE:
|
|
|
|
app->rememberJumpworkspace(true);
|
|
|
|
break;
|
2003-04-26 13:47:53 +00:00
|
|
|
case REM_LAYER:
|
2003-05-15 11:17:29 +00:00
|
|
|
app->rememberLayer(win->layerNum());
|
2003-04-26 13:47:53 +00:00
|
|
|
break;
|
2003-04-26 07:57:00 +00:00
|
|
|
case REM_SAVEONCLOSE:
|
|
|
|
app->rememberSaveOnClose(true);
|
|
|
|
break;
|
|
|
|
case REM_LASTATTRIB:
|
|
|
|
default:
|
|
|
|
// nothing
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Remember::forgetAttrib(WinClient &winclient, Attribute attrib) {
|
|
|
|
FluxboxWindow *win = winclient.fbwindow();
|
|
|
|
if (!win) return;
|
|
|
|
Application *app = find(winclient);
|
|
|
|
if (!app) {
|
|
|
|
app = add(winclient);
|
|
|
|
if (!app) return;
|
|
|
|
}
|
|
|
|
switch (attrib) {
|
|
|
|
case REM_WORKSPACE:
|
|
|
|
app->forgetWorkspace();
|
|
|
|
break;
|
|
|
|
case REM_DIMENSIONS:
|
|
|
|
app->forgetDimensions();
|
|
|
|
break;
|
|
|
|
case REM_POSITION:
|
|
|
|
app->forgetPosition();
|
|
|
|
break;
|
|
|
|
case REM_STUCKSTATE:
|
|
|
|
app->forgetStuckstate();
|
|
|
|
break;
|
|
|
|
case REM_DECOSTATE:
|
|
|
|
app->forgetDecostate();
|
|
|
|
break;
|
|
|
|
case REM_SHADEDSTATE:
|
|
|
|
app->forgetShadedstate();
|
|
|
|
break;
|
|
|
|
// case REM_TABSTATE:
|
|
|
|
// break;
|
|
|
|
case REM_JUMPWORKSPACE:
|
|
|
|
app->forgetJumpworkspace();
|
|
|
|
break;
|
2003-04-26 13:47:53 +00:00
|
|
|
case REM_LAYER:
|
|
|
|
app->forgetLayer();
|
|
|
|
break;
|
2003-04-26 07:57:00 +00:00
|
|
|
case REM_SAVEONCLOSE:
|
|
|
|
app->forgetSaveOnClose();
|
|
|
|
break;
|
|
|
|
case REM_LASTATTRIB:
|
|
|
|
default:
|
|
|
|
// nothing
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Remember::setupWindow(FluxboxWindow &win) {
|
|
|
|
WinClient &winclient = win.winClient();
|
|
|
|
|
2003-04-27 15:53:53 +00:00
|
|
|
// we don't touch the window if it is a transient
|
|
|
|
// of something else
|
2003-05-15 11:17:29 +00:00
|
|
|
int menupos = win.menu().numberOfItems()-2;
|
2003-05-10 22:47:55 +00:00
|
|
|
if (menupos < -1)
|
|
|
|
menupos = -1;
|
|
|
|
|
2003-04-27 15:53:53 +00:00
|
|
|
if (winclient.transientFor()) {
|
|
|
|
// still put something in the menu so people don't get confused
|
|
|
|
// so, we add a disabled item...
|
|
|
|
FbTk::MenuItem *item = new FbTk::MenuItem("Remember...");
|
|
|
|
item->setEnabled(false);
|
2003-05-15 11:17:29 +00:00
|
|
|
win.menu().insert(item, menupos);
|
|
|
|
win.menu().update();
|
2003-04-27 15:53:53 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2003-04-26 14:36:21 +00:00
|
|
|
// add the menu, this -2 is somewhat dodgy... :-/
|
|
|
|
// All windows get the remember menu.
|
|
|
|
// TODO: nls
|
2003-05-15 11:17:29 +00:00
|
|
|
win.menu().insert("Remember...",
|
2003-04-26 14:36:21 +00:00
|
|
|
createRememberMenu(*this, win),
|
2003-04-28 12:58:08 +00:00
|
|
|
menupos);
|
2003-05-15 11:17:29 +00:00
|
|
|
win.menu().reconfigure();
|
2003-04-26 14:36:21 +00:00
|
|
|
|
2003-04-26 07:57:00 +00:00
|
|
|
Application *app = find(winclient);
|
2003-05-10 22:47:55 +00:00
|
|
|
if (app == 0)
|
|
|
|
return; // nothing to do
|
2003-04-26 07:57:00 +00:00
|
|
|
|
2003-05-11 13:36:12 +00:00
|
|
|
BScreen &screen = win.screen();
|
2003-04-26 07:57:00 +00:00
|
|
|
|
|
|
|
if (app->workspace_remember) {
|
|
|
|
// TODO: fix placement to initialise properly
|
|
|
|
screen.reassociateWindow(&win, app->workspace, true);
|
|
|
|
if (app->jumpworkspace_remember)
|
|
|
|
screen.changeWorkspaceID(app->workspace);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (app->dimensions_remember)
|
|
|
|
win.resize(app->w, app->h);
|
|
|
|
|
|
|
|
if (app->position_remember)
|
|
|
|
win.move(app->x, app->y);
|
|
|
|
|
|
|
|
if (app->shadedstate_remember)
|
|
|
|
// if inconsistent...
|
|
|
|
if (win.isShaded() && !app->shadedstate ||
|
|
|
|
!win.isShaded() && app->shadedstate)
|
|
|
|
win.shade(); // toggles
|
|
|
|
|
|
|
|
// external tabs aren't available atm...
|
|
|
|
//if (app->tabstate_remember) ...
|
|
|
|
|
|
|
|
if (app->decostate_remember)
|
|
|
|
win.setDecorationMask(app->decostate);
|
|
|
|
|
|
|
|
if (app->stuckstate_remember)
|
|
|
|
// if inconsistent...
|
|
|
|
if (win.isStuck() && !app->stuckstate ||
|
|
|
|
!win.isStuck() && app->stuckstate)
|
|
|
|
win.stick(); // toggles
|
|
|
|
|
2003-04-26 13:47:53 +00:00
|
|
|
if (app->layer_remember)
|
|
|
|
win.moveToLayer(app->layer);
|
|
|
|
|
2003-04-26 07:57:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Remember::updateWindowClose(FluxboxWindow &win) {
|
|
|
|
// This doesn't work at present since fluxbox.cc is missing the windowclose stuff.
|
|
|
|
// I don't trust it (particularly winClient()) while this is the case
|
|
|
|
return;
|
|
|
|
|
|
|
|
WinClient &winclient = win.winClient();
|
|
|
|
Application *app = find(winclient);
|
|
|
|
|
|
|
|
if (!app || !(app->save_on_close_remember && app->save_on_close))
|
|
|
|
return;
|
|
|
|
|
|
|
|
for (int attrib = 0; attrib <= REM_LASTATTRIB; attrib++) {
|
|
|
|
if (isRemembered(winclient, (Attribute) attrib)) {
|
|
|
|
rememberAttrib(winclient, (Attribute) attrib);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
if (app->workspace_remember)
|
2003-05-15 11:17:29 +00:00
|
|
|
app->rememberWorkspace(win.workspaceNumber());
|
2003-04-26 07:57:00 +00:00
|
|
|
if (app->dimensions_remember)
|
2003-05-11 13:36:12 +00:00
|
|
|
app->rememberDimensions(win.width(), win.height());
|
2003-04-26 07:57:00 +00:00
|
|
|
if (app->position_remember)
|
2003-05-15 11:17:29 +00:00
|
|
|
app->rememberPosition(win.x(), win.y());
|
2003-04-26 07:57:00 +00:00
|
|
|
if (app->shadedstate_remember)
|
|
|
|
app->rememberShadedstate(win.isShaded());
|
|
|
|
// external tabs off atm
|
|
|
|
//if (app->tabstate_remember) ...
|
|
|
|
if (app->decostate_remember)
|
2003-05-15 11:17:29 +00:00
|
|
|
app->rememberDecostate(win.decorationMask());
|
2003-04-26 07:57:00 +00:00
|
|
|
if (app->stuckstate_remember)
|
|
|
|
app->rememberStuckstate(win.isStuck());
|
|
|
|
if (app->jumpworkspace_remember)
|
|
|
|
app->rememberJumpworkspace(true);
|
|
|
|
*/
|
|
|
|
save();
|
|
|
|
}
|