diff options
Diffstat (limited to 'src/Slit.cc')
-rw-r--r-- | src/Slit.cc | 133 |
1 files changed, 71 insertions, 62 deletions
diff --git a/src/Slit.cc b/src/Slit.cc index d5d2dde..2e32f27 100644 --- a/src/Slit.cc +++ b/src/Slit.cc | |||
@@ -164,7 +164,67 @@ private: | |||
164 | unsigned int Slit::s_eventmask = SubstructureRedirectMask | ButtonPressMask | | 164 | unsigned int Slit::s_eventmask = SubstructureRedirectMask | ButtonPressMask | |
165 | EnterWindowMask | LeaveWindowMask | ExposureMask; | 165 | EnterWindowMask | LeaveWindowMask | ExposureMask; |
166 | 166 | ||
167 | Slit::Slit(BScreen &scr, FbTk::Layer &layer, const char *filename) | 167 | void Slit::SlitClientsRes::setFromLua(lua::state &l) { |
168 | lua::stack_sentry s(l, -1); | ||
169 | l.checkstack(1); | ||
170 | |||
171 | // to avoid modifying the master copy until we are sure the new list is ok | ||
172 | SlitClients copy(*this); | ||
173 | // this will be the new list once we are done | ||
174 | SlitClients t; | ||
175 | |||
176 | if(l.type(-1) != lua::TTABLE) { | ||
177 | std::cerr << "Cannot convert to a client list from lua type " | ||
178 | << l.type_name(l.type(-1)) << std::endl; | ||
179 | return; | ||
180 | } | ||
181 | for(size_t i = 1; l.rawgeti(-1, i), !l.isnil(-1); l.pop(), ++i) { | ||
182 | if(l.type(-1) != lua::TSTRING && l.type(-1) != lua::TNUMBER) { | ||
183 | std::cerr << "Cannot convert to a client name from lua type " | ||
184 | << l.type_name(l.type(-1)) << std::endl; | ||
185 | continue; | ||
186 | } | ||
187 | const std::string &name = l.tostring(-1); | ||
188 | // look for a matching window | ||
189 | bool found = false; | ||
190 | for(SlitClients::iterator j = copy.begin(); j != copy.end(); ++j) { | ||
191 | if((*j)->matchName().logical() == name) { | ||
192 | t.push_back(*j); | ||
193 | copy.erase(j); | ||
194 | found = true; | ||
195 | break; | ||
196 | } | ||
197 | } | ||
198 | if(!found) { | ||
199 | // no matching window, create a placeholder | ||
200 | t.push_back( new SlitClient(name.c_str()) ); | ||
201 | } | ||
202 | } l.pop(); | ||
203 | |||
204 | // move remaining non-placeholder clients to the new list | ||
205 | while(!copy.empty()) { | ||
206 | if(copy.front()->window() != None) | ||
207 | t.push_back(copy.front()); | ||
208 | copy.pop_front(); | ||
209 | } | ||
210 | SlitClients::operator=(t); | ||
211 | |||
212 | l.pop(); | ||
213 | } | ||
214 | |||
215 | void Slit::SlitClientsRes::pushToLua(lua::state &l) const { | ||
216 | l.checkstack(2); | ||
217 | l.createtable(size()); | ||
218 | lua::stack_sentry s(l); | ||
219 | |||
220 | int j = 1; | ||
221 | for(const_iterator i = begin(); i != end(); ++i) { | ||
222 | l.pushstring((*i)->matchName().logical()); | ||
223 | l.rawseti(-2, j++); | ||
224 | } | ||
225 | } | ||
226 | |||
227 | Slit::Slit(BScreen &scr, FbTk::Layer &layer) | ||
168 | : m_hidden(false), m_visible(false), | 228 | : m_hidden(false), m_visible(false), |
169 | m_screen(scr), | 229 | m_screen(scr), |
170 | m_clientlist_menu(scr.menuTheme(), | 230 | m_clientlist_menu(scr.menuTheme(), |
@@ -188,7 +248,7 @@ Slit::Slit(BScreen &scr, FbTk::Layer &layer, const char *filename) | |||
188 | m_slit_theme(new SlitTheme(scr.rootWindow().screenNumber())), | 248 | m_slit_theme(new SlitTheme(scr.rootWindow().screenNumber())), |
189 | m_strut(0), | 249 | m_strut(0), |
190 | // resources | 250 | // resources |
191 | // lock in first resource | 251 | m_client_list(scr.resourceManager(), scr.name() + ".slit.clientList"), |
192 | m_rc_kde_dockapp(scr.resourceManager(), true, scr.name() + ".slit.acceptKdeDockapps"), | 252 | m_rc_kde_dockapp(scr.resourceManager(), true, scr.name() + ".slit.acceptKdeDockapps"), |
193 | m_rc_auto_hide(scr.resourceManager(), false, scr.name() + ".slit.autoHide"), | 253 | m_rc_auto_hide(scr.resourceManager(), false, scr.name() + ".slit.autoHide"), |
194 | // TODO: this resource name must change | 254 | // TODO: this resource name must change |
@@ -243,11 +303,6 @@ Slit::Slit(BScreen &scr, FbTk::Layer &layer, const char *filename) | |||
243 | 303 | ||
244 | moveToLayer(static_cast<int>(*m_rc_layernum)); | 304 | moveToLayer(static_cast<int>(*m_rc_layernum)); |
245 | 305 | ||
246 | |||
247 | |||
248 | // Get client list for sorting purposes | ||
249 | loadClientList(filename); | ||
250 | |||
251 | setupMenu(); | 306 | setupMenu(); |
252 | } | 307 | } |
253 | 308 | ||
@@ -800,7 +855,6 @@ void Slit::reposition() { | |||
800 | 855 | ||
801 | 856 | ||
802 | void Slit::shutdown() { | 857 | void Slit::shutdown() { |
803 | saveClientList(); | ||
804 | while (!m_client_list.empty()) | 858 | while (!m_client_list.empty()) |
805 | removeClient(m_client_list.front(), true, true); | 859 | removeClient(m_client_list.front(), true, true); |
806 | } | 860 | } |
@@ -824,6 +878,8 @@ void Slit::clientUp(SlitClient* client) { | |||
824 | break; | 878 | break; |
825 | } | 879 | } |
826 | } | 880 | } |
881 | |||
882 | saveClientList(); | ||
827 | } | 883 | } |
828 | 884 | ||
829 | void Slit::clientDown(SlitClient* client) { | 885 | void Slit::clientDown(SlitClient* client) { |
@@ -845,6 +901,8 @@ void Slit::clientDown(SlitClient* client) { | |||
845 | break; | 901 | break; |
846 | } | 902 | } |
847 | } | 903 | } |
904 | |||
905 | saveClientList(); | ||
848 | } | 906 | } |
849 | 907 | ||
850 | void Slit::cycleClientsUp() { | 908 | void Slit::cycleClientsUp() { |
@@ -857,6 +915,8 @@ void Slit::cycleClientsUp() { | |||
857 | m_client_list.erase(it); | 915 | m_client_list.erase(it); |
858 | m_client_list.push_back(client); | 916 | m_client_list.push_back(client); |
859 | reconfigure(); | 917 | reconfigure(); |
918 | |||
919 | saveClientList(); | ||
860 | } | 920 | } |
861 | 921 | ||
862 | void Slit::cycleClientsDown() { | 922 | void Slit::cycleClientsDown() { |
@@ -868,6 +928,8 @@ void Slit::cycleClientsDown() { | |||
868 | m_client_list.remove(client); | 928 | m_client_list.remove(client); |
869 | m_client_list.push_front(client); | 929 | m_client_list.push_front(client); |
870 | reconfigure(); | 930 | reconfigure(); |
931 | |||
932 | saveClientList(); | ||
871 | } | 933 | } |
872 | 934 | ||
873 | void Slit::handleEvent(XEvent &event) { | 935 | void Slit::handleEvent(XEvent &event) { |
@@ -998,40 +1060,6 @@ void Slit::toggleHidden() { | |||
998 | frame.window.move(frame.x, frame.y); | 1060 | frame.window.move(frame.x, frame.y); |
999 | } | 1061 | } |
1000 | 1062 | ||
1001 | void Slit::loadClientList(const char *filename) { | ||
1002 | if (filename == 0 || filename[0] == '\0') | ||
1003 | return; | ||
1004 | |||
1005 | // save filename so we can save client list later | ||
1006 | m_filename = filename; | ||
1007 | string real_filename= FbTk::StringUtil::expandFilename(filename); | ||
1008 | |||
1009 | struct stat buf; | ||
1010 | if (stat(real_filename.c_str(), &buf) == 0) { | ||
1011 | ifstream file(real_filename.c_str()); | ||
1012 | string name; | ||
1013 | while (! file.eof()) { | ||
1014 | name = ""; | ||
1015 | getline(file, name); // get the entire line | ||
1016 | if (name.empty()) | ||
1017 | continue; | ||
1018 | |||
1019 | // remove whitespaces from start and end | ||
1020 | FbTk::StringUtil::removeFirstWhitespace(name); | ||
1021 | |||
1022 | // the cleaned string could still be a comment, or blank | ||
1023 | if ( name.empty() || name[0] == '#' || name[0] == '!' ) | ||
1024 | continue; | ||
1025 | |||
1026 | // trailing whitespace won't affect the above test | ||
1027 | FbTk::StringUtil::removeTrailingWhitespace(name); | ||
1028 | |||
1029 | SlitClient *client = new SlitClient(name.c_str()); | ||
1030 | m_client_list.push_back(client); | ||
1031 | } | ||
1032 | } | ||
1033 | } | ||
1034 | |||
1035 | void Slit::updateClientmenu() { | 1063 | void Slit::updateClientmenu() { |
1036 | if (screen().isShuttingdown()) | 1064 | if (screen().isShuttingdown()) |
1037 | return; | 1065 | return; |
@@ -1055,30 +1083,11 @@ void Slit::updateClientmenu() { | |||
1055 | m_clientlist_menu.insert(new SlitClientMenuItem(*this, *(*it), reconfig)); | 1083 | m_clientlist_menu.insert(new SlitClientMenuItem(*this, *(*it), reconfig)); |
1056 | } | 1084 | } |
1057 | 1085 | ||
1058 | m_clientlist_menu.insert(new FbTk::MenuSeparator()); | ||
1059 | FbTk::RefCount<FbTk::Command<void> > savecmd(new FbTk::SimpleCommand<Slit>(*this, &Slit::saveClientList)); | ||
1060 | m_clientlist_menu.insert(_FB_XTEXT(Slit, | ||
1061 | SaveSlitList, | ||
1062 | "Save SlitList", "Saves the current order in the slit"), | ||
1063 | savecmd); | ||
1064 | |||
1065 | m_clientlist_menu.updateMenu(); | 1086 | m_clientlist_menu.updateMenu(); |
1066 | } | 1087 | } |
1067 | 1088 | ||
1068 | void Slit::saveClientList() { | 1089 | void Slit::saveClientList() { |
1069 | 1090 | Fluxbox::instance()->save_rc(); | |
1070 | ofstream file(FbTk::StringUtil::expandFilename(m_filename).c_str()); | ||
1071 | SlitClients::iterator it = m_client_list.begin(); | ||
1072 | SlitClients::iterator it_end = m_client_list.end(); | ||
1073 | string prevName; | ||
1074 | string name; | ||
1075 | for (; it != it_end; ++it) { | ||
1076 | name = (*it)->matchName().logical(); | ||
1077 | if (name != prevName) | ||
1078 | file << name.c_str() << endl; | ||
1079 | |||
1080 | prevName = name; | ||
1081 | } | ||
1082 | } | 1091 | } |
1083 | 1092 | ||
1084 | void Slit::setupMenu() { | 1093 | void Slit::setupMenu() { |