diff -u -r -N -x depcomp -x Entries -x aclocal.m4 -x Makefile.in -x config.guess -x config.sub -x ltmain.sh -x ltconfig -x Entries.Log -x config.h.in -x Translation.m -x configure fluxbox-0.1.14/autogen.sh fluxbox-0.1.14-remember/autogen.sh --- fluxbox-0.1.14/autogen.sh Thu Jan 1 01:00:00 1970 +++ fluxbox-0.1.14-remember/autogen.sh Fri Nov 15 13:47:27 2002 @@ -0,0 +1,10 @@ +#!/bin/sh +libtoolize --copy --force --automake +rm -f config.cache +aclocal +autoheader +automake -a +autoconf +echo "Done." + + diff -u -r -N -x depcomp -x Entries -x aclocal.m4 -x Makefile.in -x config.guess -x config.sub -x ltmain.sh -x ltconfig -x Entries.Log -x config.h.in -x Translation.m -x configure fluxbox-0.1.14/doc/fluxbox.1.in fluxbox-0.1.14-remember/doc/fluxbox.1.in --- fluxbox-0.1.14/doc/fluxbox.1.in Sun Sep 22 15:55:22 2002 +++ fluxbox-0.1.14-remember/doc/fluxbox.1.in Mon Dec 9 15:46:12 2002 @@ -323,6 +323,9 @@ An .B [end] tag is required to end the submenu. +.IP +If you create a submenu labelled 'Startup', applications located in this +submenu will be launched on fluxbox startup. .TP .B [reconfig] (label) When selected, this item rereads the current style and menu files and @@ -375,6 +378,12 @@ [exec] (edit) {mozilla -edit} [exec] (compose) {mozilla -compose} [end] + [submenu] (Startup) + [exec] (gkrellm) {gkrellm -w} + [exec] (xmms) {xmms -p} + [exec] (galeon) {galeon -s} + [exec] (kdeinit) {kdeinit} + [end] [submenu] (Window Manager) [exec] (Edit Menus) {nedit ~/.fluxbox/menu} [submenu] (Style) {Which Style?} @@ -1069,6 +1078,66 @@ This way the main workspace (screen0) has the maximum amount of space available and the secondary workspace could show the time and run some withrawn apps like gkrellm in the slit, always visible yet out of the way of real work. +.SH APPLICATIONS SETTINGS +Sometimes, you want to force an application to have always the same dimensions, +position, and other settings. It is now possible with the new window-submenu +called 'Remember...'. Settings are saved in the +.I ~/.fluxbox/apps +file. You don't have to edit the file yourself as all manipulations can be +done using the 'Remember...' submenu. +.TP +.B Workspace [0-N] +Force the workspace of the application to be the current one, even if you launch +the application from another workspace. +.TP +.B Dimensions [Width Height] +Remember the current dimensions. +.TP +.B Position [X Y] +Remember the current position. +.TP +.B Shaded state [yes|no] +Remember the current shaded state. +.TP +.B Tab state [yes|no] +Remember the current tab state. +.TP +.B Decoration state [NONE|NORMAL|TOOL|TINY] +Remember the current decoration state. +.TP +.B Sticky state [yes|no] +Remember the current sticky state. +.TP +.B Jump to workspace [yes|no] +This one is only useful if 'Workspace' is set too. The workspace is changed +to the workspace containing the application being launched. +.TP +.B Save settings on close [yes|no] +By default, application settings are not saved when a window is closed. Set +this option if you want previous settings to be saved when the window is closed. +.SS Applications example +Here is a short example of an apps file: +.PP +.nf +[app] (kate) + [Dimensions] {1022 747} + [Position] {0 0} + [Close] {yes} +[end] +[app] (konqueror) + [Workspace] {1} + [Dimensions] {1006 749} + [Position] {16 0} + [Jump] {yes} +[end] +[app] (xterm) + [Deco] {NONE} +[end] +.fi + +Parameters in the 'apps' file are case-sensitive. Application names are taken +from the first X-Window WM_CLASS attribute. You can see this attribute by using +the xprop command. Transient windows are not affected by application settings. .SH ENVIRONMENT .TP .B HOME diff -u -r -N -x depcomp -x Entries -x aclocal.m4 -x Makefile.in -x config.guess -x config.sub -x ltmain.sh -x ltconfig -x Entries.Log -x config.h.in -x Translation.m -x configure fluxbox-0.1.14/nls/C/Windowmenu.m fluxbox-0.1.14-remember/nls/C/Windowmenu.m --- fluxbox-0.1.14/nls/C/Windowmenu.m Mon Dec 17 20:49:45 2001 +++ fluxbox-0.1.14-remember/nls/C/Windowmenu.m Mon Dec 9 15:46:12 2002 @@ -22,3 +22,23 @@ # Close $ #Tab # Tab +$ #Remember +# Remember ... +$ #RememberWorkspace +# Workspace +$ #RememberDimensions +# Dimensions +$ #RememberPosition +# Position +$ #RememberShaded +# Shaded state +$ #RememberTab +# Tab state +$ #RememberDeco +# Decoration state +$ #RememberSticky +# Sticky state +$ #RememberJump +# Jump to Workspace +$ #RememberSave +# Save settings on close diff -u -r -N -x depcomp -x Entries -x aclocal.m4 -x Makefile.in -x config.guess -x config.sub -x ltmain.sh -x ltconfig -x Entries.Log -x config.h.in -x Translation.m -x configure fluxbox-0.1.14/nls/blackbox-nls.hh fluxbox-0.1.14-remember/nls/blackbox-nls.hh --- fluxbox-0.1.14/nls/blackbox-nls.hh Sun Dec 8 03:20:38 2002 +++ fluxbox-0.1.14-remember/nls/blackbox-nls.hh Mon Dec 9 15:46:12 2002 @@ -124,6 +124,16 @@ WindowmenuKillClient = 0x9, WindowmenuClose = 0xa, WindowmenuTab = 0xb, + WindowmenuRemember = 0xc, + WindowmenuRememberWorkspace = 0xd, + WindowmenuRememberDimensions = 0xe, + WindowmenuRememberPosition = 0xf, + WindowmenuRememberShaded = 0x10, + WindowmenuRememberTab = 0x11, + WindowmenuRememberDeco = 0x12, + WindowmenuRememberSticky = 0x13, + WindowmenuRememberJump = 0x14, + WindowmenuRememberSave = 0x15, WorkspaceSet = 0xb, WorkspaceDefaultNameFormat = 0x1, diff -u -r -N -x depcomp -x Entries -x aclocal.m4 -x Makefile.in -x config.guess -x config.sub -x ltmain.sh -x ltconfig -x Entries.Log -x config.h.in -x Translation.m -x configure fluxbox-0.1.14/nls/fr_FR/Windowmenu.m fluxbox-0.1.14-remember/nls/fr_FR/Windowmenu.m --- fluxbox-0.1.14/nls/fr_FR/Windowmenu.m Sat Jan 5 17:23:31 2002 +++ fluxbox-0.1.14-remember/nls/fr_FR/Windowmenu.m Mon Dec 9 15:46:12 2002 @@ -22,3 +22,23 @@ # Fermer $ #Tab # Onglet +$ #Remember +# Retenir ... +$ #RememberWorkspace +# Bureau +$ #RememberDimensions +# Dimensions +$ #RememberPosition +# Position +$ #RememberShaded +# Etat ombr� +$ #RememberTab +# Etat de l'onglet +$ #RememberDeco +# Etat des d�corations +$ #RememberSticky +# Etat collant +$ #RememberJump +# Aller au bureau +$ #RememberSave +# Sauver les param�tres � la fermeture diff -u -r -N -x depcomp -x Entries -x aclocal.m4 -x Makefile.in -x config.guess -x config.sub -x ltmain.sh -x ltconfig -x Entries.Log -x config.h.in -x Translation.m -x configure fluxbox-0.1.14/src/Application.cc fluxbox-0.1.14-remember/src/Application.cc --- fluxbox-0.1.14/src/Application.cc Thu Jan 1 01:00:00 1970 +++ fluxbox-0.1.14-remember/src/Application.cc Mon Dec 9 15:46:12 2002 @@ -0,0 +1,227 @@ +// Application.cc for Fluxbox Window Manager +// Copyright (c) 2002 Xavier Brouckaert +// +// 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. + +//use GNU extensions +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif // _GNU_SOURCE + +#include <iostream> +#include <string> +#include <memory> +#include <sstream> +#include <fstream> +#include <stdio.h> + +#include "Application.hh" +#include "fluxbox.hh" + +#ifndef MAXPATHLEN +#define MAXPATHLEN 255 +#endif // MAXPATHLEN + +Application::Application() { + workspace_remember = + dimensions_remember = + position_remember = + stuckstate_remember = + decostate_remember = + shadedstate_remember = + tabstate_remember = + jumpworkspace_remember = + save_on_close_remember = false; +} + +Applications::Applications() { + load(); +} + +Application* Applications::add(char* app_name) { + if (!app_name) + return NULL; + Application* a = new Application(); + apps[app_name] = a; + return a; +} + +Application* Applications::find(char* app_name) { + if (!app_name) + return NULL; + Apps::iterator i = apps.find(app_name); + if (i!=apps.end()) + return i->second; + else + return NULL; +} + +void Applications::parseApp(ifstream &file, Application *a) { + string line; + + while (! file.eof()) { + if (getline(file, line)) { + if (line[0] != '#') { //the line is commented + int parse_pos = 0, err = 0; + std::string str_key, str_label; + err = StringUtil::getStringBetween(str_key, line.c_str(), '[', ']'); + if (err > 0 ) { + parse_pos += err; + err = StringUtil::getStringBetween(str_label, line.c_str() + parse_pos, '{', '}'); + if (err>0) { + parse_pos += err; + } + } else + continue; //read next line + if (!str_key.size()) + continue; //read next line + if (str_key == "Workspace") { + unsigned int w; + istringstream iss(str_label.c_str()); + iss >> w; + a->rememberWorkspace(w); + } else if (str_key == "Dimensions") { + unsigned int h,w; + istringstream iss(str_label.c_str()); + iss >> w >> h; + a->rememberDimensions(w,h); + } else if (str_key == "Position") { + unsigned int x,y; + istringstream iss(str_label); + iss >> x >> y; + a->rememberPosition(x,y); + } else if (str_key == "Shaded") { + a->rememberShadedstate((str_label=="yes")); + } else if (str_key == "Tab") { + a->rememberTabstate((str_label=="yes")); + } else if (str_key == "Deco") { + if (str_label == "NONE") { + a->rememberDecostate(FluxboxWindow::DECOR_NONE); + } else if (str_label == "NORMAL") { + a->rememberDecostate(FluxboxWindow::DECOR_NORMAL); + } else if (str_label == "TINY") { + a->rememberDecostate(FluxboxWindow::DECOR_TINY); + } else if (str_label == "TOOL") { + a->rememberDecostate(FluxboxWindow::DECOR_TOOL); + } + } else if (str_key == "Sticky") { + a->rememberStuckstate((str_label=="yes")); + } else if (str_key == "Jump") { + a->rememberJumpworkspace((str_label=="yes")); + } else if (str_key == "Close") { + a->rememberSave((str_label=="yes")); + } else if (str_key == "end") { + return; + } else { + cerr << "Unsupported apps key = " << str_key << endl; + } + } + } + } +} + +void Applications::load() { + cerr << "Loading apps file..." << endl; + string apps_string = getenv("HOME")+string("/.")+RC_PATH+string("/")+"apps"; + ifstream apps_file(apps_string.c_str()); + if (!apps_file.fail()) { + if (!apps_file.eof()) { + string line; + int row = 0; + while (getline(apps_file, line) && ! apps_file.eof()) { + row++; + if (line[0] != '#') { + string key; + int pos=0; + int err = StringUtil::getStringBetween(key, line.c_str(), '[', ']'); + + if (key == "app") { + pos += err; + string label; + err = StringUtil::getStringBetween(label, line.c_str()+pos, '(', ')'); + if (err>0) { + Application *a; + Apps::iterator i = apps.find(label); + if (i==apps.end()) { + a = new Application(); + apps[label] = a; + } else + a = i->second; + parseApp(apps_file, a); + } else + cerr<<"Error in apps file. Line("<<row<<")"<<endl; + } + } + } + } else { + cerr<<__FILE__<<"("<<__LINE__<< "Empty apps file" << endl; + } + } else { + cerr << "apps file failure" << endl; + } +} + +void Applications::save() { + cerr << "Saving apps file..." << endl; + string apps_string = getenv("HOME")+string("/.")+RC_PATH+string("/")+"apps"; + ofstream apps_file(apps_string.c_str()); + 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 (FluxboxWindow::DECOR_NONE) : + apps_file << " [Deco]\t{NONE}" << endl; break; + case (FluxboxWindow::DECOR_NORMAL) : + apps_file << " [Deco]\t{NORMAL}" << endl; break; + case (FluxboxWindow::DECOR_TINY) : + apps_file << " [Deco]\t{TINY}" << endl; break; + case (FluxboxWindow::DECOR_TOOL) : + apps_file << " [Deco]\t{TOOL}" << 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; + } + if (a->save_on_close_remember) { + apps_file << " [Close]\t{" << ((a->save_on_close)?"yes":"no") << "}" << endl; + } + apps_file << "[end]" << endl; + } +} diff -u -r -N -x depcomp -x Entries -x aclocal.m4 -x Makefile.in -x config.guess -x config.sub -x ltmain.sh -x ltconfig -x Entries.Log -x config.h.in -x Translation.m -x configure fluxbox-0.1.14/src/Application.hh fluxbox-0.1.14-remember/src/Application.hh --- fluxbox-0.1.14/src/Application.hh Thu Jan 1 01:00:00 1970 +++ fluxbox-0.1.14-remember/src/Application.hh Mon Dec 9 15:46:12 2002 @@ -0,0 +1,103 @@ +// Application.hh for Fluxbox Window Manager +// Copyright (c) 2002 Xavier Brouckaert +// +// 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. + +#ifndef APPLICATION_HH +#define APPLICATION_HH + +#include <iostream> +#include <fstream> +#include <string> +#include <map> +#include "Window.hh" +#include "StringUtil.hh" + +using namespace std; + +class Application { +public: + Application(); + inline void forgetWorkspace() { workspace_remember = false; } + inline void forgetDimensions() { dimensions_remember = false; } + inline void forgetPosition() { position_remember = false; } + inline void forgetShadedstate() { shadedstate_remember = false; } + inline void forgetTabstate() { tabstate_remember = false; } + inline void forgetDecostate() { decostate_remember = false; } + inline void forgetStuckstate() { stuckstate_remember = false; } + inline void forgetJumpworkspace() { jumpworkspace_remember = false; } + inline void forgetSave() { save_on_close_remember = false; } + + inline void rememberWorkspace(int ws) { workspace = ws; workspace_remember = true; } + inline void rememberDimensions(int width, int height) { w = width; h = height; dimensions_remember = true; } + inline void rememberPosition(int posx, int posy) { x = posx; y = posy; position_remember = true; } + inline void rememberShadedstate(bool state) { shadedstate = state; shadedstate_remember = true; } + inline void rememberTabstate(bool state) { tabstate = state; tabstate_remember = true; } + inline void rememberDecostate(FluxboxWindow::Decoration state) { decostate = state; decostate_remember = true; } + inline void rememberStuckstate(bool state) { stuckstate = state; stuckstate_remember = true; } + inline void rememberJumpworkspace(bool state) { jumpworkspace = state; jumpworkspace_remember = true; } + inline void rememberSave(bool state) { save_on_close = state; save_on_close_remember = true; } + + + bool workspace_remember; + unsigned int workspace; + + bool dimensions_remember; + int w,h; // width, height + + bool position_remember; + int x,y; + + bool shadedstate_remember; + bool shadedstate; + + bool tabstate_remember; + bool tabstate; + + bool decostate_remember; + FluxboxWindow::Decoration decostate; + + bool stuckstate_remember; + bool stuckstate; + + bool jumpworkspace_remember; + bool jumpworkspace; + + bool save_on_close_remember; + bool save_on_close; +}; + +typedef std::map<string,Application *> Apps; + +class Applications { +private: + void parseApp(ifstream &file, Application *a); + Apps apps; + +public: + Applications(); + + Application* find(char* app_name); + Application* add(char* app_name); + + void load(); + void save(); +}; + +#endif diff -u -r -N -x depcomp -x Entries -x aclocal.m4 -x Makefile.in -x config.guess -x config.sub -x ltmain.sh -x ltconfig -x Entries.Log -x config.h.in -x Translation.m -x configure fluxbox-0.1.14/src/Basemenu.hh fluxbox-0.1.14-remember/src/Basemenu.hh --- fluxbox-0.1.14/src/Basemenu.hh Sat Dec 7 15:15:23 2002 +++ fluxbox-0.1.14-remember/src/Basemenu.hh Mon Dec 9 15:56:56 2002 @@ -110,6 +110,8 @@ bool hasSubmenu(unsigned int index) const; bool isItemSelected(unsigned int index) const; bool isItemEnabled(unsigned int index) const; + typedef std::vector<BasemenuItem *> Menuitems; + inline Menuitems *getMenuitems() { return &menuitems; } //@} protected: @@ -130,7 +132,7 @@ private: - typedef std::vector<BasemenuItem *> Menuitems; + //typedef std::vector<BasemenuItem *> Menuitems; BScreen *m_screen; Display *m_display; Basemenu *m_parent; diff -u -r -N -x depcomp -x Entries -x aclocal.m4 -x Makefile.in -x config.guess -x config.sub -x ltmain.sh -x ltconfig -x Entries.Log -x config.h.in -x Translation.m -x configure fluxbox-0.1.14/src/Makefile.am fluxbox-0.1.14-remember/src/Makefile.am --- fluxbox-0.1.14/src/Makefile.am Sat Dec 7 15:45:25 2002 +++ fluxbox-0.1.14-remember/src/Makefile.am Mon Dec 9 15:59:55 2002 @@ -60,6 +60,7 @@ Tab.hh Tab.cc Theme.hh Theme.cc Timer.cc Timer.hh Toolbar.cc Toolbar.hh Observer.cc Observer.hh\ Window.cc Window.hh Windowmenu.cc Windowmenu.hh \ Workspace.cc Workspace.hh Workspacemenu.cc Workspacemenu.hh \ - XrmDatabaseHelper.hh + XrmDatabaseHelper.hh \ + Application.hh Application.cc LDADD=FbTk/libFbTk.a diff -u -r -N -x depcomp -x Entries -x aclocal.m4 -x Makefile.in -x config.guess -x config.sub -x ltmain.sh -x ltconfig -x Entries.Log -x config.h.in -x Translation.m -x configure fluxbox-0.1.14/src/Rootmenu.cc fluxbox-0.1.14-remember/src/Rootmenu.cc --- fluxbox-0.1.14/src/Rootmenu.cc Sat Dec 7 15:13:58 2002 +++ fluxbox-0.1.14-remember/src/Rootmenu.cc Mon Dec 9 15:46:12 2002 @@ -155,4 +155,14 @@ return w; } +Basemenu* Rootmenu::getStartupMenu() { + for (unsigned int i=0;i<numberOfItems();i++) { + BasemenuItem *item = find(i); + if (item->label()=="Startup") { + return item->submenu(); + } + } + return NULL; +} + diff -u -r -N -x depcomp -x Entries -x aclocal.m4 -x Makefile.in -x config.guess -x config.sub -x ltmain.sh -x ltconfig -x Entries.Log -x config.h.in -x Translation.m -x configure fluxbox-0.1.14/src/Rootmenu.hh fluxbox-0.1.14-remember/src/Rootmenu.hh --- fluxbox-0.1.14/src/Rootmenu.hh Sat Dec 7 15:13:58 2002 +++ fluxbox-0.1.14-remember/src/Rootmenu.hh Mon Dec 9 15:46:12 2002 @@ -32,6 +32,7 @@ explicit Rootmenu(BScreen *scr); void setAutoGroupWindow(Window window); void show(); + Basemenu* getStartupMenu(); protected: virtual void itemSelected(int button, unsigned int index); diff -u -r -N -x depcomp -x Entries -x aclocal.m4 -x Makefile.in -x config.guess -x config.sub -x ltmain.sh -x ltconfig -x Entries.Log -x config.h.in -x Translation.m -x configure fluxbox-0.1.14/src/Screen.cc fluxbox-0.1.14-remember/src/Screen.cc --- fluxbox-0.1.14/src/Screen.cc Sun Dec 8 15:06:29 2002 +++ fluxbox-0.1.14-remember/src/Screen.cc Mon Dec 9 15:46:12 2002 @@ -290,6 +290,7 @@ root_colormap_installed = true; fluxbox->load_rc(this); + fluxbox->getApplications()->load(); image_control->setDither(*resource.image_dither); theme = new Theme(disp, getRootWindow(), colormap(), getScreenNumber(), diff -u -r -N -x depcomp -x Entries -x aclocal.m4 -x Makefile.in -x config.guess -x config.sub -x ltmain.sh -x ltconfig -x Entries.Log -x config.h.in -x Translation.m -x configure fluxbox-0.1.14/src/Window.cc fluxbox-0.1.14-remember/src/Window.cc --- fluxbox-0.1.14/src/Window.cc Sat Dec 7 21:04:24 2002 +++ fluxbox-0.1.14-remember/src/Window.cc Mon Dec 9 15:51:35 2002 @@ -35,6 +35,7 @@ #include "StringUtil.hh" #include "Netizen.hh" #include "Keys.hh" +#include "Application.hh" #ifdef HAVE_CONFIG_H #include "config.h" @@ -72,6 +73,7 @@ lastButtonPressTime(0), m_windowmenu(0), m_layer(LAYER_NORMAL), old_decoration(DECOR_NORMAL), +decor(false), tab(0) { lastFocusTime.tv_sec = lastFocusTime.tv_usec = 0; @@ -307,11 +309,6 @@ m_windowmenu = tmp; } - if (workspace_number < 0 || workspace_number >= screen->getCount()) - screen->getCurrentWorkspace()->addWindow(this, place_window); - else - screen->getWorkspace(workspace_number)->addWindow(this, place_window); - configure(frame.x, frame.y, frame.width, frame.height); if (shaded) { @@ -337,6 +334,61 @@ fprintf(stderr, "%s(%d): FluxboxWindow(this=%p)\n", __FILE__, __LINE__, this); #endif // DEBUG + char *app_name = getWMClass(); + bool workspace_set = false; + if ((app_name) && (!checkTransient2())) { + Application* a = Fluxbox::instance()->getApplications()->find(app_name); + if (a) { // Information exists about this application + if (a->workspace_remember) { + screen->getWorkspace(a->workspace)->addWindow(this, place_window); + workspace_set = true; + if ((a->jumpworkspace_remember) && (a->jumpworkspace)) { + screen->changeWorkspaceID(a->workspace); + } else { + if ((screen->getCurrentWorkspaceID() != a->workspace) && (tab)) + tab->withdraw(); + } + } + if (a->dimensions_remember) { + place_window = false; + configure(frame.x, frame.y, a->w, a->h); + } + if (a->position_remember) { + place_window = false; + configure(a->x, a->y, frame.width, frame.height); + } + if (a->shadedstate_remember) { + if (a->shadedstate) { + shade(); + if (tab) + tab->shade(); + } else { + // Do nothing by now : default is not shaded + } + } + if (a->tabstate_remember) { + setTab(a->tabstate); + } + if (a->decostate_remember) { + setDecoration(a->decostate); + } + if (a->stuckstate_remember) { + if (a->stuckstate) + stick(); + // FIXME: unstick() has been defined in + // Window.hh but not implemented !!! + // else + // unstick(); + } + } + } + if (!workspace_set) { + if (workspace_number < 0 || workspace_number >= screen->getCount()) + screen->getCurrentWorkspace()->addWindow(this, place_window); + else + screen->getWorkspace(workspace_number)->addWindow(this, place_window); + } + fluxbox->ungrab(); } @@ -1068,6 +1120,17 @@ tab->setPosition(); } +char* FluxboxWindow::getWMClass(void) { + XClassHint xch; + + if (XGetClassHint(display, client.window, &xch)) { + char *app_name = StringUtil::strdup(xch.res_name); + XFree((char *)xch.res_name); + XFree((char *)xch.res_class); + return app_name; + } else + return NULL; +} void FluxboxWindow::getWMName() { @@ -1641,8 +1704,35 @@ } } +void FluxboxWindow::save_on_close() { + Fluxbox *fluxbox = Fluxbox::instance(); + Applications *apps = fluxbox->getApplications(); + Application *a = apps->find(getWMClass()); + if (a!=NULL) { + if ((a->save_on_close_remember) && (a->save_on_close)) { + if (a->workspace_remember) + a->rememberWorkspace(screen->getCurrentWorkspaceID()); + if (a->dimensions_remember) + a->rememberDimensions(getWidth(),getHeight()); + if (a->position_remember) + a->rememberPosition(getXFrame(),getYFrame()); + if (a->shadedstate_remember) + a->rememberShadedstate(isShaded()); + if (a->shadedstate_remember) + a->rememberTabstate(hasTab()); + if (a->decostate_remember) + a->rememberDecostate(getDecoration()); + if (a->stuckstate_remember) + a->rememberStuckstate(isStuck()); + if (a->jumpworkspace_remember) + a->rememberJumpworkspace(true); + apps->save(); + } + } +} void FluxboxWindow::close() { + save_on_close(); Fluxbox *fluxbox = Fluxbox::instance(); XEvent ce; ce.xclient.type = ClientMessage; @@ -2357,7 +2447,8 @@ m_windowmenu->show(); m_windowmenu->raise(); m_windowmenu->getSendToMenu().raise(); - m_windowmenu->getSendGroupToMenu().raise(); + m_windowmenu->getSendGroupToMenu().raise(); + m_windowmenu->getRememberMenu().raise(); } void FluxboxWindow::restoreGravity() { @@ -3170,6 +3261,7 @@ } void FluxboxWindow::toggleDecoration() { + static bool decor = false; //don't toggle decor if the window is shaded if (isShaded()) return; @@ -3480,6 +3572,17 @@ frame.handle = 0; } +} + +bool FluxboxWindow::checkTransient2() { + Window win; + if (XGetTransientForHint(display, client.window, &win)) + if (win) + return true; + else + return false; + else + return false; } void FluxboxWindow::checkTransient() { diff -u -r -N -x depcomp -x Entries -x aclocal.m4 -x Makefile.in -x config.guess -x config.sub -x ltmain.sh -x ltconfig -x Entries.Log -x config.h.in -x Translation.m -x configure fluxbox-0.1.14/src/Window.hh fluxbox-0.1.14-remember/src/Window.hh --- fluxbox-0.1.14/src/Window.hh Sat Dec 7 15:15:26 2002 +++ fluxbox-0.1.14-remember/src/Window.hh Mon Dec 9 15:46:12 2002 @@ -55,6 +55,8 @@ class FluxboxWindow : public TimeoutHandler { public: + char* getWMClass(void); + enum WinLayer { LAYER_BOTTOM = 0x01, LAYER_BELOW = 0x02, @@ -204,6 +206,16 @@ //@} void setDecoration(Decoration decoration); + inline Decoration getDecoration() { + if (!decor) { + #ifdef DEBUG + if ((old_decoration!=DECOR_NONE) && (old_decoration!=DECOR_NORMAL) && (old_decoration!=DECOR_TINY) && (old_decoration!=DECOR_TOOL)) + cerr<<__FILE__<<"("<<__LINE__<< "DEBUG: old_decoration fucked up" << endl; + #endif //DEBUG + return old_decoration; + } else + return DECOR_NONE; + } void toggleDecoration(); #ifdef SHAPE @@ -276,6 +288,8 @@ } client; + bool decor; + struct _decorations { bool titlebar, handle, border, iconify, maximize, close, menu, sticky, shade, tab, enabled; @@ -333,12 +347,15 @@ void stopResizing(Window win=0); void updateIcon(); + void save_on_close(); + // Decoration functions void createTitlebar(); void destroyTitlebar(); void createHandle(); void destroyHandle(); void checkTransient(); + bool checkTransient2(); Window findTitleButton(int type); diff -u -r -N -x depcomp -x Entries -x aclocal.m4 -x Makefile.in -x config.guess -x config.sub -x ltmain.sh -x ltconfig -x Entries.Log -x config.h.in -x Translation.m -x configure fluxbox-0.1.14/src/Windowmenu.cc fluxbox-0.1.14-remember/src/Windowmenu.cc --- fluxbox-0.1.14/src/Windowmenu.cc Sat Dec 7 15:14:03 2002 +++ fluxbox-0.1.14-remember/src/Windowmenu.cc Mon Dec 9 15:46:12 2002 @@ -38,6 +38,7 @@ #include "Window.hh" #include "Windowmenu.hh" #include "Workspace.hh" +#include "Application.hh" #include <cstring> @@ -45,7 +46,8 @@ window(win), screen(win.getScreen()), sendToMenu(win), -sendGroupToMenu(win) { +sendGroupToMenu(win), +rememberMenu(win) { setTitleVisibility(False); setMovable(False); @@ -63,6 +65,11 @@ WindowmenuSet, WindowmenuSendGroupTo, "Send Group To ..."), &sendGroupToMenu); + + insert(i18n->getMessage( + WindowmenuSet, WindowmenuRemember, + "Remember ..."), + &rememberMenu); insert(i18n->getMessage( WindowmenuSet, WindowmenuShade, @@ -199,7 +206,8 @@ setItemEnabled(10, window.isResizable()); // tab option only enabled if resizable sendToMenu.reconfigure(); - sendGroupToMenu.reconfigure(); + sendGroupToMenu.reconfigure(); + rememberMenu.reconfigure(); Basemenu::reconfigure(); } @@ -299,5 +307,135 @@ hide(); } +Windowmenu::Remembermenu::Remembermenu(FluxboxWindow &win): Basemenu(win.getScreen()), +m_fbwindow(win) +{ + setTitleVisibility(false); + setMovable(false); + setInternalMenu(); + update(); +} + +void Windowmenu::Remembermenu::show() { + update(); + + Basemenu::show(); +} + +void Windowmenu::Remembermenu::itemSelected(int button, unsigned int index) { + if (button > 1) { + hide(); + return; + } + + if (button == 1) { + char* app_name = fbwin().getWMClass(); + if (app_name) { + Applications *apps = Fluxbox::instance()->getApplications(); + Application *a = apps->find(app_name); + if (a==NULL) + a = apps->add(app_name); + if (!isItemSelected(index)) { + switch (index) { + case 0 : // Workspace + a->rememberWorkspace(screen()->getCurrentWorkspaceID()); + break; + case 1 : // Dimensions + a->rememberDimensions(fbwin().getWidth(), + fbwin().getHeight()); + break; + case 2 : // Position + a->rememberPosition(fbwin().getXFrame(), + fbwin().getYFrame()); + break; + case 3 : // Shaded state + a->rememberShadedstate(fbwin().isShaded()); + break; + case 4 : // Tab state + a->rememberTabstate(fbwin().hasTab()); + break; + case 5 : // Deco state + a->rememberDecostate(fbwin().getDecoration()); + break; + case 6 : // Stuck state + a->rememberStuckstate(fbwin().isStuck()); + break; + case 7 : // Jump to workspace + a->rememberJumpworkspace(true); + break; + case 8 : // Save on close + a->rememberSave(true); + } + } else { + switch (index) { + case 0 : // Workspace + a->forgetWorkspace(); + break; + case 1 : // Dimensions + a->forgetDimensions(); + break; + case 2 : // Position + a->forgetPosition(); + break; + case 3 : // Shaded state + a->forgetShadedstate(); + break; + case 4 : // Tab state + a->forgetTabstate(); + break; + case 5 : // Deco state + a->forgetDecostate(); + break; + case 6 : // Stuck state + a->forgetStuckstate(); + break; + case 7 : // Jump to workspace + a->forgetJumpworkspace(); + break; + case 8 : // Save on close + a->forgetSave(); + break; + } + } + setItemSelected(index,!isItemSelected(index)); + apps->save(); + } + } + Basemenu::update(); +} + +void Windowmenu::Remembermenu::update(void) { + if (numberOfItems() == 0) { + I18n *i18n = I18n::instance(); + using namespace FBNLS; + insert(i18n->getMessage(WindowmenuSet, WindowmenuRememberWorkspace, "Workspace")); + insert(i18n->getMessage(WindowmenuSet, WindowmenuRememberDimensions, "Dimensions")); + insert(i18n->getMessage(WindowmenuSet, WindowmenuRememberPosition, "Position")); + insert(i18n->getMessage(WindowmenuSet, WindowmenuRememberShaded, "Shaded state")); + insert(i18n->getMessage(WindowmenuSet, WindowmenuRememberTab, "Tab state")); + insert(i18n->getMessage(WindowmenuSet, WindowmenuRememberDeco, "Decoration state")); + insert(i18n->getMessage(WindowmenuSet, WindowmenuRememberSticky, "Sticky state")); + insert(i18n->getMessage(WindowmenuSet, WindowmenuRememberJump, "Jump to Workspace")); + insert(i18n->getMessage(WindowmenuSet, WindowmenuRememberSave, "Save settings on close")); + + // Set Selected when needed + char *app_name = fbwin().getWMClass(); + if (app_name) { + Application *a = Fluxbox::instance()->getApplications()->find(app_name); + if (a) { + setItemSelected(0,a->workspace_remember); + setItemSelected(1,a->dimensions_remember); + setItemSelected(2,a->position_remember); + setItemSelected(3,a->shadedstate_remember); + setItemSelected(4,a->tabstate_remember); + setItemSelected(5,a->decostate_remember); + setItemSelected(6,a->stuckstate_remember); + setItemSelected(7,a->jumpworkspace_remember); + setItemSelected(8,a->save_on_close_remember); + } + } + } + Basemenu::update(); +} diff -u -r -N -x depcomp -x Entries -x aclocal.m4 -x Makefile.in -x config.guess -x config.sub -x ltmain.sh -x ltconfig -x Entries.Log -x config.h.in -x Translation.m -x configure fluxbox-0.1.14/src/Windowmenu.hh fluxbox-0.1.14-remember/src/Windowmenu.hh --- fluxbox-0.1.14/src/Windowmenu.hh Sat Dec 7 15:14:03 2002 +++ fluxbox-0.1.14-remember/src/Windowmenu.hh Mon Dec 9 15:46:12 2002 @@ -36,6 +36,8 @@ Basemenu &getSendToMenu() { return sendToMenu; } const Basemenu &getSendGroupToMenu() const { return sendGroupToMenu; } Basemenu &getSendGroupToMenu() { return sendGroupToMenu; } + const Basemenu &getRememberMenu() const { return rememberMenu; } + Basemenu &getRememberMenu() { return rememberMenu; } void reconfigure(); void setClosable(); @@ -70,11 +72,24 @@ protected: virtual void itemSelected(int button, unsigned int index); - }; - + }; + + class Remembermenu : public Basemenu { + public: + Remembermenu(FluxboxWindow &win); + void update(); + + virtual void show(); + FluxboxWindow &fbwin() { return m_fbwindow; } + protected: + virtual void itemSelected(int button, unsigned int index); + private: + FluxboxWindow &m_fbwindow; + }; + SendtoWorkspacemenu sendToMenu; SendGroupToWorkspacemenu sendGroupToMenu; - + Remembermenu rememberMenu; }; diff -u -r -N -x depcomp -x Entries -x aclocal.m4 -x Makefile.in -x config.guess -x config.sub -x ltmain.sh -x ltconfig -x Entries.Log -x config.h.in -x Translation.m -x configure fluxbox-0.1.14/src/fluxbox.cc fluxbox-0.1.14-remember/src/fluxbox.cc --- fluxbox-0.1.14/src/fluxbox.cc Sun Dec 8 16:55:32 2002 +++ fluxbox-0.1.14-remember/src/fluxbox.cc Mon Dec 9 15:46:12 2002 @@ -142,10 +142,6 @@ #endif // HAVE_BASENAME -#define RC_PATH "fluxbox" -#define RC_INIT_FILE "init" - - // X event scanner for enter/leave notifies - adapted from twm typedef struct scanargs { Window w; @@ -2586,4 +2582,38 @@ if (old_screen && old_screen != screen) old_screen->updateNetizenWindowFocus(); +} + +void Fluxbox::launchStartupProgs(void) { + ScreenList::iterator it = screenList.begin(); + ScreenList::iterator it_end = screenList.end(); + + for (; it != it_end; ++it) { + BScreen *screen = (*it); + Basemenu* startupmenu = screen->getRootmenu()->getStartupMenu(); + + if (!startupmenu) + return; + + Basemenu::Menuitems* mi = startupmenu->getMenuitems(); + Basemenu::Menuitems::iterator mit = mi->begin(); + Basemenu::Menuitems::iterator mit_end = mi->end(); + for (; mit != mit_end; ++mit) { + BasemenuItem *app = (*mit); + cerr << app->label() << endl; + if (app->exec().size()) { +#ifndef __EMX__ + char displaystring[MAXPATHLEN]; + sprintf(displaystring, "DISPLAY=%s", + DisplayString(screen->getBaseDisplay()->getXDisplay())); + sprintf(displaystring + strlen(displaystring) - 1, "%d", + screen->getScreenNumber()); + + bexec(app->exec().c_str(), displaystring); +#else // __EMX__ + spawnlp(P_NOWAIT, "cmd.exe", "cmd.exe", "/c", app->exec().c_str(), NULL); +#endif // !__EMX__ + } + } + } } diff -u -r -N -x depcomp -x Entries -x aclocal.m4 -x Makefile.in -x config.guess -x config.sub -x ltmain.sh -x ltconfig -x Entries.Log -x config.h.in -x Translation.m -x configure fluxbox-0.1.14/src/fluxbox.hh fluxbox-0.1.14-remember/src/fluxbox.hh --- fluxbox-0.1.14/src/fluxbox.hh Sat Dec 7 15:15:26 2002 +++ fluxbox-0.1.14-remember/src/fluxbox.hh Mon Dec 9 15:46:12 2002 @@ -27,6 +27,7 @@ #ifndef FLUXBOX_HH #define FLUXBOX_HH +#include "Application.hh" #include "Resource.hh" #include "Keys.hh" #include "BaseDisplay.hh" @@ -72,6 +73,9 @@ class AtomHandler; +#define RC_PATH "fluxbox" +#define RC_INIT_FILE "init" + /** main class for the window manager. singleton type @@ -189,6 +193,9 @@ typedef std::vector<Fluxbox::Titlebar> TitlebarList; + inline Applications* getApplications() { return &applications; } + void launchStartupProgs(void); + private: struct cursor { Cursor session, move, ll_angle, lr_angle; @@ -204,6 +211,8 @@ timeval auto_raise_delay; } resource; + + Applications applications; std::string getRcFilename(); void getDefaultDataFilename(char *, std::string &); diff -u -r -N -x depcomp -x Entries -x aclocal.m4 -x Makefile.in -x config.guess -x config.sub -x ltmain.sh -x ltconfig -x Entries.Log -x config.h.in -x Translation.m -x configure fluxbox-0.1.14/src/main.cc fluxbox-0.1.14-remember/src/main.cc --- fluxbox-0.1.14/src/main.cc Sun Dec 8 16:46:41 2002 +++ fluxbox-0.1.14-remember/src/main.cc Mon Dec 9 15:46:12 2002 @@ -197,6 +197,7 @@ try { fluxbox = new Fluxbox(argc, argv, session_display, rc_file); + fluxbox->launchStartupProgs(); fluxbox->eventLoop(); } catch (std::out_of_range oor) {