2003-04-26 07:57:00 +00:00
|
|
|
// Remember.cc for Fluxbox Window Manager
|
2006-02-16 06:53:05 +00:00
|
|
|
// Copyright (c) 2003 - 2006 Henrik Kinnunen (fluxgen at fluxbox dot org)
|
2005-01-24 17:14:24 +00:00
|
|
|
// and Simon Bowden (rathnor at users.sourceforge.net)
|
2005-01-24 18:34:57 +00:00
|
|
|
// Copyright (c) 2002 Xavier Brouckaert
|
2006-10-27 06:57:43 +00:00
|
|
|
//
|
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.
|
|
|
|
|
|
|
|
#include "Remember.hh"
|
2003-06-12 15:12:19 +00:00
|
|
|
#include "ClientPattern.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"
|
2003-07-10 13:23:09 +00:00
|
|
|
#include "FbCommands.hh"
|
2003-12-19 00:48:41 +00:00
|
|
|
#include "fluxbox.hh"
|
2006-02-20 21:04:35 +00:00
|
|
|
#include "Layer.hh"
|
2010-03-17 15:35:07 +00:00
|
|
|
#include "Debug.hh"
|
2003-12-19 00:48:41 +00:00
|
|
|
|
2004-06-07 11:46:05 +00:00
|
|
|
#include "FbTk/I18n.hh"
|
2003-12-19 00:48:41 +00:00
|
|
|
#include "FbTk/StringUtil.hh"
|
2006-04-23 14:51:04 +00:00
|
|
|
#include "FbTk/FileUtil.hh"
|
2003-12-19 00:48:41 +00:00
|
|
|
#include "FbTk/MenuItem.hh"
|
|
|
|
#include "FbTk/App.hh"
|
2005-02-13 16:36:54 +00:00
|
|
|
#include "FbTk/stringstream.hh"
|
2007-01-07 11:55:14 +00:00
|
|
|
#include "FbTk/Transparent.hh"
|
2008-08-14 05:53:38 +00:00
|
|
|
#include "FbTk/AutoReloadHelper.hh"
|
|
|
|
#include "FbTk/RefCount.hh"
|
2010-09-09 13:31:54 +00:00
|
|
|
#include "FbTk/Util.hh"
|
2003-04-26 07:57:00 +00:00
|
|
|
|
2007-06-29 17:25:24 +00:00
|
|
|
#ifdef HAVE_CSTRING
|
|
|
|
#include <cstring>
|
|
|
|
#else
|
|
|
|
#include <string.h>
|
|
|
|
#endif
|
2003-04-26 12:46:18 +00:00
|
|
|
|
2003-04-26 07:57:00 +00:00
|
|
|
//use GNU extensions
|
2007-12-30 15:32:53 +00:00
|
|
|
#ifndef _GNU_SOURCE
|
|
|
|
#define _GNU_SOURCE
|
2003-04-26 07:57:00 +00:00
|
|
|
#endif // _GNU_SOURCE
|
|
|
|
|
|
|
|
#include <iostream>
|
2003-07-04 01:03:41 +00:00
|
|
|
#include <set>
|
2003-04-26 07:57:00 +00:00
|
|
|
|
2003-11-17 00:20:54 +00:00
|
|
|
|
2006-10-27 06:57:43 +00:00
|
|
|
using std::cerr;
|
|
|
|
using std::endl;
|
|
|
|
using std::string;
|
|
|
|
using std::list;
|
|
|
|
using std::set;
|
|
|
|
using std::make_pair;
|
|
|
|
using std::ifstream;
|
|
|
|
using std::ofstream;
|
|
|
|
using std::hex;
|
|
|
|
using std::dec;
|
|
|
|
|
2008-08-14 05:53:38 +00:00
|
|
|
/*------------------------------------------------------------------*\
|
|
|
|
\*------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
class Application {
|
|
|
|
public:
|
2008-08-19 16:18:32 +00:00
|
|
|
Application(bool transient, bool grouped, ClientPattern *pat = 0);
|
2008-08-14 05:53:38 +00:00
|
|
|
void reset();
|
|
|
|
void forgetWorkspace() { workspace_remember = false; }
|
|
|
|
void forgetHead() { head_remember = false; }
|
|
|
|
void forgetDimensions() { dimensions_remember = false; }
|
|
|
|
void forgetPosition() { position_remember = false; }
|
|
|
|
void forgetShadedstate() { shadedstate_remember = false; }
|
|
|
|
void forgetTabstate() { tabstate_remember = false; }
|
|
|
|
void forgetDecostate() { decostate_remember = false; }
|
|
|
|
void forgetFocusHiddenstate() { focushiddenstate_remember= false; }
|
|
|
|
void forgetIconHiddenstate() { iconhiddenstate_remember= false; }
|
|
|
|
void forgetStuckstate() { stuckstate_remember = false; }
|
2011-02-03 17:50:17 +00:00
|
|
|
void forgetFocusNewWindow() { focusnewwindow_remember = false; }
|
2008-08-14 05:53:38 +00:00
|
|
|
void forgetJumpworkspace() { jumpworkspace_remember = false; }
|
|
|
|
void forgetLayer() { layer_remember = false; }
|
|
|
|
void forgetSaveOnClose() { save_on_close_remember = false; }
|
|
|
|
void forgetAlpha() { alpha_remember = false; }
|
|
|
|
void forgetMinimizedstate() { minimizedstate_remember = false; }
|
|
|
|
void forgetMaximizedstate() { maximizedstate_remember = false; }
|
|
|
|
void forgetFullscreenstate() { fullscreenstate_remember = false; }
|
|
|
|
|
|
|
|
void rememberWorkspace(int ws)
|
|
|
|
{ workspace = ws; workspace_remember = true; }
|
|
|
|
void rememberHead(int h)
|
|
|
|
{ head = h; head_remember = true; }
|
|
|
|
void rememberDimensions(int width, int height)
|
|
|
|
{ w = width; h = height; dimensions_remember = true; }
|
|
|
|
void rememberFocusHiddenstate(bool state)
|
|
|
|
{ focushiddenstate= state; focushiddenstate_remember= true; }
|
|
|
|
void rememberIconHiddenstate(bool state)
|
|
|
|
{ iconhiddenstate= state; iconhiddenstate_remember= true; }
|
2008-08-18 12:12:30 +00:00
|
|
|
void rememberPosition(int posx, int posy,
|
|
|
|
FluxboxWindow::ReferenceCorner rfc = FluxboxWindow::LEFTTOP)
|
2008-08-14 05:53:38 +00:00
|
|
|
{ x = posx; y = posy; refc = rfc; position_remember = true; }
|
|
|
|
void rememberShadedstate(bool state)
|
|
|
|
{ shadedstate = state; shadedstate_remember = true; }
|
|
|
|
void rememberTabstate(bool state)
|
|
|
|
{ tabstate = state; tabstate_remember = true; }
|
|
|
|
void rememberDecostate(unsigned int state)
|
|
|
|
{ decostate = state; decostate_remember = true; }
|
|
|
|
void rememberStuckstate(bool state)
|
|
|
|
{ stuckstate = state; stuckstate_remember = true; }
|
2011-02-03 17:50:17 +00:00
|
|
|
void rememberFocusNewWindow(bool state)
|
|
|
|
{ focusnewwindow = state; focusnewwindow_remember = true; }
|
2008-08-14 05:53:38 +00:00
|
|
|
void rememberJumpworkspace(bool state)
|
|
|
|
{ jumpworkspace = state; jumpworkspace_remember = true; }
|
|
|
|
void rememberLayer(int layernum)
|
|
|
|
{ layer = layernum; layer_remember = true; }
|
|
|
|
void rememberSaveOnClose(bool state)
|
|
|
|
{ save_on_close = state; save_on_close_remember = true; }
|
|
|
|
void rememberAlpha(int focused_a, int unfocused_a)
|
|
|
|
{ focused_alpha = focused_a; unfocused_alpha = unfocused_a; alpha_remember = true; }
|
|
|
|
void rememberMinimizedstate(bool state)
|
|
|
|
{ minimizedstate = state; minimizedstate_remember = true; }
|
|
|
|
void rememberMaximizedstate(int state)
|
|
|
|
{ maximizedstate = state; maximizedstate_remember = true; }
|
|
|
|
void rememberFullscreenstate(bool state)
|
|
|
|
{ fullscreenstate = state; fullscreenstate_remember = true; }
|
|
|
|
|
|
|
|
bool workspace_remember;
|
|
|
|
unsigned int workspace;
|
|
|
|
|
|
|
|
bool head_remember;
|
|
|
|
int head;
|
|
|
|
|
|
|
|
bool dimensions_remember;
|
|
|
|
int w,h; // width, height
|
|
|
|
|
|
|
|
bool position_remember;
|
|
|
|
int x,y;
|
2008-08-18 12:12:30 +00:00
|
|
|
FluxboxWindow::ReferenceCorner refc;
|
2008-08-14 05:53:38 +00:00
|
|
|
|
|
|
|
bool alpha_remember;
|
|
|
|
int focused_alpha;
|
|
|
|
int unfocused_alpha;
|
|
|
|
|
|
|
|
bool shadedstate_remember;
|
|
|
|
bool shadedstate;
|
|
|
|
|
|
|
|
bool tabstate_remember;
|
|
|
|
bool tabstate;
|
|
|
|
|
|
|
|
bool decostate_remember;
|
|
|
|
unsigned int decostate;
|
|
|
|
|
|
|
|
bool stuckstate_remember;
|
|
|
|
bool stuckstate;
|
|
|
|
|
2011-02-03 17:50:17 +00:00
|
|
|
bool focusnewwindow_remember;
|
|
|
|
bool focusnewwindow;
|
|
|
|
|
2008-08-14 05:53:38 +00:00
|
|
|
bool focushiddenstate_remember;
|
|
|
|
bool focushiddenstate;
|
|
|
|
|
|
|
|
bool iconhiddenstate_remember;
|
|
|
|
bool iconhiddenstate;
|
|
|
|
|
|
|
|
bool jumpworkspace_remember;
|
|
|
|
bool jumpworkspace;
|
|
|
|
|
|
|
|
bool layer_remember;
|
|
|
|
int layer;
|
|
|
|
|
|
|
|
bool save_on_close_remember;
|
|
|
|
bool save_on_close;
|
|
|
|
|
|
|
|
bool minimizedstate_remember;
|
|
|
|
bool minimizedstate;
|
|
|
|
|
|
|
|
bool maximizedstate_remember;
|
|
|
|
int maximizedstate;
|
|
|
|
|
|
|
|
bool fullscreenstate_remember;
|
|
|
|
bool fullscreenstate;
|
|
|
|
|
2008-08-19 16:18:32 +00:00
|
|
|
bool is_transient, is_grouped;
|
2008-08-14 05:53:38 +00:00
|
|
|
FbTk::RefCount<ClientPattern> group_pattern;
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2008-08-19 16:18:32 +00:00
|
|
|
Application::Application(bool transient, bool grouped, ClientPattern *pat):
|
|
|
|
is_transient(transient), is_grouped(grouped), group_pattern(pat)
|
2008-08-14 05:53:38 +00:00
|
|
|
{
|
|
|
|
reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Application::reset() {
|
|
|
|
decostate_remember =
|
|
|
|
dimensions_remember =
|
|
|
|
focushiddenstate_remember =
|
|
|
|
iconhiddenstate_remember =
|
|
|
|
jumpworkspace_remember =
|
|
|
|
layer_remember =
|
|
|
|
position_remember =
|
|
|
|
shadedstate_remember =
|
|
|
|
stuckstate_remember =
|
2011-02-03 17:50:17 +00:00
|
|
|
focusnewwindow_remember =
|
2008-08-14 05:53:38 +00:00
|
|
|
tabstate_remember =
|
|
|
|
workspace_remember =
|
|
|
|
head_remember =
|
|
|
|
alpha_remember =
|
|
|
|
minimizedstate_remember =
|
|
|
|
maximizedstate_remember =
|
|
|
|
fullscreenstate_remember =
|
|
|
|
save_on_close_remember = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*------------------------------------------------------------------*\
|
|
|
|
\*------------------------------------------------------------------*/
|
2003-04-26 12:46:18 +00:00
|
|
|
|
2003-04-26 07:57:00 +00:00
|
|
|
namespace {
|
|
|
|
|
2007-08-05 03:20:38 +00:00
|
|
|
// replace special chars like ( ) and [ ] with \( \) and \[ \]
|
2010-09-08 19:45:33 +00:00
|
|
|
string escapeRememberChars(const string& str) {
|
2007-08-05 03:20:38 +00:00
|
|
|
if (str.empty())
|
|
|
|
return str;
|
|
|
|
|
2010-09-08 19:45:33 +00:00
|
|
|
string escaped_str;
|
|
|
|
escaped_str.reserve(str.capacity());
|
|
|
|
|
|
|
|
string::const_iterator i;
|
|
|
|
for (i = str.begin(); i != str.end(); i++) {
|
|
|
|
switch (*i) {
|
|
|
|
case '(': case ')': case '[': case ']':
|
|
|
|
escaped_str += '\\';
|
|
|
|
default:
|
|
|
|
escaped_str += *i;
|
|
|
|
}
|
|
|
|
}
|
2007-08-05 03:20:38 +00:00
|
|
|
|
2010-09-08 19:45:33 +00:00
|
|
|
return escaped_str;
|
2006-05-01 01:42:17 +00:00
|
|
|
}
|
|
|
|
|
2003-04-26 07:57:00 +00:00
|
|
|
class RememberMenuItem : public FbTk::MenuItem {
|
|
|
|
public:
|
2006-05-20 15:08:14 +00:00
|
|
|
RememberMenuItem(const FbTk::FbString &label,
|
2003-04-26 07:57:00 +00:00
|
|
|
Remember::Attribute attrib) :
|
2005-06-23 03:07:25 +00:00
|
|
|
FbTk::MenuItem(label),
|
|
|
|
m_attrib(attrib) {
|
2004-12-21 16:09:36 +00:00
|
|
|
setToggleItem(true);
|
2007-12-18 05:44:17 +00:00
|
|
|
setCloseOnClick(false);
|
2004-11-09 11:28:55 +00:00
|
|
|
}
|
2003-04-26 07:57:00 +00:00
|
|
|
|
|
|
|
bool isSelected() const {
|
2008-08-30 22:36:53 +00:00
|
|
|
if (FbMenu::window() == 0)
|
2005-06-23 03:07:25 +00:00
|
|
|
return false;
|
|
|
|
|
2008-08-30 22:36:53 +00:00
|
|
|
if (FbMenu::window()->numClients()) // ensure it HAS clients
|
|
|
|
return Remember::instance().isRemembered(FbMenu::window()->winClient(), m_attrib);
|
2004-09-02 09:52:26 +00:00
|
|
|
else
|
|
|
|
return false;
|
2003-04-26 07:57:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool isEnabled() const {
|
2008-08-30 22:36:53 +00:00
|
|
|
if (FbMenu::window() == 0)
|
2005-06-23 03:07:25 +00:00
|
|
|
return false;
|
|
|
|
|
2004-12-21 16:09:36 +00:00
|
|
|
if (m_attrib != Remember::REM_JUMPWORKSPACE)
|
2003-04-26 07:57:00 +00:00
|
|
|
return true;
|
2008-08-30 22:36:53 +00:00
|
|
|
else if (FbMenu::window()->numClients())
|
|
|
|
return (Remember::instance().isRemembered(FbMenu::window()->winClient(), Remember::REM_WORKSPACE));
|
2004-09-02 09:52:26 +00:00
|
|
|
else
|
|
|
|
return false;
|
2003-04-26 07:57:00 +00:00
|
|
|
}
|
|
|
|
|
2007-12-18 05:44:17 +00:00
|
|
|
void click(int button, int time, unsigned int mods) {
|
2006-05-01 01:42:17 +00:00
|
|
|
// reconfigure only does stuff if the apps file has changed
|
2008-05-12 16:30:13 +00:00
|
|
|
Remember::instance().checkReload();
|
2008-08-30 22:36:53 +00:00
|
|
|
if (FbMenu::window() != 0) {
|
2005-06-23 03:07:25 +00:00
|
|
|
if (isSelected()) {
|
2008-08-30 22:36:53 +00:00
|
|
|
Remember::instance().forgetAttrib(FbMenu::window()->winClient(), m_attrib);
|
2005-06-23 03:07:25 +00:00
|
|
|
} else {
|
2008-08-30 22:36:53 +00:00
|
|
|
Remember::instance().rememberAttrib(FbMenu::window()->winClient(), m_attrib);
|
2005-06-23 03:07:25 +00:00
|
|
|
}
|
2003-04-26 07:57:00 +00:00
|
|
|
}
|
2005-06-23 03:07:25 +00:00
|
|
|
Remember::instance().save();
|
2007-12-18 05:44:17 +00:00
|
|
|
FbTk::MenuItem::click(button, time, mods);
|
2003-04-26 07:57:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
Remember::Attribute m_attrib;
|
|
|
|
};
|
|
|
|
|
2005-06-23 03:07:25 +00:00
|
|
|
FbTk::Menu *createRememberMenu(BScreen &screen) {
|
2003-04-26 07:57:00 +00:00
|
|
|
// each fluxboxwindow has its own windowmenu
|
|
|
|
// so we also create a remember menu just for it...
|
2006-12-29 03:05:53 +00:00
|
|
|
FbTk::Menu *menu = screen.createMenu("Remember");
|
2003-07-20 08:12:36 +00:00
|
|
|
|
|
|
|
// if enabled, then we want this to be a unavailable menu
|
2005-06-23 03:07:25 +00:00
|
|
|
/*
|
2003-07-20 08:12:36 +00:00
|
|
|
if (!enabled) {
|
|
|
|
FbTk::MenuItem *item = new FbTk::MenuItem("unavailable");
|
|
|
|
item->setEnabled(false);
|
|
|
|
menu->insert(item);
|
2004-12-13 14:03:17 +00:00
|
|
|
menu->updateMenu();
|
2003-07-20 08:12:36 +00:00
|
|
|
return menu;
|
|
|
|
}
|
2005-06-23 03:07:25 +00:00
|
|
|
*/
|
2004-06-07 11:46:05 +00:00
|
|
|
_FB_USES_NLS;
|
2006-06-21 14:41:16 +00:00
|
|
|
menu->insert(new RememberMenuItem(_FB_XTEXT(Remember, Workspace, "Workspace", "Remember Workspace"),
|
2005-06-23 03:07:25 +00:00
|
|
|
Remember::REM_WORKSPACE));
|
2006-06-21 14:41:16 +00:00
|
|
|
menu->insert(new RememberMenuItem(_FB_XTEXT(Remember, JumpToWorkspace, "Jump to workspace", "Change active workspace to remembered one on open"),
|
2005-06-23 03:07:25 +00:00
|
|
|
Remember::REM_JUMPWORKSPACE));
|
2006-06-21 14:41:16 +00:00
|
|
|
menu->insert(new RememberMenuItem(_FB_XTEXT(Remember, Head, "Head", "Remember Head"),
|
2005-06-23 03:07:25 +00:00
|
|
|
Remember::REM_HEAD));
|
2006-06-21 14:41:16 +00:00
|
|
|
menu->insert(new RememberMenuItem(_FB_XTEXT(Remember, Dimensions, "Dimensions", "Remember Dimensions - with width and height"),
|
2005-06-23 03:07:25 +00:00
|
|
|
Remember::REM_DIMENSIONS));
|
2006-06-21 14:41:16 +00:00
|
|
|
menu->insert(new RememberMenuItem(_FB_XTEXT(Remember, Position, "Position", "Remember position - window co-ordinates"),
|
2005-06-23 03:07:25 +00:00
|
|
|
Remember::REM_POSITION));
|
2006-06-21 14:41:16 +00:00
|
|
|
menu->insert(new RememberMenuItem(_FB_XTEXT(Remember, Sticky, "Sticky", "Remember Sticky"),
|
2005-06-23 03:07:25 +00:00
|
|
|
Remember::REM_STUCKSTATE));
|
2006-06-21 14:41:16 +00:00
|
|
|
menu->insert(new RememberMenuItem(_FB_XTEXT(Remember, Decorations, "Decorations", "Remember window decorations"),
|
2005-06-23 03:07:25 +00:00
|
|
|
Remember::REM_DECOSTATE));
|
2006-06-21 14:41:16 +00:00
|
|
|
menu->insert(new RememberMenuItem(_FB_XTEXT(Remember, Shaded, "Shaded", "Remember shaded"),
|
2005-06-23 03:07:25 +00:00
|
|
|
Remember::REM_SHADEDSTATE));
|
2007-10-23 17:34:30 +00:00
|
|
|
menu->insert(new RememberMenuItem(_FB_XTEXT(Remember, Minimized, "Minimized", "Remember minimized"),
|
|
|
|
Remember::REM_MINIMIZEDSTATE));
|
|
|
|
menu->insert(new RememberMenuItem(_FB_XTEXT(Remember, Maximized, "Maximized", "Remember maximized"),
|
|
|
|
Remember::REM_MAXIMIZEDSTATE));
|
|
|
|
menu->insert(new RememberMenuItem(_FB_XTEXT(Remember, Fullscreen, "Fullscreen", "Remember fullscreen"),
|
|
|
|
Remember::REM_FULLSCREENSTATE));
|
2007-01-07 11:55:14 +00:00
|
|
|
if (FbTk::Transparent::haveComposite()
|
|
|
|
|| FbTk::Transparent::haveRender())
|
|
|
|
menu->insert(new RememberMenuItem(_FB_XTEXT(Remember, Alpha, "Transparency", "Remember window tranparency settings"),
|
|
|
|
Remember::REM_ALPHA));
|
2006-06-21 14:41:16 +00:00
|
|
|
menu->insert(new RememberMenuItem(_FB_XTEXT(Remember, Layer, "Layer", "Remember Layer"),
|
2005-06-23 03:07:25 +00:00
|
|
|
Remember::REM_LAYER));
|
2006-06-21 14:41:16 +00:00
|
|
|
menu->insert(new RememberMenuItem(_FB_XTEXT(Remember, SaveOnClose, "Save on close", "Save remembered attributes on close"),
|
2005-06-23 03:07:25 +00:00
|
|
|
Remember::REM_SAVEONCLOSE));
|
2003-04-26 07:57:00 +00:00
|
|
|
|
2004-12-13 14:03:17 +00:00
|
|
|
menu->updateMenu();
|
2003-04-26 07:57:00 +00:00
|
|
|
return menu;
|
2009-09-30 19:02:24 +00:00
|
|
|
}
|
2003-04-26 07:57:00 +00:00
|
|
|
|
2003-07-10 13:23:09 +00:00
|
|
|
// offset is the offset in the string that we start looking from
|
|
|
|
// return true if all ok, false on error
|
2003-08-18 09:32:15 +00:00
|
|
|
bool handleStartupItem(const string &line, int offset) {
|
2003-07-10 13:23:09 +00:00
|
|
|
int next = 0;
|
|
|
|
string str;
|
2007-01-03 18:59:43 +00:00
|
|
|
unsigned int screen = Fluxbox::instance()->keyScreen()->screenNumber();
|
2003-07-10 13:23:09 +00:00
|
|
|
|
|
|
|
// accept some options, for now only "screen=NN"
|
|
|
|
// these option are given in parentheses before the command
|
2004-12-21 16:09:36 +00:00
|
|
|
next = FbTk::StringUtil::getStringBetween(str,
|
|
|
|
line.c_str() + offset,
|
2003-07-10 13:23:09 +00:00
|
|
|
'(', ')');
|
|
|
|
if (next > 0) {
|
|
|
|
// there are some options
|
|
|
|
string option;
|
|
|
|
int pos = str.find('=');
|
|
|
|
bool error = false;
|
|
|
|
if (pos > 0) {
|
|
|
|
option = str.substr(0, pos);
|
2006-05-01 01:42:17 +00:00
|
|
|
if (strcasecmp(option.c_str(), "screen") == 0) {
|
2010-09-08 19:43:38 +00:00
|
|
|
error = !FbTk::StringUtil::extractNumber(str.c_str() + pos + 1, screen);
|
2003-07-10 13:23:09 +00:00
|
|
|
} else {
|
|
|
|
error = true;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
error = true;
|
|
|
|
}
|
|
|
|
if (error) {
|
|
|
|
cerr<<"Error parsing startup options."<<endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
next = 0;
|
|
|
|
}
|
|
|
|
|
2004-12-21 16:09:36 +00:00
|
|
|
next = FbTk::StringUtil::getStringBetween(str,
|
|
|
|
line.c_str() + offset + next,
|
2003-07-10 13:23:09 +00:00
|
|
|
'{', '}');
|
|
|
|
|
|
|
|
if (next <= 0) {
|
|
|
|
cerr<<"Error parsing [startup] at column "<<offset<<" - expecting {command}."<<endl;
|
|
|
|
return false;
|
2007-01-03 18:59:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// don't run command if fluxbox is restarting
|
|
|
|
if (Fluxbox::instance()->findScreen(screen)->isRestart())
|
|
|
|
// the line was successfully read; we just didn't use it
|
|
|
|
return true;
|
|
|
|
|
|
|
|
FbCommands::ExecuteCmd *tmp_exec_cmd = new FbCommands::ExecuteCmd(str, screen);
|
2010-03-17 15:35:07 +00:00
|
|
|
|
|
|
|
fbdbg<<"Executing startup Command<void> '"<<str<<"' on screen "<<screen<<endl;
|
|
|
|
|
2007-01-03 18:59:43 +00:00
|
|
|
tmp_exec_cmd->execute();
|
|
|
|
delete tmp_exec_cmd;
|
|
|
|
return true;
|
2009-09-30 19:02:24 +00:00
|
|
|
}
|
2003-07-10 13:23:09 +00:00
|
|
|
|
2007-01-02 03:12:24 +00:00
|
|
|
|
2003-04-26 07:57:00 +00:00
|
|
|
|
2008-08-14 05:53:38 +00:00
|
|
|
// returns number of lines read
|
|
|
|
// optionally can give a line to read before the first (lookahead line)
|
|
|
|
int parseApp(ifstream &file, Application &app, string *first_line = 0) {
|
2003-04-26 12:01:55 +00:00
|
|
|
string line;
|
2004-06-07 11:46:05 +00:00
|
|
|
_FB_USES_NLS;
|
2003-04-26 07:57:00 +00:00
|
|
|
int row = 0;
|
|
|
|
while (! file.eof()) {
|
2003-07-04 01:03:41 +00:00
|
|
|
if (first_line || getline(file, line)) {
|
|
|
|
if (first_line) {
|
|
|
|
line = *first_line;
|
|
|
|
first_line = 0;
|
|
|
|
}
|
|
|
|
|
2003-04-26 07:57:00 +00:00
|
|
|
row++;
|
2004-09-02 08:58:06 +00:00
|
|
|
FbTk::StringUtil::removeFirstWhitespace(line);
|
|
|
|
FbTk::StringUtil::removeTrailingWhitespace(line);
|
|
|
|
if (line.size() == 0 || line[0] == '#')
|
|
|
|
continue; //the line is commented or blank
|
2008-08-14 05:53:38 +00:00
|
|
|
|
2003-07-04 14:06:20 +00:00
|
|
|
int parse_pos = 0, err = 0;
|
2003-12-11 15:23:14 +00:00
|
|
|
string str_key, str_option, str_label;
|
2008-08-14 05:53:38 +00:00
|
|
|
|
2004-12-21 16:09:36 +00:00
|
|
|
err = FbTk::StringUtil::getStringBetween(str_key,
|
|
|
|
line.c_str(),
|
2003-07-04 14:06:20 +00:00
|
|
|
'[', ']');
|
2003-12-11 15:23:14 +00:00
|
|
|
if (err > 0) {
|
|
|
|
int tmp;
|
|
|
|
tmp= FbTk::StringUtil::getStringBetween(str_option,
|
|
|
|
line.c_str() + err,
|
|
|
|
'(', ')');
|
|
|
|
if (tmp>0)
|
2004-08-10 18:35:05 +00:00
|
|
|
err += tmp;
|
2003-12-11 15:23:14 +00:00
|
|
|
}
|
2003-07-04 14:06:20 +00:00
|
|
|
if (err > 0 ) {
|
|
|
|
parse_pos += err;
|
2004-12-21 16:09:36 +00:00
|
|
|
err = FbTk::StringUtil::getStringBetween(str_label,
|
|
|
|
line.c_str() + parse_pos,
|
2003-07-04 14:06:20 +00:00
|
|
|
'{', '}');
|
|
|
|
if (err>0) {
|
2003-04-26 07:57:00 +00:00
|
|
|
parse_pos += err;
|
2003-07-04 14:06:20 +00:00
|
|
|
}
|
|
|
|
} else
|
|
|
|
continue; //read next line
|
|
|
|
|
2006-05-01 01:42:17 +00:00
|
|
|
bool had_error = false;
|
|
|
|
|
2007-09-08 18:38:30 +00:00
|
|
|
if (str_key.empty())
|
2003-07-04 14:06:20 +00:00
|
|
|
continue; //read next line
|
2008-08-14 05:53:38 +00:00
|
|
|
|
|
|
|
str_key = FbTk::StringUtil::toLower(str_key);
|
|
|
|
|
|
|
|
if (str_key == "workspace") {
|
2003-07-04 14:06:20 +00:00
|
|
|
unsigned int w;
|
2010-09-08 19:43:38 +00:00
|
|
|
if (FbTk::StringUtil::extractNumber(str_label, w))
|
2006-05-01 01:42:17 +00:00
|
|
|
app.rememberWorkspace(w);
|
|
|
|
else
|
|
|
|
had_error = true;
|
2008-08-14 05:53:38 +00:00
|
|
|
} else if (str_key == "head") {
|
2006-05-01 01:42:17 +00:00
|
|
|
unsigned int h;
|
2010-09-08 19:43:38 +00:00
|
|
|
if (FbTk::StringUtil::extractNumber(str_label, h))
|
2006-05-01 01:42:17 +00:00
|
|
|
app.rememberHead(h);
|
|
|
|
else
|
|
|
|
had_error = true;
|
2008-08-14 05:53:38 +00:00
|
|
|
} else if (str_key == "layer") {
|
2011-03-23 11:02:15 +00:00
|
|
|
int l = ResourceLayer::getNumFromString(str_label);
|
2008-08-05 07:05:21 +00:00
|
|
|
had_error = (l == -1);
|
2006-05-01 01:42:17 +00:00
|
|
|
if (!had_error)
|
|
|
|
app.rememberLayer(l);
|
2008-08-14 05:53:38 +00:00
|
|
|
} else if (str_key == "dimensions") {
|
2003-07-04 14:06:20 +00:00
|
|
|
unsigned int h,w;
|
2006-06-27 08:54:24 +00:00
|
|
|
if (sscanf(str_label.c_str(), "%u %u", &w, &h) == 2)
|
2006-05-01 01:42:17 +00:00
|
|
|
app.rememberDimensions(w, h);
|
|
|
|
else
|
|
|
|
had_error = true;
|
2008-08-14 05:53:38 +00:00
|
|
|
} else if (str_key == "position") {
|
2008-08-18 12:12:30 +00:00
|
|
|
FluxboxWindow::ReferenceCorner r = FluxboxWindow::LEFTTOP;
|
|
|
|
int x = 0, y = 0;
|
2003-12-11 15:23:14 +00:00
|
|
|
// more info about the parameter
|
|
|
|
// in ::rememberPosition
|
2004-12-21 16:09:36 +00:00
|
|
|
|
2008-08-18 12:12:30 +00:00
|
|
|
if (str_option.length())
|
|
|
|
r = FluxboxWindow::getCorner(str_option);
|
|
|
|
had_error = (r == FluxboxWindow::ERROR);
|
2003-12-11 15:23:14 +00:00
|
|
|
|
2008-08-18 12:12:30 +00:00
|
|
|
if (!had_error && sscanf(str_label.c_str(), "%d %d", &x, &y) == 2)
|
2006-05-01 01:42:17 +00:00
|
|
|
app.rememberPosition(x, y, r);
|
|
|
|
else
|
|
|
|
had_error = true;
|
2008-08-14 05:53:38 +00:00
|
|
|
} else if (str_key == "shaded") {
|
2006-05-01 01:42:17 +00:00
|
|
|
app.rememberShadedstate((strcasecmp(str_label.c_str(), "yes") == 0));
|
2008-08-14 05:53:38 +00:00
|
|
|
} else if (str_key == "tab") {
|
2006-05-01 01:42:17 +00:00
|
|
|
app.rememberTabstate((strcasecmp(str_label.c_str(), "yes") == 0));
|
2008-08-14 05:53:38 +00:00
|
|
|
} else if (str_key == "focushidden") {
|
2006-05-01 01:42:17 +00:00
|
|
|
app.rememberFocusHiddenstate((strcasecmp(str_label.c_str(), "yes") == 0));
|
2008-08-14 05:53:38 +00:00
|
|
|
} else if (str_key == "iconhidden") {
|
2006-05-01 01:42:17 +00:00
|
|
|
app.rememberIconHiddenstate((strcasecmp(str_label.c_str(), "yes") == 0));
|
2008-08-14 05:53:38 +00:00
|
|
|
} else if (str_key == "hidden") {
|
2006-05-01 01:42:17 +00:00
|
|
|
app.rememberIconHiddenstate((strcasecmp(str_label.c_str(), "yes") == 0));
|
|
|
|
app.rememberFocusHiddenstate((strcasecmp(str_label.c_str(), "yes") == 0));
|
2008-08-14 05:53:38 +00:00
|
|
|
} else if (str_key == "deco") {
|
2008-08-27 17:05:49 +00:00
|
|
|
int deco = WindowState::getDecoMaskFromString(str_label);
|
2007-03-06 17:20:13 +00:00
|
|
|
if (deco == -1)
|
|
|
|
had_error = 1;
|
|
|
|
else
|
|
|
|
app.rememberDecostate((unsigned int)deco);
|
2008-08-14 05:53:38 +00:00
|
|
|
} else if (str_key == "alpha") {
|
2007-01-07 11:55:14 +00:00
|
|
|
int focused_a, unfocused_a;
|
2010-09-09 13:31:54 +00:00
|
|
|
switch (sscanf(str_label.c_str(), "%i %i", &focused_a, &unfocused_a)) {
|
|
|
|
case 1: // 'alpha <focus>'
|
|
|
|
unfocused_a = focused_a;
|
|
|
|
case 2: // 'alpha <focus> <unfocus>'
|
|
|
|
focused_a = FbTk::Util::clamp(focused_a, 0, 255);
|
|
|
|
unfocused_a = FbTk::Util::clamp(unfocused_a, 0, 255);
|
2007-01-07 11:55:14 +00:00
|
|
|
app.rememberAlpha(focused_a, unfocused_a);
|
2010-09-09 13:31:54 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
had_error = true;
|
|
|
|
break;
|
2007-01-07 11:55:14 +00:00
|
|
|
}
|
2008-08-14 05:53:38 +00:00
|
|
|
} else if (str_key == "sticky") {
|
2006-05-01 01:42:17 +00:00
|
|
|
app.rememberStuckstate((strcasecmp(str_label.c_str(), "yes") == 0));
|
2011-02-03 17:50:17 +00:00
|
|
|
} else if (str_key == "focusnewwindow") {
|
|
|
|
app.rememberFocusNewWindow((strcasecmp(str_label.c_str(), "yes") == 0));
|
2008-08-14 05:53:38 +00:00
|
|
|
} else if (str_key == "minimized") {
|
2007-10-23 17:34:30 +00:00
|
|
|
app.rememberMinimizedstate((strcasecmp(str_label.c_str(), "yes") == 0));
|
2008-08-14 05:53:38 +00:00
|
|
|
} else if (str_key == "maximized") {
|
2007-10-23 17:34:30 +00:00
|
|
|
if (strcasecmp(str_label.c_str(), "yes") == 0)
|
2008-08-27 17:05:49 +00:00
|
|
|
app.rememberMaximizedstate(WindowState::MAX_FULL);
|
2007-10-23 17:34:30 +00:00
|
|
|
else if (strcasecmp(str_label.c_str(), "horz") == 0)
|
2008-08-27 17:05:49 +00:00
|
|
|
app.rememberMaximizedstate(WindowState::MAX_HORZ);
|
2007-10-23 17:34:30 +00:00
|
|
|
else if (strcasecmp(str_label.c_str(), "vert") == 0)
|
2008-08-27 17:05:49 +00:00
|
|
|
app.rememberMaximizedstate(WindowState::MAX_VERT);
|
2007-10-23 17:34:30 +00:00
|
|
|
else
|
2008-08-27 17:05:49 +00:00
|
|
|
app.rememberMaximizedstate(WindowState::MAX_NONE);
|
2008-08-14 05:53:38 +00:00
|
|
|
} else if (str_key == "fullscreen") {
|
2007-10-23 17:34:30 +00:00
|
|
|
app.rememberFullscreenstate((strcasecmp(str_label.c_str(), "yes") == 0));
|
2008-08-14 05:53:38 +00:00
|
|
|
} else if (str_key == "jump") {
|
2006-05-01 01:42:17 +00:00
|
|
|
app.rememberJumpworkspace((strcasecmp(str_label.c_str(), "yes") == 0));
|
2008-08-14 05:53:38 +00:00
|
|
|
} else if (str_key == "close") {
|
2006-05-01 01:42:17 +00:00
|
|
|
app.rememberSaveOnClose((strcasecmp(str_label.c_str(), "yes") == 0));
|
2008-08-14 05:53:38 +00:00
|
|
|
} else if (str_key == "end") {
|
2003-07-04 14:06:20 +00:00
|
|
|
return row;
|
|
|
|
} else {
|
2006-06-21 14:41:16 +00:00
|
|
|
cerr << _FB_CONSOLETEXT(Remember, Unknown, "Unknown apps key", "apps entry type not known")<<" = " << str_key << endl;
|
2003-04-26 07:57:00 +00:00
|
|
|
}
|
2006-05-01 01:42:17 +00:00
|
|
|
if (had_error) {
|
|
|
|
cerr<<"Error parsing apps entry: ("<<line<<")"<<endl;
|
|
|
|
}
|
2003-04-26 07:57:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return row;
|
|
|
|
}
|
|
|
|
|
2008-08-14 05:53:38 +00:00
|
|
|
|
|
|
|
|
2006-04-23 14:51:04 +00:00
|
|
|
/*
|
|
|
|
This function is used to search for old instances of the same pattern
|
|
|
|
(when reloading apps file). More than one pattern might match, but only
|
|
|
|
if the application is the same (also note that they'll be adjacent).
|
2006-10-27 06:57:43 +00:00
|
|
|
We REMOVE and delete any matching patterns from the old list, as they're
|
|
|
|
effectively moved into the new
|
2006-04-23 14:51:04 +00:00
|
|
|
*/
|
|
|
|
|
2008-08-19 16:18:32 +00:00
|
|
|
Application* findMatchingPatterns(ClientPattern *pat, Remember::Patterns *patlist, bool transient, bool is_group, ClientPattern *match_pat = 0) {
|
2008-08-14 05:53:38 +00:00
|
|
|
|
|
|
|
Remember::Patterns::iterator it = patlist->begin();
|
|
|
|
Remember::Patterns::iterator it_end = patlist->end();
|
|
|
|
|
2006-04-23 14:51:04 +00:00
|
|
|
for (; it != it_end; ++it) {
|
2007-10-24 17:09:26 +00:00
|
|
|
if (*it->first == *pat && is_group == it->second->is_grouped &&
|
2008-08-19 16:18:32 +00:00
|
|
|
transient == it->second->is_transient &&
|
2007-10-13 21:51:37 +00:00
|
|
|
((match_pat == 0 && *it->second->group_pattern == 0) ||
|
2007-10-24 17:09:26 +00:00
|
|
|
(match_pat && *match_pat == **it->second->group_pattern))) {
|
2008-08-14 05:53:38 +00:00
|
|
|
|
2006-04-23 14:51:04 +00:00
|
|
|
Application *ret = it->second;
|
|
|
|
|
2007-10-24 17:09:26 +00:00
|
|
|
if (!is_group) return ret;
|
|
|
|
// find the rest of the group and remove it from the list
|
2006-04-23 14:51:04 +00:00
|
|
|
|
|
|
|
// rewind
|
2008-08-14 05:53:38 +00:00
|
|
|
Remember::Patterns::iterator tmpit = it;
|
2006-04-23 14:51:04 +00:00
|
|
|
while (tmpit != patlist->begin()) {
|
|
|
|
--tmpit;
|
|
|
|
if (tmpit->second == ret)
|
|
|
|
it = tmpit;
|
|
|
|
else
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// forward
|
2006-06-27 08:54:24 +00:00
|
|
|
for(; it != it_end && it->second == ret; ++it) {
|
|
|
|
delete it->first;
|
2006-04-23 14:51:04 +00:00
|
|
|
}
|
2006-06-27 08:54:24 +00:00
|
|
|
patlist->erase(patlist->begin(), it);
|
|
|
|
|
2006-04-23 14:51:04 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
}
|
2003-04-26 12:46:18 +00:00
|
|
|
|
2006-04-23 14:51:04 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-09-30 19:02:24 +00:00
|
|
|
} // end anonymous namespace
|
2008-08-14 05:53:38 +00:00
|
|
|
|
|
|
|
/*------------------------------------------------------------------*\
|
|
|
|
\*------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
Remember *Remember::s_instance = 0;
|
|
|
|
|
|
|
|
Remember::Remember():
|
|
|
|
m_pats(new Patterns()),
|
|
|
|
m_reloader(new FbTk::AutoReloadHelper()) {
|
|
|
|
|
2010-09-13 20:04:24 +00:00
|
|
|
setName("remember");
|
|
|
|
|
2008-08-14 05:53:38 +00:00
|
|
|
if (s_instance != 0)
|
|
|
|
throw string("Can not create more than one instance of Remember");
|
|
|
|
|
|
|
|
s_instance = this;
|
|
|
|
enableUpdate();
|
|
|
|
|
|
|
|
m_reloader->setReloadCmd(FbTk::RefCount<FbTk::Command<void> >(new FbTk::SimpleCommand<Remember>(*this, &Remember::reload)));
|
|
|
|
reconfigure();
|
|
|
|
}
|
|
|
|
|
|
|
|
Remember::~Remember() {
|
|
|
|
|
|
|
|
// free our resources
|
|
|
|
|
|
|
|
// the patterns free the "Application"s
|
|
|
|
// the client mapping shouldn't need cleaning
|
|
|
|
Patterns::iterator it;
|
|
|
|
set<Application *> all_apps; // no duplicates
|
|
|
|
while (!m_pats->empty()) {
|
|
|
|
it = m_pats->begin();
|
|
|
|
delete it->first; // ClientPattern
|
|
|
|
all_apps.insert(it->second); // Application, not necessarily unique
|
|
|
|
m_pats->erase(it);
|
|
|
|
}
|
|
|
|
|
|
|
|
set<Application *>::iterator ait = all_apps.begin(); // no duplicates
|
|
|
|
for (; ait != all_apps.end(); ++ait) {
|
|
|
|
delete (*ait);
|
|
|
|
}
|
|
|
|
|
|
|
|
delete(m_reloader);
|
|
|
|
|
|
|
|
s_instance = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
Application* Remember::find(WinClient &winclient) {
|
|
|
|
// if it is already associated with a application, return that one
|
|
|
|
// otherwise, check it against every pattern that we've got
|
|
|
|
Clients::iterator wc_it = m_clients.find(&winclient);
|
|
|
|
if (wc_it != m_clients.end())
|
|
|
|
return wc_it->second;
|
|
|
|
else {
|
|
|
|
Patterns::iterator it = m_pats->begin();
|
|
|
|
for (; it != m_pats->end(); it++)
|
2008-08-19 16:18:32 +00:00
|
|
|
if (it->first->match(winclient) &&
|
|
|
|
it->second->is_transient == winclient.isTransient()) {
|
2008-08-14 05:53:38 +00:00
|
|
|
it->first->addMatch();
|
|
|
|
m_clients[&winclient] = it->second;
|
|
|
|
return it->second;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// oh well, no matches
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
Application * Remember::add(WinClient &winclient) {
|
|
|
|
ClientPattern *p = new ClientPattern();
|
2008-08-19 16:18:32 +00:00
|
|
|
Application *app = new Application(winclient.isTransient(), false);
|
2008-08-14 05:53:38 +00:00
|
|
|
|
|
|
|
// by default, we match against the WMClass of a window (instance and class strings)
|
|
|
|
string win_name = ::escapeRememberChars(p->getProperty(ClientPattern::NAME, winclient));
|
|
|
|
string win_class = ::escapeRememberChars(p->getProperty(ClientPattern::CLASS, winclient));
|
|
|
|
string win_role = ::escapeRememberChars(p->getProperty(ClientPattern::ROLE, winclient));
|
|
|
|
|
|
|
|
p->addTerm(win_name, ClientPattern::NAME);
|
|
|
|
p->addTerm(win_class, ClientPattern::CLASS);
|
|
|
|
if (!win_role.empty())
|
|
|
|
p->addTerm(win_role, ClientPattern::ROLE);
|
|
|
|
m_clients[&winclient] = app;
|
|
|
|
p->addMatch();
|
|
|
|
m_pats->push_back(make_pair(p, app));
|
|
|
|
return app;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2006-04-23 14:51:04 +00:00
|
|
|
|
|
|
|
void Remember::reconfigure() {
|
2008-08-14 05:53:38 +00:00
|
|
|
m_reloader->setMainFile(Fluxbox::instance()->getAppsFilename());
|
2008-05-12 16:30:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Remember::checkReload() {
|
2008-08-14 05:53:38 +00:00
|
|
|
m_reloader->checkReload();
|
2008-05-12 16:00:02 +00:00
|
|
|
}
|
2003-05-27 11:55:23 +00:00
|
|
|
|
2008-05-12 16:00:02 +00:00
|
|
|
void Remember::reload() {
|
|
|
|
string apps_string = FbTk::StringUtil::expandFilename(Fluxbox::instance()->getAppsFilename());
|
2006-10-27 06:57:43 +00:00
|
|
|
|
2010-03-17 15:35:07 +00:00
|
|
|
|
|
|
|
fbdbg<<"("<<__FUNCTION__<<"): Loading apps file ["<<apps_string<<"]"<<endl;
|
2006-10-27 06:57:43 +00:00
|
|
|
|
2003-04-26 12:01:55 +00:00
|
|
|
ifstream apps_file(apps_string.c_str());
|
2003-04-26 12:46:18 +00:00
|
|
|
|
2006-04-23 14:51:04 +00:00
|
|
|
// we merge the old patterns with new ones
|
|
|
|
Patterns *old_pats = m_pats.release();
|
2008-02-04 16:53:32 +00:00
|
|
|
set<Application *> reused_apps;
|
2006-04-23 14:51:04 +00:00
|
|
|
m_pats.reset(new Patterns());
|
2006-04-23 14:56:06 +00:00
|
|
|
m_startups.clear();
|
2006-04-23 14:51:04 +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;
|
2007-10-13 21:51:37 +00:00
|
|
|
bool in_group = false;
|
|
|
|
ClientPattern *pat = 0;
|
2006-10-27 06:57:43 +00:00
|
|
|
list<ClientPattern *> grouped_pats;
|
2003-04-26 07:57:00 +00:00
|
|
|
while (getline(apps_file, line) && ! apps_file.eof()) {
|
|
|
|
row++;
|
2004-09-04 04:54:38 +00:00
|
|
|
FbTk::StringUtil::removeFirstWhitespace(line);
|
|
|
|
FbTk::StringUtil::removeTrailingWhitespace(line);
|
|
|
|
if (line.size() == 0 || line[0] == '#')
|
2003-04-26 07:57:00 +00:00
|
|
|
continue;
|
2003-04-26 12:01:55 +00:00
|
|
|
string key;
|
2003-06-12 15:12:19 +00:00
|
|
|
int err=0;
|
2004-12-21 16:09:36 +00:00
|
|
|
int pos = FbTk::StringUtil::getStringBetween(key,
|
|
|
|
line.c_str(),
|
2003-04-26 18:58:30 +00:00
|
|
|
'[', ']');
|
2003-04-26 07:57:00 +00:00
|
|
|
|
2008-08-19 16:18:32 +00:00
|
|
|
if (pos > 0 && (strcasecmp(key.c_str(), "app") == 0 ||
|
|
|
|
strcasecmp(key.c_str(), "transient") == 0)) {
|
|
|
|
ClientPattern *pat = new ClientPattern(line.c_str() + pos);
|
2007-10-13 21:51:37 +00:00
|
|
|
if (!in_group) {
|
2003-07-04 01:03:41 +00:00
|
|
|
if ((err = pat->error()) == 0) {
|
2008-08-19 16:18:32 +00:00
|
|
|
bool transient = (strcasecmp(key.c_str(),
|
|
|
|
"transient") == 0);
|
|
|
|
Application *app = findMatchingPatterns(pat,
|
|
|
|
old_pats, transient, false);
|
2008-02-04 16:53:32 +00:00
|
|
|
if (app) {
|
2007-10-23 17:34:30 +00:00
|
|
|
app->reset();
|
2008-02-04 16:53:32 +00:00
|
|
|
reused_apps.insert(app);
|
2008-08-19 16:18:32 +00:00
|
|
|
} else {
|
|
|
|
app = new Application(transient, false);
|
|
|
|
}
|
2006-04-23 14:51:04 +00:00
|
|
|
|
|
|
|
m_pats->push_back(make_pair(pat, app));
|
2003-07-04 01:03:41 +00:00
|
|
|
row += parseApp(apps_file, *app);
|
|
|
|
} else {
|
|
|
|
cerr<<"Error reading apps file at line "<<row<<", column "<<(err+pos)<<"."<<endl;
|
|
|
|
delete pat; // since it didn't work
|
|
|
|
}
|
2003-06-12 15:12:19 +00:00
|
|
|
} else {
|
2003-07-04 01:03:41 +00:00
|
|
|
grouped_pats.push_back(pat);
|
|
|
|
}
|
2007-01-01 00:10:27 +00:00
|
|
|
} else if (pos > 0 && strcasecmp(key.c_str(), "startup") == 0 &&
|
|
|
|
Fluxbox::instance()->isStartup()) {
|
2003-07-10 13:23:09 +00:00
|
|
|
if (!handleStartupItem(line, pos)) {
|
|
|
|
cerr<<"Error reading apps file at line "<<row<<"."<<endl;
|
|
|
|
}
|
|
|
|
// save the item even if it was bad (aren't we nice)
|
|
|
|
m_startups.push_back(line.substr(pos));
|
2006-05-01 01:42:17 +00:00
|
|
|
} else if (pos > 0 && strcasecmp(key.c_str(), "group") == 0) {
|
2007-10-13 21:51:37 +00:00
|
|
|
in_group = true;
|
|
|
|
if (line.find('(') != string::npos)
|
2008-08-19 16:18:32 +00:00
|
|
|
pat = new ClientPattern(line.c_str() + pos);
|
2003-07-04 01:03:41 +00:00
|
|
|
} else if (in_group) {
|
|
|
|
// otherwise assume that it is the start of the attributes
|
2006-04-23 14:51:04 +00:00
|
|
|
Application *app = 0;
|
|
|
|
// search for a matching app
|
2006-10-27 06:57:43 +00:00
|
|
|
list<ClientPattern *>::iterator it = grouped_pats.begin();
|
|
|
|
list<ClientPattern *>::iterator it_end = grouped_pats.end();
|
2006-04-23 14:51:04 +00:00
|
|
|
while (!app && it != it_end) {
|
2008-08-19 16:18:32 +00:00
|
|
|
app = findMatchingPatterns(*it, old_pats, false,
|
|
|
|
in_group, pat);
|
2006-04-23 14:51:04 +00:00
|
|
|
++it;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!app)
|
2008-08-19 16:18:32 +00:00
|
|
|
app = new Application(false, in_group, pat);
|
2008-02-04 16:53:32 +00:00
|
|
|
else
|
|
|
|
reused_apps.insert(app);
|
2006-04-23 14:51:04 +00:00
|
|
|
|
2003-07-04 01:03:41 +00:00
|
|
|
while (!grouped_pats.empty()) {
|
|
|
|
// associate all the patterns with this app
|
2006-04-23 14:51:04 +00:00
|
|
|
m_pats->push_back(make_pair(grouped_pats.front(), app));
|
2003-07-04 01:03:41 +00:00
|
|
|
grouped_pats.pop_front();
|
|
|
|
}
|
2004-12-21 16:09:36 +00:00
|
|
|
|
2003-07-04 01:03:41 +00:00
|
|
|
// we hit end... probably don't have attribs for the group
|
|
|
|
// so finish it off with an empty application
|
|
|
|
// otherwise parse the app
|
2006-05-01 01:42:17 +00:00
|
|
|
if (!(pos>0 && strcasecmp(key.c_str(), "end") == 0)) {
|
2003-07-04 01:03:41 +00:00
|
|
|
row += parseApp(apps_file, *app, &line);
|
2003-06-12 15:12:19 +00:00
|
|
|
}
|
2007-10-13 21:51:37 +00:00
|
|
|
in_group = false;
|
2003-04-26 07:57:00 +00:00
|
|
|
} else
|
2003-06-12 15:12:19 +00:00
|
|
|
cerr<<"Error in apps file on line "<<row<<"."<<endl;
|
2004-12-21 16:09:36 +00:00
|
|
|
|
2003-04-26 07:57:00 +00:00
|
|
|
}
|
|
|
|
} else {
|
2010-03-17 15:35:07 +00:00
|
|
|
fbdbg<<"("<<__FUNCTION__<< ") Empty apps file" << endl;
|
2003-04-26 07:57:00 +00:00
|
|
|
}
|
|
|
|
} else {
|
2008-05-12 16:00:02 +00:00
|
|
|
cerr << "failed to open apps file" << endl;
|
2003-04-26 07:57:00 +00:00
|
|
|
}
|
2006-04-23 14:51:04 +00:00
|
|
|
|
|
|
|
// Clean up old state
|
|
|
|
// can't just delete old patterns list. Need to delete the
|
|
|
|
// patterns themselves, plus the applications!
|
2006-10-27 06:57:43 +00:00
|
|
|
|
2006-04-23 14:51:04 +00:00
|
|
|
Patterns::iterator it;
|
2006-10-27 06:57:43 +00:00
|
|
|
set<Application *> old_apps; // no duplicates
|
2006-04-23 14:51:04 +00:00
|
|
|
while (!old_pats->empty()) {
|
|
|
|
it = old_pats->begin();
|
|
|
|
delete it->first; // ClientPattern
|
2008-02-04 16:53:32 +00:00
|
|
|
if (reused_apps.find(it->second) == reused_apps.end())
|
|
|
|
old_apps.insert(it->second); // Application, not necessarily unique
|
2006-04-23 14:51:04 +00:00
|
|
|
old_pats->erase(it);
|
|
|
|
}
|
|
|
|
|
|
|
|
// now remove any client entries for the old apps
|
|
|
|
Clients::iterator cit = m_clients.begin();
|
|
|
|
Clients::iterator cit_end = m_clients.end();
|
|
|
|
while (cit != cit_end) {
|
|
|
|
if (old_apps.find(cit->second) != old_apps.end()) {
|
|
|
|
Clients::iterator tmpit = cit;
|
|
|
|
++cit;
|
|
|
|
m_clients.erase(tmpit);
|
|
|
|
} else {
|
|
|
|
++cit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-10-27 06:57:43 +00:00
|
|
|
set<Application *>::iterator ait = old_apps.begin(); // no duplicates
|
2006-06-27 08:54:24 +00:00
|
|
|
for (; ait != old_apps.end(); ++ait) {
|
2006-04-23 14:51:04 +00:00
|
|
|
delete (*ait);
|
|
|
|
}
|
|
|
|
|
|
|
|
delete old_pats;
|
2003-04-26 07:57:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Remember::save() {
|
2006-03-24 02:40:09 +00:00
|
|
|
|
|
|
|
string apps_string = FbTk::StringUtil::expandFilename(Fluxbox::instance()->getAppsFilename());
|
|
|
|
|
2010-03-17 15:35:07 +00:00
|
|
|
fbdbg<<"("<<__FUNCTION__<<"): Saving apps file ["<<apps_string<<"]"<<endl;
|
|
|
|
|
2003-04-26 12:01:55 +00:00
|
|
|
ofstream apps_file(apps_string.c_str());
|
2003-07-10 13:23:09 +00:00
|
|
|
|
|
|
|
// first of all we output all the startup commands
|
|
|
|
Startups::iterator sit = m_startups.begin();
|
|
|
|
Startups::iterator sit_end = m_startups.end();
|
|
|
|
for (; sit != sit_end; ++sit) {
|
|
|
|
apps_file<<"[startup] "<<(*sit)<<endl;
|
|
|
|
}
|
|
|
|
|
2006-04-23 14:51:04 +00:00
|
|
|
Patterns::iterator it = m_pats->begin();
|
|
|
|
Patterns::iterator it_end = m_pats->end();
|
2003-07-04 01:03:41 +00:00
|
|
|
|
2006-10-27 06:57:43 +00:00
|
|
|
set<Application *> grouped_apps; // no duplicates
|
2003-07-04 01:03:41 +00:00
|
|
|
|
2003-04-26 07:57:00 +00:00
|
|
|
for (; it != it_end; ++it) {
|
2003-06-12 15:12:19 +00:00
|
|
|
Application &a = *it->second;
|
2003-07-04 01:03:41 +00:00
|
|
|
if (a.is_grouped) {
|
|
|
|
// if already processed
|
|
|
|
if (grouped_apps.find(&a) != grouped_apps.end())
|
|
|
|
continue;
|
2003-07-10 13:23:09 +00:00
|
|
|
grouped_apps.insert(&a);
|
2003-07-04 01:03:41 +00:00
|
|
|
// otherwise output this whole group
|
2007-02-05 17:20:01 +00:00
|
|
|
apps_file << "[group]";
|
2007-10-13 21:51:37 +00:00
|
|
|
if (*a.group_pattern)
|
|
|
|
apps_file << " " << a.group_pattern->toString();
|
2007-02-05 17:20:01 +00:00
|
|
|
apps_file << endl;
|
|
|
|
|
2006-04-23 14:51:04 +00:00
|
|
|
Patterns::iterator git = m_pats->begin();
|
|
|
|
Patterns::iterator git_end = m_pats->end();
|
2003-07-04 01:03:41 +00:00
|
|
|
for (; git != git_end; git++) {
|
2003-07-10 13:23:09 +00:00
|
|
|
if (git->second == &a) {
|
2008-08-19 16:18:32 +00:00
|
|
|
apps_file << (a.is_transient ? " [transient]" : " [app]") <<
|
|
|
|
git->first->toString()<<endl;
|
2003-07-04 01:03:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2008-08-19 16:18:32 +00:00
|
|
|
apps_file << (a.is_transient ? "[transient]" : "[app]") <<
|
|
|
|
it->first->toString()<<endl;
|
2003-07-04 01:03:41 +00:00
|
|
|
}
|
2003-06-12 15:12:19 +00:00
|
|
|
if (a.workspace_remember) {
|
|
|
|
apps_file << " [Workspace]\t{" << a.workspace << "}" << endl;
|
2003-04-26 07:57:00 +00:00
|
|
|
}
|
2004-12-21 16:09:36 +00:00
|
|
|
if (a.head_remember) {
|
|
|
|
apps_file << " [Head]\t{" << a.head << "}" << endl;
|
|
|
|
}
|
2003-06-12 15:12:19 +00:00
|
|
|
if (a.dimensions_remember) {
|
|
|
|
apps_file << " [Dimensions]\t{" << a.w << " " << a.h << "}" << endl;
|
2003-04-26 07:57:00 +00:00
|
|
|
}
|
2003-06-12 15:12:19 +00:00
|
|
|
if (a.position_remember) {
|
2005-05-09 06:09:37 +00:00
|
|
|
apps_file << " [Position]\t(";
|
|
|
|
switch(a.refc) {
|
2008-08-18 12:12:30 +00:00
|
|
|
case FluxboxWindow::CENTER:
|
2005-05-09 06:09:37 +00:00
|
|
|
apps_file << "CENTER";
|
|
|
|
break;
|
2008-08-18 12:12:30 +00:00
|
|
|
case FluxboxWindow::LEFTBOTTOM:
|
2005-05-09 06:09:37 +00:00
|
|
|
apps_file << "LOWERLEFT";
|
|
|
|
break;
|
2008-08-18 12:12:30 +00:00
|
|
|
case FluxboxWindow::RIGHTBOTTOM:
|
2005-05-09 06:09:37 +00:00
|
|
|
apps_file << "LOWERRIGHT";
|
|
|
|
break;
|
2008-08-18 12:12:30 +00:00
|
|
|
case FluxboxWindow::RIGHTTOP:
|
2005-05-09 06:09:37 +00:00
|
|
|
apps_file << "UPPERRIGHT";
|
|
|
|
break;
|
2008-08-18 12:12:30 +00:00
|
|
|
case FluxboxWindow::LEFT:
|
|
|
|
apps_file << "LEFT";
|
|
|
|
break;
|
|
|
|
case FluxboxWindow::RIGHT:
|
|
|
|
apps_file << "RIGHT";
|
|
|
|
break;
|
|
|
|
case FluxboxWindow::TOP:
|
|
|
|
apps_file << "TOP";
|
|
|
|
break;
|
|
|
|
case FluxboxWindow::BOTTOM:
|
|
|
|
apps_file << "BOTTOM";
|
|
|
|
break;
|
2005-05-09 06:09:37 +00:00
|
|
|
default:
|
|
|
|
apps_file << "UPPERLEFT";
|
|
|
|
}
|
|
|
|
apps_file << ")\t{" << a.x << " " << a.y << "}" << endl;
|
2003-04-26 07:57:00 +00:00
|
|
|
}
|
2003-06-12 15:12:19 +00:00
|
|
|
if (a.shadedstate_remember) {
|
|
|
|
apps_file << " [Shaded]\t{" << ((a.shadedstate)?"yes":"no") << "}" << endl;
|
2003-04-26 07:57:00 +00:00
|
|
|
}
|
2003-06-12 15:12:19 +00:00
|
|
|
if (a.tabstate_remember) {
|
|
|
|
apps_file << " [Tab]\t\t{" << ((a.tabstate)?"yes":"no") << "}" << endl;
|
2003-04-26 07:57:00 +00:00
|
|
|
}
|
2003-06-12 15:12:19 +00:00
|
|
|
if (a.decostate_remember) {
|
|
|
|
switch (a.decostate) {
|
2003-04-26 07:57:00 +00:00
|
|
|
case (0) :
|
2004-12-21 16:09:36 +00:00
|
|
|
apps_file << " [Deco]\t{NONE}" << endl;
|
2003-04-26 07:57:00 +00:00
|
|
|
break;
|
|
|
|
case (0xffffffff):
|
2011-02-03 07:43:47 +00:00
|
|
|
case (WindowState::DECOR_NORMAL):
|
2003-04-26 07:57:00 +00:00
|
|
|
apps_file << " [Deco]\t{NORMAL}" << endl;
|
|
|
|
break;
|
2011-02-03 07:43:47 +00:00
|
|
|
case (WindowState::DECOR_TOOL):
|
2003-04-26 07:57:00 +00:00
|
|
|
apps_file << " [Deco]\t{TOOL}" << endl;
|
|
|
|
break;
|
2011-02-03 07:43:47 +00:00
|
|
|
case (WindowState::DECOR_TINY):
|
2003-04-26 07:57:00 +00:00
|
|
|
apps_file << " [Deco]\t{TINY}" << endl;
|
|
|
|
break;
|
2011-02-03 07:43:47 +00:00
|
|
|
case (WindowState::DECOR_BORDER):
|
2003-05-26 11:27:31 +00:00
|
|
|
apps_file << " [Deco]\t{BORDER}" << endl;
|
|
|
|
break;
|
2011-02-03 07:43:47 +00:00
|
|
|
case (WindowState::DECORM_TAB):
|
2006-05-01 01:42:17 +00:00
|
|
|
apps_file << " [Deco]\t{TAB}" << endl;
|
|
|
|
break;
|
2003-04-26 07:57:00 +00:00
|
|
|
default:
|
2003-06-12 15:12:19 +00:00
|
|
|
apps_file << " [Deco]\t{0x"<<hex<<a.decostate<<dec<<"}"<<endl;
|
2003-04-26 07:57:00 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2004-02-20 09:07:27 +00:00
|
|
|
|
|
|
|
if (a.focushiddenstate_remember || a.iconhiddenstate_remember) {
|
|
|
|
if (a.focushiddenstate_remember && a.iconhiddenstate_remember &&
|
2006-12-27 04:49:17 +00:00
|
|
|
a.focushiddenstate == a.iconhiddenstate)
|
2004-02-20 09:07:27 +00:00
|
|
|
apps_file << " [Hidden]\t{" << ((a.focushiddenstate)?"yes":"no") << "}" << endl;
|
|
|
|
else if (a.focushiddenstate_remember) {
|
|
|
|
apps_file << " [FocusHidden]\t{" << ((a.focushiddenstate)?"yes":"no") << "}" << endl;
|
|
|
|
} else if (a.iconhiddenstate_remember) {
|
|
|
|
apps_file << " [IconHidden]\t{" << ((a.iconhiddenstate)?"yes":"no") << "}" << endl;
|
|
|
|
}
|
|
|
|
}
|
2003-06-12 15:12:19 +00:00
|
|
|
if (a.stuckstate_remember) {
|
|
|
|
apps_file << " [Sticky]\t{" << ((a.stuckstate)?"yes":"no") << "}" << endl;
|
2003-04-26 07:57:00 +00:00
|
|
|
}
|
2011-02-03 17:50:17 +00:00
|
|
|
if (a.focusnewwindow_remember) {
|
|
|
|
apps_file << " [FocusNewWindow]\t{" << ((a.focusnewwindow)?"yes":"no") << "}" << endl;
|
|
|
|
}
|
2007-10-23 17:34:30 +00:00
|
|
|
if (a.minimizedstate_remember) {
|
|
|
|
apps_file << " [Minimized]\t{" << ((a.minimizedstate)?"yes":"no") << "}" << endl;
|
|
|
|
}
|
|
|
|
if (a.maximizedstate_remember) {
|
|
|
|
apps_file << " [Maximized]\t{";
|
|
|
|
switch (a.maximizedstate) {
|
2008-08-27 17:05:49 +00:00
|
|
|
case WindowState::MAX_FULL:
|
2007-10-23 17:34:30 +00:00
|
|
|
apps_file << "yes" << "}" << endl;
|
|
|
|
break;
|
2008-08-27 17:05:49 +00:00
|
|
|
case WindowState::MAX_HORZ:
|
2007-10-23 17:34:30 +00:00
|
|
|
apps_file << "horz" << "}" << endl;
|
|
|
|
break;
|
2008-08-27 17:05:49 +00:00
|
|
|
case WindowState::MAX_VERT:
|
2007-10-23 17:34:30 +00:00
|
|
|
apps_file << "vert" << "}" << endl;
|
|
|
|
break;
|
2008-08-27 17:05:49 +00:00
|
|
|
case WindowState::MAX_NONE:
|
2007-10-23 17:34:30 +00:00
|
|
|
default:
|
|
|
|
apps_file << "no" << "}" << endl;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (a.fullscreenstate_remember) {
|
|
|
|
apps_file << " [Fullscreen]\t{" << ((a.fullscreenstate)?"yes":"no") << "}" << endl;
|
|
|
|
}
|
2003-06-12 15:12:19 +00:00
|
|
|
if (a.jumpworkspace_remember) {
|
|
|
|
apps_file << " [Jump]\t{" << ((a.jumpworkspace)?"yes":"no") << "}" << endl;
|
2003-04-26 07:57:00 +00:00
|
|
|
}
|
2003-06-12 15:12:19 +00:00
|
|
|
if (a.layer_remember) {
|
|
|
|
apps_file << " [Layer]\t{" << a.layer << "}" << endl;
|
2003-04-26 13:47:53 +00:00
|
|
|
}
|
2003-06-12 15:12:19 +00:00
|
|
|
if (a.save_on_close_remember) {
|
|
|
|
apps_file << " [Close]\t{" << ((a.save_on_close)?"yes":"no") << "}" << endl;
|
2003-04-26 07:57:00 +00:00
|
|
|
}
|
2007-01-07 11:55:14 +00:00
|
|
|
if (a.alpha_remember) {
|
|
|
|
if (a.focused_alpha == a.unfocused_alpha)
|
|
|
|
apps_file << " [Alpha]\t{" << a.focused_alpha << "}" << endl;
|
|
|
|
else
|
|
|
|
apps_file << " [Alpha]\t{" << a.focused_alpha << " " << a.unfocused_alpha << "}" << endl;
|
|
|
|
}
|
2003-04-26 07:57:00 +00:00
|
|
|
apps_file << "[end]" << endl;
|
|
|
|
}
|
2006-05-01 01:42:17 +00:00
|
|
|
apps_file.close();
|
2008-05-12 16:00:02 +00:00
|
|
|
// update timestamp to avoid unnecessary reload
|
2008-08-14 05:53:38 +00:00
|
|
|
m_reloader->addFile(Fluxbox::instance()->getAppsFilename());
|
2003-04-26 07:57:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
2004-12-21 16:09:36 +00:00
|
|
|
case REM_HEAD:
|
|
|
|
return app->head_remember;
|
|
|
|
break;
|
2003-04-26 07:57:00 +00:00
|
|
|
case REM_DIMENSIONS:
|
|
|
|
return app->dimensions_remember;
|
|
|
|
break;
|
|
|
|
case REM_POSITION:
|
|
|
|
return app->position_remember;
|
|
|
|
break;
|
2004-02-20 09:07:27 +00:00
|
|
|
case REM_FOCUSHIDDENSTATE:
|
|
|
|
return app->focushiddenstate_remember;
|
|
|
|
break;
|
|
|
|
case REM_ICONHIDDENSTATE:
|
|
|
|
return app->iconhiddenstate_remember;
|
2004-02-16 10:26:03 +00:00
|
|
|
break;
|
2003-04-26 07:57:00 +00:00
|
|
|
case REM_STUCKSTATE:
|
|
|
|
return app->stuckstate_remember;
|
|
|
|
break;
|
2011-02-03 17:50:17 +00:00
|
|
|
case REM_FOCUSNEWWINDOW:
|
|
|
|
return app->focusnewwindow_remember;
|
|
|
|
break;
|
2007-10-23 17:34:30 +00:00
|
|
|
case REM_MINIMIZEDSTATE:
|
|
|
|
return app->minimizedstate_remember;
|
|
|
|
break;
|
|
|
|
case REM_MAXIMIZEDSTATE:
|
|
|
|
return app->maximizedstate_remember;
|
|
|
|
break;
|
|
|
|
case REM_FULLSCREENSTATE:
|
|
|
|
return app->fullscreenstate_remember;
|
|
|
|
break;
|
2003-04-26 07:57:00 +00:00
|
|
|
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;
|
2007-01-07 11:55:14 +00:00
|
|
|
case REM_ALPHA:
|
|
|
|
return app->alpha_remember;
|
2003-04-26 07:57:00 +00:00
|
|
|
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;
|
2004-12-21 16:09:36 +00:00
|
|
|
case REM_HEAD:
|
|
|
|
app->rememberHead(win->screen().getHead(win->fbWindow()));
|
|
|
|
break;
|
2003-04-26 07:57:00 +00:00
|
|
|
case REM_DIMENSIONS:
|
2008-08-27 20:29:35 +00:00
|
|
|
app->rememberDimensions(win->normalWidth(),
|
|
|
|
win->normalHeight());
|
2003-04-26 07:57:00 +00:00
|
|
|
break;
|
2007-03-18 23:49:54 +00:00
|
|
|
case REM_POSITION: {
|
|
|
|
int head = win->screen().getHead(win->fbWindow());
|
2008-08-18 12:12:30 +00:00
|
|
|
int head_x = win->screen().maxLeft(head);
|
|
|
|
int head_y = win->screen().maxTop(head);
|
2008-08-27 20:29:35 +00:00
|
|
|
app->rememberPosition(win->normalX() - head_x,
|
|
|
|
win->normalY() - head_y);
|
2003-04-26 07:57:00 +00:00
|
|
|
break;
|
2007-03-18 23:49:54 +00:00
|
|
|
}
|
2004-02-20 09:07:27 +00:00
|
|
|
case REM_FOCUSHIDDENSTATE:
|
|
|
|
app->rememberFocusHiddenstate(win->isFocusHidden());
|
|
|
|
break;
|
|
|
|
case REM_ICONHIDDENSTATE:
|
|
|
|
app->rememberIconHiddenstate(win->isIconHidden());
|
2004-02-16 10:26:03 +00:00
|
|
|
break;
|
2003-05-31 01:07:36 +00:00
|
|
|
case REM_SHADEDSTATE:
|
2003-04-26 07:57:00 +00:00
|
|
|
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;
|
2003-05-31 01:07:36 +00:00
|
|
|
case REM_STUCKSTATE:
|
2003-04-26 07:57:00 +00:00
|
|
|
app->rememberStuckstate(win->isStuck());
|
|
|
|
break;
|
2011-02-03 17:50:17 +00:00
|
|
|
case REM_FOCUSNEWWINDOW:
|
|
|
|
app->rememberFocusNewWindow(win->isFocusNew());
|
|
|
|
break;
|
2007-10-23 17:34:30 +00:00
|
|
|
case REM_MINIMIZEDSTATE:
|
|
|
|
app->rememberMinimizedstate(win->isIconic());
|
|
|
|
break;
|
|
|
|
case REM_MAXIMIZEDSTATE:
|
|
|
|
app->rememberMaximizedstate(win->maximizedState());
|
|
|
|
break;
|
|
|
|
case REM_FULLSCREENSTATE:
|
|
|
|
app->rememberFullscreenstate(win->isFullscreen());
|
|
|
|
break;
|
2007-01-07 11:55:14 +00:00
|
|
|
case REM_ALPHA:
|
|
|
|
app->rememberAlpha(win->frame().getAlpha(true), win->frame().getAlpha(false));
|
|
|
|
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;
|
2004-12-21 16:09:36 +00:00
|
|
|
case REM_HEAD:
|
|
|
|
app->forgetHead();
|
|
|
|
break;
|
2003-04-26 07:57:00 +00:00
|
|
|
case REM_DIMENSIONS:
|
|
|
|
app->forgetDimensions();
|
|
|
|
break;
|
|
|
|
case REM_POSITION:
|
|
|
|
app->forgetPosition();
|
|
|
|
break;
|
2004-02-20 09:07:27 +00:00
|
|
|
case REM_FOCUSHIDDENSTATE:
|
|
|
|
app->forgetFocusHiddenstate();
|
|
|
|
break;
|
|
|
|
case REM_ICONHIDDENSTATE:
|
|
|
|
app->forgetIconHiddenstate();
|
2004-02-16 10:26:03 +00:00
|
|
|
break;
|
2003-04-26 07:57:00 +00:00
|
|
|
case REM_STUCKSTATE:
|
|
|
|
app->forgetStuckstate();
|
|
|
|
break;
|
2011-02-03 17:50:17 +00:00
|
|
|
case REM_FOCUSNEWWINDOW:
|
|
|
|
app->forgetFocusNewWindow();
|
|
|
|
break;
|
2007-10-23 17:34:30 +00:00
|
|
|
case REM_MINIMIZEDSTATE:
|
|
|
|
app->forgetMinimizedstate();
|
|
|
|
break;
|
|
|
|
case REM_MAXIMIZEDSTATE:
|
|
|
|
app->forgetMaximizedstate();
|
|
|
|
break;
|
|
|
|
case REM_FULLSCREENSTATE:
|
|
|
|
app->forgetFullscreenstate();
|
|
|
|
break;
|
2003-04-26 07:57:00 +00:00
|
|
|
case REM_DECOSTATE:
|
|
|
|
app->forgetDecostate();
|
|
|
|
break;
|
|
|
|
case REM_SHADEDSTATE:
|
|
|
|
app->forgetShadedstate();
|
|
|
|
break;
|
2007-01-07 11:55:14 +00:00
|
|
|
case REM_ALPHA:
|
|
|
|
app->forgetAlpha();
|
|
|
|
break;
|
2003-04-26 07:57:00 +00:00
|
|
|
// 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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-07-04 01:03:41 +00:00
|
|
|
void Remember::setupFrame(FluxboxWindow &win) {
|
2003-04-26 07:57:00 +00:00
|
|
|
WinClient &winclient = win.winClient();
|
|
|
|
Application *app = find(winclient);
|
2004-12-21 16:09:36 +00:00
|
|
|
if (app == 0)
|
2003-05-10 22:47:55 +00:00
|
|
|
return; // nothing to do
|
2003-04-26 07:57:00 +00:00
|
|
|
|
2006-08-04 21:43:47 +00:00
|
|
|
// first, set the options that aren't preserved as window properties on
|
2006-08-06 22:33:54 +00:00
|
|
|
// restart, then return if fluxbox is restarting -- we want restart to
|
2006-08-04 21:43:47 +00:00
|
|
|
// disturb the current window state as little as possible
|
2003-07-04 01:03:41 +00:00
|
|
|
|
2006-08-04 21:43:47 +00:00
|
|
|
if (app->focushiddenstate_remember)
|
2006-12-27 04:49:17 +00:00
|
|
|
win.setFocusHidden(app->focushiddenstate);
|
2006-08-04 21:43:47 +00:00
|
|
|
if (app->iconhiddenstate_remember)
|
2006-12-27 04:49:17 +00:00
|
|
|
win.setIconHidden(app->iconhiddenstate);
|
2006-08-04 21:43:47 +00:00
|
|
|
if (app->layer_remember)
|
|
|
|
win.moveToLayer(app->layer);
|
|
|
|
if (app->decostate_remember)
|
|
|
|
win.setDecorationMask(app->decostate);
|
|
|
|
|
2007-01-07 11:55:14 +00:00
|
|
|
if (app->alpha_remember) {
|
2007-12-27 04:42:10 +00:00
|
|
|
win.frame().setDefaultAlpha();
|
2007-01-07 11:55:14 +00:00
|
|
|
win.frame().setAlpha(true,app->focused_alpha);
|
|
|
|
win.frame().setAlpha(false,app->unfocused_alpha);
|
|
|
|
}
|
|
|
|
|
2003-07-04 01:03:41 +00:00
|
|
|
BScreen &screen = winclient.screen();
|
2003-04-26 07:57:00 +00:00
|
|
|
|
2006-08-06 22:33:54 +00:00
|
|
|
// now check if fluxbox is restarting
|
|
|
|
if (screen.isRestart())
|
|
|
|
return;
|
|
|
|
|
2003-04-26 07:57:00 +00:00
|
|
|
if (app->workspace_remember) {
|
2005-05-13 11:01:01 +00:00
|
|
|
// we use setWorkspace and not reassoc because we're still initialising
|
|
|
|
win.setWorkspace(app->workspace);
|
2006-12-27 04:49:17 +00:00
|
|
|
if (app->jumpworkspace_remember && app->jumpworkspace)
|
2003-04-26 07:57:00 +00:00
|
|
|
screen.changeWorkspaceID(app->workspace);
|
|
|
|
}
|
|
|
|
|
2004-12-21 16:09:36 +00:00
|
|
|
if (app->head_remember) {
|
2007-10-23 17:34:30 +00:00
|
|
|
win.setOnHead(app->head);
|
2004-12-21 16:09:36 +00:00
|
|
|
}
|
|
|
|
|
2003-04-26 07:57:00 +00:00
|
|
|
if (app->dimensions_remember)
|
|
|
|
win.resize(app->w, app->h);
|
2004-12-21 16:09:36 +00:00
|
|
|
|
2003-12-11 15:23:14 +00:00
|
|
|
if (app->position_remember) {
|
2008-08-18 12:12:30 +00:00
|
|
|
int newx = app->x, newy = app->y;
|
|
|
|
win.translateCoords(newx, newy, app->refc);
|
|
|
|
win.move(newx, newy);
|
2003-12-11 15:23:14 +00:00
|
|
|
}
|
2003-04-26 07:57:00 +00:00
|
|
|
|
|
|
|
if (app->shadedstate_remember)
|
|
|
|
// if inconsistent...
|
2008-08-16 12:54:07 +00:00
|
|
|
if ((win.isShaded() && !app->shadedstate) ||
|
|
|
|
(!win.isShaded() && app->shadedstate))
|
2003-04-26 07:57:00 +00:00
|
|
|
win.shade(); // toggles
|
|
|
|
|
|
|
|
// external tabs aren't available atm...
|
|
|
|
//if (app->tabstate_remember) ...
|
|
|
|
|
|
|
|
if (app->stuckstate_remember)
|
|
|
|
// if inconsistent...
|
2008-08-16 12:54:07 +00:00
|
|
|
if ((win.isStuck() && !app->stuckstate) ||
|
|
|
|
(!win.isStuck() && app->stuckstate))
|
2003-04-26 07:57:00 +00:00
|
|
|
win.stick(); // toggles
|
2003-04-26 13:47:53 +00:00
|
|
|
|
2011-02-03 17:50:17 +00:00
|
|
|
if (app->focusnewwindow_remember)
|
|
|
|
win.setFocusNew(app->focusnewwindow);
|
|
|
|
|
2007-10-23 17:34:30 +00:00
|
|
|
if (app->minimizedstate_remember) {
|
|
|
|
// if inconsistent...
|
|
|
|
// this one doesn't actually work, but I can't imagine needing it
|
|
|
|
if (win.isIconic() && !app->minimizedstate)
|
|
|
|
win.deiconify();
|
|
|
|
else if (!win.isIconic() && app->minimizedstate)
|
|
|
|
win.iconify();
|
|
|
|
}
|
|
|
|
|
|
|
|
// I can't really test the "no" case of this
|
|
|
|
if (app->maximizedstate_remember)
|
|
|
|
win.setMaximizedState(app->maximizedstate);
|
|
|
|
|
|
|
|
// I can't really test the "no" case of this
|
|
|
|
if (app->fullscreenstate_remember)
|
|
|
|
win.setFullscreen(app->fullscreenstate);
|
2003-04-26 07:57:00 +00:00
|
|
|
}
|
|
|
|
|
2003-07-04 01:03:41 +00:00
|
|
|
void Remember::setupClient(WinClient &winclient) {
|
|
|
|
|
2007-06-08 19:39:12 +00:00
|
|
|
// leave windows alone on restart
|
2007-10-14 18:05:31 +00:00
|
|
|
if (winclient.screen().isRestart())
|
2007-06-08 19:39:12 +00:00
|
|
|
return;
|
2006-08-05 01:39:45 +00:00
|
|
|
|
2008-05-12 16:00:02 +00:00
|
|
|
// check if apps file has changed
|
2008-05-12 16:30:13 +00:00
|
|
|
checkReload();
|
2008-05-12 16:00:02 +00:00
|
|
|
|
2003-07-04 01:03:41 +00:00
|
|
|
Application *app = find(winclient);
|
2004-12-21 16:09:36 +00:00
|
|
|
if (app == 0)
|
2003-07-04 01:03:41 +00:00
|
|
|
return; // nothing to do
|
|
|
|
|
2007-02-05 17:20:01 +00:00
|
|
|
FluxboxWindow *group;
|
|
|
|
if (winclient.fbwindow() == 0 && app->is_grouped &&
|
|
|
|
(group = findGroup(app, winclient.screen()))) {
|
|
|
|
group->attachClient(winclient);
|
2006-12-27 04:49:17 +00:00
|
|
|
if (app->jumpworkspace_remember && app->jumpworkspace)
|
|
|
|
// jump to window, not saved workspace
|
2007-02-05 17:20:01 +00:00
|
|
|
winclient.screen().changeWorkspaceID(group->workspaceNumber());
|
2003-07-04 01:03:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-02-05 17:20:01 +00:00
|
|
|
FluxboxWindow *Remember::findGroup(Application *app, BScreen &screen) {
|
|
|
|
if (!app || !app->is_grouped)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
// find the first client associated with the app and return its fbwindow
|
|
|
|
Clients::iterator it = m_clients.begin();
|
|
|
|
Clients::iterator it_end = m_clients.end();
|
|
|
|
for (; it != it_end; ++it) {
|
|
|
|
if (it->second == app && it->first->fbwindow() &&
|
|
|
|
&screen == &it->first->screen() &&
|
2007-10-13 21:51:37 +00:00
|
|
|
(!*app->group_pattern || app->group_pattern->match(*it->first)))
|
2007-02-05 17:20:01 +00:00
|
|
|
return it->first->fbwindow();
|
|
|
|
}
|
|
|
|
|
|
|
|
// there weren't any open, but that's ok
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2008-08-14 05:53:38 +00:00
|
|
|
void Remember::updateDecoStateFromClient(WinClient& winclient) {
|
|
|
|
|
|
|
|
Application* app= find(winclient);
|
|
|
|
|
|
|
|
if ( app && isRemembered(winclient, REM_DECOSTATE)) {
|
|
|
|
winclient.fbwindow()->setDecorationMask(app->decostate);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-07-04 14:06:20 +00:00
|
|
|
void Remember::updateClientClose(WinClient &winclient) {
|
2008-05-12 16:30:13 +00:00
|
|
|
checkReload(); // reload if it's changed
|
2003-07-04 14:06:20 +00:00
|
|
|
Application *app = find(winclient);
|
|
|
|
|
2008-08-20 12:26:12 +00:00
|
|
|
if (app) {
|
|
|
|
Patterns::iterator it = m_pats->begin();
|
|
|
|
for (; it != m_pats->end(); it++) {
|
|
|
|
if (it->second == app) {
|
|
|
|
it->first->removeMatch();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-07-04 14:06:20 +00:00
|
|
|
if (app && (app->save_on_close_remember && app->save_on_close)) {
|
2003-06-12 15:12:19 +00:00
|
|
|
|
2006-06-27 08:54:24 +00:00
|
|
|
for (int attrib = 0; attrib < REM_LASTATTRIB; attrib++) {
|
2003-07-04 14:06:20 +00:00
|
|
|
if (isRemembered(winclient, (Attribute) attrib)) {
|
|
|
|
rememberAttrib(winclient, (Attribute) attrib);
|
|
|
|
}
|
|
|
|
}
|
2003-07-04 01:03:41 +00:00
|
|
|
|
2003-07-04 14:06:20 +00:00
|
|
|
save();
|
|
|
|
}
|
2003-04-26 07:57:00 +00:00
|
|
|
|
2003-07-04 14:06:20 +00:00
|
|
|
// we need to get rid of references to this client
|
|
|
|
Clients::iterator wc_it = m_clients.find(&winclient);
|
2003-06-12 15:12:19 +00:00
|
|
|
|
2003-07-04 14:06:20 +00:00
|
|
|
if (wc_it != m_clients.end()) {
|
2003-06-12 15:12:19 +00:00
|
|
|
m_clients.erase(wc_it);
|
2003-07-04 14:06:20 +00:00
|
|
|
}
|
2003-04-26 07:57:00 +00:00
|
|
|
|
2003-07-04 14:06:20 +00:00
|
|
|
}
|
2003-04-26 07:57:00 +00:00
|
|
|
|
2005-06-23 03:07:25 +00:00
|
|
|
void Remember::initForScreen(BScreen &screen) {
|
|
|
|
// All windows get the remember menu.
|
2005-06-23 09:22:11 +00:00
|
|
|
_FB_USES_NLS;
|
2006-06-21 14:41:16 +00:00
|
|
|
screen.addExtraWindowMenu(_FB_XTEXT(Remember, MenuItemName, "Remember...", "Remember item in menu"),
|
2005-06-23 03:07:25 +00:00
|
|
|
createRememberMenu(screen));
|
|
|
|
|
|
|
|
}
|