1 // openbox.cc for Openbox
2 // Copyright (c) 2001 Sean 'Shaleh' Perry <shaleh@debian.org>
3 // Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
5 // Permission is hereby granted, free of charge, to any person obtaining a
6 // copy of this software and associated documentation files (the "Software"),
7 // to deal in the Software without restriction, including without limitation
8 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 // and/or sell copies of the Software, and to permit persons to whom the
10 // Software is furnished to do so, subject to the following conditions:
12 // The above copyright notice and this permission notice shall be included in
13 // all copies or substantial portions of the Software.
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 // DEALINGS IN THE SOFTWARE.
23 // stupid macros needed to access some functions in version 2 of the GNU C
30 # include "../config.h"
31 #endif // HAVE_CONFIG_H
34 #include <X11/Xutil.h>
35 #include <X11/Xresource.h>
36 #include <X11/Xatom.h>
37 #include <X11/keysym.h>
40 #include <X11/extensions/shape.h>
46 #include "Clientmenu.h"
56 #include "Workspace.h"
57 #include "Workspacemenu.h"
61 #endif // HAVE_STDIO_H
66 #endif // STDC_HEADERS
69 # include <sys/types.h>
71 #endif // HAVE_UNISTD_H
73 #ifdef HAVE_SYS_PARAM_H
74 # include <sys/param.h>
75 #endif // HAVE_SYS_PARAM_H
78 #define MAXPATHLEN 255
81 #ifdef HAVE_SYS_SELECT_H
82 # include <sys/select.h>
83 #endif // HAVE_SYS_SELECT_H
87 #endif // HAVE_SIGNAL_H
89 #ifdef HAVE_SYS_SIGNAL_H
90 # include <sys/signal.h>
91 #endif // HAVE_SYS_SIGNAL_H
93 #ifdef HAVE_SYS_STAT_H
94 # include <sys/types.h>
95 # include <sys/stat.h>
96 #endif // HAVE_SYS_STAT_H
98 #ifdef TIME_WITH_SYS_TIME
99 # include <sys/time.h>
101 #else // !TIME_WITH_SYS_TIME
102 # ifdef HAVE_SYS_TIME_H
103 # include <sys/time.h>
104 # else // !HAVE_SYS_TIME_H
106 # endif // HAVE_SYS_TIME_H
107 #endif // TIME_WITH_SYS_TIME
111 #endif // HAVE_LIBGEN_H
113 #ifndef HAVE_BASENAME
114 static inline char *basename (char *s) {
117 while (*s) if (*s++ == '/') save = s;
121 #endif // HAVE_BASENAME
124 // X event scanner for enter/leave notifies - adapted from twm
125 typedef struct scanargs {
127 Bool leave, inferior, enter;
130 static Bool queueScanner(Display *, XEvent *e, char *args) {
131 if ((e->type == LeaveNotify) &&
132 (e->xcrossing.window == ((scanargs *) args)->w) &&
133 (e->xcrossing.mode == NotifyNormal)) {
134 ((scanargs *) args)->leave = True;
135 ((scanargs *) args)->inferior = (e->xcrossing.detail == NotifyInferior);
136 } else if ((e->type == EnterNotify) &&
137 (e->xcrossing.mode == NotifyUngrab)) {
138 ((scanargs *) args)->enter = True;
147 Openbox::Openbox(int m_argc, char **m_argv, char *dpy_name, char *rc)
148 : BaseDisplay(m_argv[0], dpy_name) {
151 if (! XSupportsLocale())
152 fprintf(stderr, "X server does not support locale\n");
154 if (XSetLocaleModifiers("") == NULL)
155 fprintf(stderr, "cannot set locale modifiers\n");
161 char *homedir = getenv("HOME");
163 rc_file = new char[strlen(homedir) + strlen("/.openbox/rc") + 1];
164 sprintf(rc_file, "%s/.openbox", homedir);
166 // try to make sure the ~/.openbox directory exists
167 mkdir(rc_file, S_IREAD | S_IWRITE | S_IEXEC | S_IRGRP | S_IWGRP | S_IXGRP |
168 S_IROTH | S_IWOTH | S_IXOTH);
170 sprintf(rc_file, "%s/.openbox/rc", homedir);
172 rc_file = bstrdup(rc);
177 resource.menu_file = resource.style_file = (char *) 0;
178 resource.titlebar_layout = (char *) NULL;
179 resource.auto_raise_delay.tv_sec = resource.auto_raise_delay.tv_usec = 0;
181 focused_window = masked_window = (OpenboxWindow *) 0;
184 windowSearchList = new LinkedList<WindowSearch>;
185 menuSearchList = new LinkedList<MenuSearch>;
188 slitSearchList = new LinkedList<SlitSearch>;
191 toolbarSearchList = new LinkedList<ToolbarSearch>;
192 groupSearchList = new LinkedList<WindowSearch>;
194 menuTimestamps = new LinkedList<MenuTimestamp>;
200 openbox_pid = XInternAtom(getXDisplay(), "_BLACKBOX_PID", False);
201 #endif // HAVE_GETPID
203 screenList = new LinkedList<BScreen>;
204 for (int i = 0; i < getNumberOfScreens(); i++) {
205 BScreen *screen = new BScreen(this, i);
207 if (! screen->isScreenManaged()) {
212 screenList->insert(screen);
215 if (! screenList->count()) {
217 i18n->getMessage(openboxSet, openboxNoManagableScreens,
218 "Openbox::Openbox: no managable screens found, aborting.\n"));
222 XSynchronize(getXDisplay(), False);
223 XSync(getXDisplay(), False);
225 reconfigure_wait = reread_menu_wait = False;
227 timer = new BTimer(this, this);
228 timer->setTimeout(0);
229 timer->fireOnce(True);
235 Openbox::~Openbox(void) {
236 while (screenList->count())
237 delete screenList->remove(0);
239 while (menuTimestamps->count()) {
240 MenuTimestamp *ts = menuTimestamps->remove(0);
243 delete [] ts->filename;
248 if (resource.menu_file)
249 delete [] resource.menu_file;
251 if (resource.style_file)
252 delete [] resource.style_file;
257 delete menuTimestamps;
259 delete windowSearchList;
260 delete menuSearchList;
261 delete toolbarSearchList;
262 delete groupSearchList;
267 delete slitSearchList;
272 void Openbox::process_event(XEvent *e) {
273 if ((masked == e->xany.window) && masked_window &&
274 (e->type == MotionNotify)) {
275 last_time = e->xmotion.time;
276 masked_window->motionNotifyEvent(&e->xmotion);
283 // strip the lock key modifiers
284 e->xbutton.state &= ~(NumLockMask | ScrollLockMask | LockMask);
286 last_time = e->xbutton.time;
288 OpenboxWindow *win = (OpenboxWindow *) 0;
289 Basemenu *menu = (Basemenu *) 0;
292 Slit *slit = (Slit *) 0;
295 Toolbar *tbar = (Toolbar *) 0;
297 if ((win = searchWindow(e->xbutton.window))) {
298 win->buttonPressEvent(&e->xbutton);
300 if (e->xbutton.button == 1)
301 win->installColormap(True);
302 } else if ((menu = searchMenu(e->xbutton.window))) {
303 menu->buttonPressEvent(&e->xbutton);
306 } else if ((slit = searchSlit(e->xbutton.window))) {
307 slit->buttonPressEvent(&e->xbutton);
310 } else if ((tbar = searchToolbar(e->xbutton.window))) {
311 tbar->buttonPressEvent(&e->xbutton);
313 LinkedListIterator<BScreen> it(screenList);
314 BScreen *screen = it.current();
315 for (; screen; it++, screen = it.current()) {
316 if (e->xbutton.window == screen->getRootWindow()) {
317 if (e->xbutton.button == 1) {
318 if (! screen->isRootColormapInstalled())
319 screen->getImageControl()->installRootColormap();
321 if (screen->getWorkspacemenu()->isVisible())
322 screen->getWorkspacemenu()->hide();
324 if (screen->getRootmenu()->isVisible())
325 screen->getRootmenu()->hide();
326 } else if (e->xbutton.button == 2) {
327 int mx = e->xbutton.x_root -
328 (screen->getWorkspacemenu()->getWidth() / 2);
329 int my = e->xbutton.y_root -
330 (screen->getWorkspacemenu()->getTitleHeight() / 2);
335 if (mx + screen->getWorkspacemenu()->getWidth() >
337 mx = screen->getWidth() -
338 screen->getWorkspacemenu()->getWidth() -
339 screen->getBorderWidth();
341 if (my + screen->getWorkspacemenu()->getHeight() >
343 my = screen->getHeight() -
344 screen->getWorkspacemenu()->getHeight() -
345 screen->getBorderWidth();
347 screen->getWorkspacemenu()->move(mx, my);
349 if (! screen->getWorkspacemenu()->isVisible()) {
350 screen->getWorkspacemenu()->removeParent();
351 screen->getWorkspacemenu()->show();
353 } else if (e->xbutton.button == 3) {
354 int mx = e->xbutton.x_root -
355 (screen->getRootmenu()->getWidth() / 2);
356 int my = e->xbutton.y_root -
357 (screen->getRootmenu()->getTitleHeight() / 2);
362 if (mx + screen->getRootmenu()->getWidth() > screen->getWidth())
363 mx = screen->getWidth() -
364 screen->getRootmenu()->getWidth() -
365 screen->getBorderWidth();
367 if (my + screen->getRootmenu()->getHeight() > screen->getHeight())
368 my = screen->getHeight() -
369 screen->getRootmenu()->getHeight() -
370 screen->getBorderWidth();
372 screen->getRootmenu()->move(mx, my);
374 if (! screen->getRootmenu()->isVisible()) {
376 screen->getRootmenu()->show();
378 } else if (e->xbutton.button == 4) {
379 if ((screen->getCurrentWorkspaceID()-1)<0)
380 screen->changeWorkspaceID(screen->getCount()-1);
382 screen->changeWorkspaceID(screen->getCurrentWorkspaceID()-1);
383 } else if (e->xbutton.button == 5) {
384 if ((screen->getCurrentWorkspaceID()+1)>screen->getCount()-1)
385 screen->changeWorkspaceID(0);
387 screen->changeWorkspaceID(screen->getCurrentWorkspaceID()+1);
396 case ButtonRelease: {
397 // strip the lock key modifiers
398 e->xbutton.state &= ~(NumLockMask | ScrollLockMask | LockMask);
400 last_time = e->xbutton.time;
402 OpenboxWindow *win = (OpenboxWindow *) 0;
403 Basemenu *menu = (Basemenu *) 0;
404 Toolbar *tbar = (Toolbar *) 0;
406 if ((win = searchWindow(e->xbutton.window)))
407 win->buttonReleaseEvent(&e->xbutton);
408 else if ((menu = searchMenu(e->xbutton.window)))
409 menu->buttonReleaseEvent(&e->xbutton);
410 else if ((tbar = searchToolbar(e->xbutton.window)))
411 tbar->buttonReleaseEvent(&e->xbutton);
416 case ConfigureRequest: {
417 OpenboxWindow *win = (OpenboxWindow *) 0;
420 Slit *slit = (Slit *) 0;
423 if ((win = searchWindow(e->xconfigurerequest.window))) {
424 win->configureRequestEvent(&e->xconfigurerequest);
427 } else if ((slit = searchSlit(e->xconfigurerequest.window))) {
428 slit->configureRequestEvent(&e->xconfigurerequest);
434 if (validateWindow(e->xconfigurerequest.window)) {
437 xwc.x = e->xconfigurerequest.x;
438 xwc.y = e->xconfigurerequest.y;
439 xwc.width = e->xconfigurerequest.width;
440 xwc.height = e->xconfigurerequest.height;
441 xwc.border_width = e->xconfigurerequest.border_width;
442 xwc.sibling = e->xconfigurerequest.above;
443 xwc.stack_mode = e->xconfigurerequest.detail;
445 XConfigureWindow(getXDisplay(), e->xconfigurerequest.window,
446 e->xconfigurerequest.value_mask, &xwc);
458 i18n->getMessage(openboxSet, openboxMapRequest,
459 "Openbox::process_event(): MapRequest for 0x%lx\n"),
460 e->xmaprequest.window);
463 OpenboxWindow *win = searchWindow(e->xmaprequest.window);
466 win = new OpenboxWindow(this, e->xmaprequest.window);
468 if ((win = searchWindow(e->xmaprequest.window)))
469 win->mapRequestEvent(&e->xmaprequest);
475 OpenboxWindow *win = searchWindow(e->xmap.window);
478 win->mapNotifyEvent(&e->xmap);
484 OpenboxWindow *win = (OpenboxWindow *) 0;
487 Slit *slit = (Slit *) 0;
490 if ((win = searchWindow(e->xunmap.window))) {
491 win->unmapNotifyEvent(&e->xunmap);
492 if (focused_window == win)
493 focused_window = (OpenboxWindow *) 0;
495 } else if ((slit = searchSlit(e->xunmap.window))) {
496 slit->removeClient(e->xunmap.window);
504 case DestroyNotify: {
505 OpenboxWindow *win = (OpenboxWindow *) 0;
508 Slit *slit = (Slit *) 0;
511 if ((win = searchWindow(e->xdestroywindow.window))) {
512 win->destroyNotifyEvent(&e->xdestroywindow);
513 if (focused_window == win)
514 focused_window = (OpenboxWindow *) 0;
516 } else if ((slit = searchSlit(e->xdestroywindow.window))) {
517 slit->removeClient(e->xdestroywindow.window, False);
525 // strip the lock key modifiers
526 e->xbutton.state &= ~(NumLockMask | ScrollLockMask | LockMask);
528 last_time = e->xmotion.time;
530 OpenboxWindow *win = (OpenboxWindow *) 0;
531 Basemenu *menu = (Basemenu *) 0;
533 if ((win = searchWindow(e->xmotion.window)))
534 win->motionNotifyEvent(&e->xmotion);
535 else if ((menu = searchMenu(e->xmotion.window)))
536 menu->motionNotifyEvent(&e->xmotion);
541 case PropertyNotify: {
542 last_time = e->xproperty.time;
544 if (e->xproperty.state != PropertyDelete) {
545 OpenboxWindow *win = searchWindow(e->xproperty.window);
548 win->propertyNotifyEvent(e->xproperty.atom);
555 last_time = e->xcrossing.time;
557 BScreen *screen = (BScreen *) 0;
558 OpenboxWindow *win = (OpenboxWindow *) 0;
559 Basemenu *menu = (Basemenu *) 0;
560 Toolbar *tbar = (Toolbar *) 0;
563 Slit *slit = (Slit *) 0;
566 if (e->xcrossing.mode == NotifyGrab) break;
570 sa.w = e->xcrossing.window;
571 sa.enter = sa.leave = False;
572 XCheckIfEvent(getXDisplay(), &dummy, queueScanner, (char *) &sa);
574 if ((e->xcrossing.window == e->xcrossing.root) &&
575 (screen = searchScreen(e->xcrossing.window))) {
576 screen->getImageControl()->installRootColormap();
577 } else if ((win = searchWindow(e->xcrossing.window))) {
578 if (win->getScreen()->isSloppyFocus() &&
579 (! win->isFocused()) && (! no_focus)) {
582 if (((! sa.leave) || sa.inferior) && win->isVisible() &&
583 win->setInputFocus())
584 win->installColormap(True);
588 } else if ((menu = searchMenu(e->xcrossing.window))) {
589 menu->enterNotifyEvent(&e->xcrossing);
590 } else if ((tbar = searchToolbar(e->xcrossing.window))) {
591 tbar->enterNotifyEvent(&e->xcrossing);
593 } else if ((slit = searchSlit(e->xcrossing.window))) {
594 slit->enterNotifyEvent(&e->xcrossing);
601 last_time = e->xcrossing.time;
603 OpenboxWindow *win = (OpenboxWindow *) 0;
604 Basemenu *menu = (Basemenu *) 0;
605 Toolbar *tbar = (Toolbar *) 0;
608 Slit *slit = (Slit *) 0;
611 if ((menu = searchMenu(e->xcrossing.window)))
612 menu->leaveNotifyEvent(&e->xcrossing);
613 else if ((win = searchWindow(e->xcrossing.window)))
614 win->installColormap(False);
615 else if ((tbar = searchToolbar(e->xcrossing.window)))
616 tbar->leaveNotifyEvent(&e->xcrossing);
618 else if ((slit = searchSlit(e->xcrossing.window)))
619 slit->leaveNotifyEvent(&e->xcrossing);
626 OpenboxWindow *win = (OpenboxWindow *) 0;
627 Basemenu *menu = (Basemenu *) 0;
628 Toolbar *tbar = (Toolbar *) 0;
630 if ((win = searchWindow(e->xexpose.window)))
631 win->exposeEvent(&e->xexpose);
632 else if ((menu = searchMenu(e->xexpose.window)))
633 menu->exposeEvent(&e->xexpose);
634 else if ((tbar = searchToolbar(e->xexpose.window)))
635 tbar->exposeEvent(&e->xexpose);
641 Toolbar *tbar = searchToolbar(e->xkey.window);
643 if (tbar && tbar->isEditing())
644 tbar->keyPressEvent(&e->xkey);
649 case ColormapNotify: {
650 BScreen *screen = searchScreen(e->xcolormap.window);
653 screen->setRootColormapInstalled((e->xcolormap.state ==
654 ColormapInstalled) ? True : False);
660 if (e->xfocus.mode == NotifyUngrab || e->xfocus.detail == NotifyPointer)
663 OpenboxWindow *win = searchWindow(e->xfocus.window);
664 if (win && ! win->isFocused())
665 setFocusedWindow(win);
673 case ClientMessage: {
674 if (e->xclient.format == 32) {
675 if (e->xclient.message_type == getWMChangeStateAtom()) {
676 OpenboxWindow *win = searchWindow(e->xclient.window);
677 if (! win || ! win->validateClient()) return;
679 if (e->xclient.data.l[0] == IconicState)
681 if (e->xclient.data.l[0] == NormalState)
683 } else if (e->xclient.message_type == getOpenboxChangeWorkspaceAtom()) {
684 BScreen *screen = searchScreen(e->xclient.window);
686 if (screen && e->xclient.data.l[0] >= 0 &&
687 e->xclient.data.l[0] < screen->getCount())
688 screen->changeWorkspaceID(e->xclient.data.l[0]);
689 } else if (e->xclient.message_type == getOpenboxChangeWindowFocusAtom()) {
690 OpenboxWindow *win = searchWindow(e->xclient.window);
692 if (win && win->isVisible() && win->setInputFocus())
693 win->installColormap(True);
694 } else if (e->xclient.message_type == getOpenboxCycleWindowFocusAtom()) {
695 BScreen *screen = searchScreen(e->xclient.window);
698 if (! e->xclient.data.l[0])
703 } else if (e->xclient.message_type == getOpenboxChangeAttributesAtom()) {
704 OpenboxWindow *win = searchWindow(e->xclient.window);
706 if (win && win->validateClient()) {
708 net.flags = e->xclient.data.l[0];
709 net.attrib = e->xclient.data.l[1];
710 net.workspace = e->xclient.data.l[2];
711 net.stack = e->xclient.data.l[3];
712 net.decoration = e->xclient.data.l[4];
714 win->changeOpenboxHints(&net);
725 if (e->type == getShapeEventBase()) {
726 XShapeEvent *shape_event = (XShapeEvent *) e;
727 OpenboxWindow *win = (OpenboxWindow *) 0;
729 if ((win = searchWindow(e->xany.window)) ||
730 (shape_event->kind != ShapeBounding))
731 win->shapeEvent(shape_event);
740 Bool Openbox::handleSignal(int sig) {
769 BScreen *Openbox::searchScreen(Window window) {
770 LinkedListIterator<BScreen> it(screenList);
772 for (BScreen *curr = it.current(); curr; it++, curr = it.current()) {
773 if (curr->getRootWindow() == window) {
778 return (BScreen *) 0;
782 OpenboxWindow *Openbox::searchWindow(Window window) {
783 LinkedListIterator<WindowSearch> it(windowSearchList);
785 for (WindowSearch *tmp = it.current(); tmp; it++, tmp = it.current()) {
786 if (tmp->getWindow() == window) {
787 return tmp->getData();
791 return (OpenboxWindow *) 0;
795 OpenboxWindow *Openbox::searchGroup(Window window, OpenboxWindow *win) {
796 OpenboxWindow *w = (OpenboxWindow *) 0;
797 LinkedListIterator<WindowSearch> it(groupSearchList);
799 for (WindowSearch *tmp = it.current(); tmp; it++, tmp = it.current()) {
800 if (tmp->getWindow() == window) {
802 if (w->getClientWindow() != win->getClientWindow())
807 return (OpenboxWindow *) 0;
811 Basemenu *Openbox::searchMenu(Window window) {
812 LinkedListIterator<MenuSearch> it(menuSearchList);
814 for (MenuSearch *tmp = it.current(); tmp; it++, tmp = it.current()) {
815 if (tmp->getWindow() == window)
816 return tmp->getData();
819 return (Basemenu *) 0;
823 Toolbar *Openbox::searchToolbar(Window window) {
824 LinkedListIterator<ToolbarSearch> it(toolbarSearchList);
826 for (ToolbarSearch *tmp = it.current(); tmp; it++, tmp = it.current()) {
827 if (tmp->getWindow() == window)
828 return tmp->getData();
831 return (Toolbar *) 0;
836 Slit *Openbox::searchSlit(Window window) {
837 LinkedListIterator<SlitSearch> it(slitSearchList);
839 for (SlitSearch *tmp = it.current(); tmp; it++, tmp = it.current()) {
840 if (tmp->getWindow() == window)
841 return tmp->getData();
849 void Openbox::saveWindowSearch(Window window, OpenboxWindow *data) {
850 windowSearchList->insert(new WindowSearch(window, data));
854 void Openbox::saveGroupSearch(Window window, OpenboxWindow *data) {
855 groupSearchList->insert(new WindowSearch(window, data));
859 void Openbox::saveMenuSearch(Window window, Basemenu *data) {
860 menuSearchList->insert(new MenuSearch(window, data));
864 void Openbox::saveToolbarSearch(Window window, Toolbar *data) {
865 toolbarSearchList->insert(new ToolbarSearch(window, data));
870 void Openbox::saveSlitSearch(Window window, Slit *data) {
871 slitSearchList->insert(new SlitSearch(window, data));
876 void Openbox::removeWindowSearch(Window window) {
877 LinkedListIterator<WindowSearch> it(windowSearchList);
878 for (WindowSearch *tmp = it.current(); tmp; it++, tmp = it.current()) {
879 if (tmp->getWindow() == window) {
880 windowSearchList->remove(tmp);
888 void Openbox::removeGroupSearch(Window window) {
889 LinkedListIterator<WindowSearch> it(groupSearchList);
890 for (WindowSearch *tmp = it.current(); tmp; it++, tmp = it.current()) {
891 if (tmp->getWindow() == window) {
892 groupSearchList->remove(tmp);
900 void Openbox::removeMenuSearch(Window window) {
901 LinkedListIterator<MenuSearch> it(menuSearchList);
902 for (MenuSearch *tmp = it.current(); tmp; it++, tmp = it.current()) {
903 if (tmp->getWindow() == window) {
904 menuSearchList->remove(tmp);
912 void Openbox::removeToolbarSearch(Window window) {
913 LinkedListIterator<ToolbarSearch> it(toolbarSearchList);
914 for (ToolbarSearch *tmp = it.current(); tmp; it++, tmp = it.current()) {
915 if (tmp->getWindow() == window) {
916 toolbarSearchList->remove(tmp);
925 void Openbox::removeSlitSearch(Window window) {
926 LinkedListIterator<SlitSearch> it(slitSearchList);
927 for (SlitSearch *tmp = it.current(); tmp; it++, tmp = it.current()) {
928 if (tmp->getWindow() == window) {
929 slitSearchList->remove(tmp);
938 void Openbox::restart(const char *prog) {
942 execlp(prog, prog, NULL);
946 // fall back in case the above execlp doesn't work
947 execvp(argv[0], argv);
948 execvp(basename(argv[0]), argv);
952 void Openbox::shutdown(void) {
953 BaseDisplay::shutdown();
955 XSetInputFocus(getXDisplay(), PointerRoot, None, CurrentTime);
957 LinkedListIterator<BScreen> it(screenList);
958 for (BScreen *s = it.current(); s; it++, s = it.current())
961 XSync(getXDisplay(), False);
967 void Openbox::save_rc(void) {
968 XrmDatabase new_openboxrc = (XrmDatabase) 0;
969 char rc_string[1024];
973 sprintf(rc_string, "session.menuFile: %s", resource.menu_file);
974 XrmPutLineResource(&new_openboxrc, rc_string);
976 sprintf(rc_string, "session.colorsPerChannel: %d",
977 resource.colors_per_channel);
978 XrmPutLineResource(&new_openboxrc, rc_string);
980 sprintf(rc_string, "session.titlebarLayout: %s",
981 resource.titlebar_layout);
982 XrmPutLineResource(&new_openboxrc, rc_string);
984 sprintf(rc_string, "session.doubleClickInterval: %lu",
985 resource.double_click_interval);
986 XrmPutLineResource(&new_openboxrc, rc_string);
988 sprintf(rc_string, "session.autoRaiseDelay: %lu",
989 ((resource.auto_raise_delay.tv_sec * 1000) +
990 (resource.auto_raise_delay.tv_usec / 1000)));
991 XrmPutLineResource(&new_openboxrc, rc_string);
993 sprintf(rc_string, "session.cacheLife: %lu", resource.cache_life / 60000);
994 XrmPutLineResource(&new_openboxrc, rc_string);
996 sprintf(rc_string, "session.cacheMax: %lu", resource.cache_max);
997 XrmPutLineResource(&new_openboxrc, rc_string);
999 LinkedListIterator<BScreen> it(screenList);
1000 for (BScreen *screen = it.current(); screen; it++, screen = it.current()) {
1001 int screen_number = screen->getScreenNumber();
1004 char *slit_placement = (char *) 0;
1006 switch (screen->getSlitPlacement()) {
1007 case Slit::TopLeft: slit_placement = "TopLeft"; break;
1008 case Slit::CenterLeft: slit_placement = "CenterLeft"; break;
1009 case Slit::BottomLeft: slit_placement = "BottomLeft"; break;
1010 case Slit::TopCenter: slit_placement = "TopCenter"; break;
1011 case Slit::BottomCenter: slit_placement = "BottomCenter"; break;
1012 case Slit::TopRight: slit_placement = "TopRight"; break;
1013 case Slit::BottomRight: slit_placement = "BottomRight"; break;
1014 case Slit::CenterRight: default: slit_placement = "CenterRight"; break;
1017 sprintf(rc_string, "session.screen%d.slit.placement: %s", screen_number,
1019 XrmPutLineResource(&new_openboxrc, rc_string);
1021 sprintf(rc_string, "session.screen%d.slit.direction: %s", screen_number,
1022 ((screen->getSlitDirection() == Slit::Horizontal) ? "Horizontal" :
1024 XrmPutLineResource(&new_openboxrc, rc_string);
1026 const char *rootcmd;
1027 if ((rootcmd = screen->getRootCommand()) != NULL) {
1028 sprintf(rc_string, "session.screen%d.rootCommand: %s", screen_number,
1030 XrmPutLineResource(&new_openboxrc, rc_string);
1033 sprintf(rc_string, "session.screen%d.slit.onTop: %s", screen_number,
1034 ((screen->getSlit()->isOnTop()) ? "True" : "False"));
1035 XrmPutLineResource(&new_openboxrc, rc_string);
1037 sprintf(rc_string, "session.screen%d.slit.autoHide: %s", screen_number,
1038 ((screen->getSlit()->doAutoHide()) ? "True" : "False"));
1039 XrmPutLineResource(&new_openboxrc, rc_string);
1042 sprintf(rc_string, "session.opaqueMove: %s",
1043 ((screen->doOpaqueMove()) ? "True" : "False"));
1044 XrmPutLineResource(&new_openboxrc, rc_string);
1046 sprintf(rc_string, "session.imageDither: %s",
1047 ((screen->getImageControl()->doDither()) ? "True" : "False"));
1048 XrmPutLineResource(&new_openboxrc, rc_string);
1050 sprintf(rc_string, "session.screen%d.fullMaximization: %s", screen_number,
1051 ((screen->doFullMax()) ? "True" : "False"));
1052 XrmPutLineResource(&new_openboxrc, rc_string);
1054 sprintf(rc_string, "session.screen%d.focusNewWindows: %s", screen_number,
1055 ((screen->doFocusNew()) ? "True" : "False"));
1056 XrmPutLineResource(&new_openboxrc, rc_string);
1058 sprintf(rc_string, "session.screen%d.focusLastWindow: %s", screen_number,
1059 ((screen->doFocusLast()) ? "True" : "False"));
1060 XrmPutLineResource(&new_openboxrc, rc_string);
1062 sprintf(rc_string, "session.screen%d.rowPlacementDirection: %s",
1064 ((screen->getRowPlacementDirection() == BScreen::LeftRight) ?
1065 "LeftToRight" : "RightToLeft"));
1066 XrmPutLineResource(&new_openboxrc, rc_string);
1068 sprintf(rc_string, "session.screen%d.colPlacementDirection: %s",
1070 ((screen->getColPlacementDirection() == BScreen::TopBottom) ?
1071 "TopToBottom" : "BottomToTop"));
1072 XrmPutLineResource(&new_openboxrc, rc_string);
1074 char *placement = (char *) 0;
1075 switch (screen->getPlacementPolicy()) {
1076 case BScreen::CascadePlacement:
1077 placement = "CascadePlacement";
1080 case BScreen::ColSmartPlacement:
1081 placement = "ColSmartPlacement";
1084 case BScreen::RowSmartPlacement:
1086 placement = "RowSmartPlacement";
1089 sprintf(rc_string, "session.screen%d.windowPlacement: %s", screen_number,
1091 XrmPutLineResource(&new_openboxrc, rc_string);
1093 sprintf(rc_string, "session.screen%d.windowZones: %i", screen_number,
1094 screen->getWindowZones());
1095 XrmPutLineResource(&new_openboxrc, rc_string);
1097 sprintf(rc_string, "session.screen%d.focusModel: %s", screen_number,
1098 ((screen->isSloppyFocus()) ?
1099 ((screen->doAutoRaise()) ? "AutoRaiseSloppyFocus" :
1102 XrmPutLineResource(&new_openboxrc, rc_string);
1104 sprintf(rc_string, "session.screen%d.workspaces: %d", screen_number,
1105 screen->getCount());
1106 XrmPutLineResource(&new_openboxrc, rc_string);
1108 sprintf(rc_string, "session.screen%d.toolbar.onTop: %s", screen_number,
1109 ((screen->getToolbar()->isOnTop()) ? "True" : "False"));
1110 XrmPutLineResource(&new_openboxrc, rc_string);
1112 sprintf(rc_string, "session.screen%d.toolbar.autoHide: %s", screen_number,
1113 ((screen->getToolbar()->doAutoHide()) ? "True" : "False"));
1114 XrmPutLineResource(&new_openboxrc, rc_string);
1116 char *toolbar_placement = (char *) 0;
1118 switch (screen->getToolbarPlacement()) {
1119 case Toolbar::TopLeft: toolbar_placement = "TopLeft"; break;
1120 case Toolbar::BottomLeft: toolbar_placement = "BottomLeft"; break;
1121 case Toolbar::TopCenter: toolbar_placement = "TopCenter"; break;
1122 case Toolbar::TopRight: toolbar_placement = "TopRight"; break;
1123 case Toolbar::BottomRight: toolbar_placement = "BottomRight"; break;
1124 case Toolbar::BottomCenter: default:
1125 toolbar_placement = "BottomCenter"; break;
1128 sprintf(rc_string, "session.screen%d.toolbar.placement: %s", screen_number,
1130 XrmPutLineResource(&new_openboxrc, rc_string);
1134 // these are static, but may not be saved in the users .openbox/rc,
1135 // writing these resources will allow the user to edit them at a later
1136 // time... but loading the defaults before saving allows us to rewrite the
1139 #ifdef HAVE_STRFTIME
1140 sprintf(rc_string, "session.screen%d.strftimeFormat: %s", screen_number,
1141 screen->getStrftimeFormat());
1142 XrmPutLineResource(&new_openboxrc, rc_string);
1143 #else // !HAVE_STRFTIME
1144 sprintf(rc_string, "session.screen%d.dateFormat: %s", screen_number,
1145 ((screen->getDateFormat() == B_EuropeanDate) ?
1146 "European" : "American"));
1147 XrmPutLineResource(&new_openboxrc, rc_string);
1149 sprintf(rc_string, "session.screen%d.clockFormat: %d", screen_number,
1150 ((screen->isClock24Hour()) ? 24 : 12));
1151 XrmPutLineResource(&new_openboxrc, rc_string);
1152 #endif // HAVE_STRFTIME
1154 sprintf(rc_string, "session.screen%d.edgeSnapThreshold: %d", screen_number,
1155 screen->getEdgeSnapThreshold());
1156 XrmPutLineResource(&new_openboxrc, rc_string);
1158 sprintf(rc_string, "session.screen%d.toolbar.widthPercent: %d",
1159 screen_number, screen->getToolbarWidthPercent());
1160 XrmPutLineResource(&new_openboxrc, rc_string);
1162 // write out the users workspace names
1164 for (i = 0; i < screen->getCount(); i++)
1165 len += strlen((screen->getWorkspace(i)->getName()) ?
1166 screen->getWorkspace(i)->getName() : "Null") + 1;
1168 char *resource_string = new char[len + 1024],
1169 *save_string = new char[len], *save_string_pos = save_string,
1172 for (i = 0; i < screen->getCount(); i++) {
1173 len = strlen((screen->getWorkspace(i)->getName()) ?
1174 screen->getWorkspace(i)->getName() : "Null") + 1;
1176 (char *) ((screen->getWorkspace(i)->getName()) ?
1177 screen->getWorkspace(i)->getName() : "Null");
1179 while (--len) *(save_string_pos++) = *(name_string_pos++);
1180 *(save_string_pos++) = ',';
1184 *(--save_string_pos) = '\0';
1186 sprintf(resource_string, "session.screen%d.workspaceNames: %s",
1187 screen_number, save_string);
1188 XrmPutLineResource(&new_openboxrc, resource_string);
1190 delete [] resource_string;
1191 delete [] save_string;
1194 XrmDatabase old_openboxrc = XrmGetFileDatabase(rc_file);
1196 XrmMergeDatabases(new_openboxrc, &old_openboxrc);
1197 XrmPutFileDatabase(old_openboxrc, rc_file);
1198 XrmDestroyDatabase(old_openboxrc);
1202 void Openbox::load_rc(void) {
1203 XrmDatabase database = (XrmDatabase) 0;
1205 database = XrmGetFileDatabase(rc_file);
1210 if (resource.menu_file)
1211 delete [] resource.menu_file;
1213 if (XrmGetResource(database, "session.menuFile", "Session.MenuFile",
1214 &value_type, &value))
1215 resource.menu_file = bstrdup(value.addr);
1217 resource.menu_file = bstrdup(DEFAULTMENU);
1219 if (XrmGetResource(database, "session.colorsPerChannel",
1220 "Session.ColorsPerChannel", &value_type, &value)) {
1221 if (sscanf(value.addr, "%d", &resource.colors_per_channel) != 1) {
1222 resource.colors_per_channel = 4;
1224 if (resource.colors_per_channel < 2) resource.colors_per_channel = 2;
1225 if (resource.colors_per_channel > 6) resource.colors_per_channel = 6;
1228 resource.colors_per_channel = 4;
1231 if (resource.style_file)
1232 delete [] resource.style_file;
1234 if (XrmGetResource(database, "session.styleFile", "Session.StyleFile",
1235 &value_type, &value))
1236 resource.style_file = bstrdup(value.addr);
1238 resource.style_file = bstrdup(DEFAULTSTYLE);
1240 if (XrmGetResource(database, "session.titlebarLayout",
1241 "Session.TitlebarLayout", &value_type, &value)) {
1242 resource.titlebar_layout = bstrdup(value.addr == NULL ? "ILMC" :
1245 resource.titlebar_layout = bstrdup("ILMC");
1248 if (XrmGetResource(database, "session.doubleClickInterval",
1249 "Session.DoubleClickInterval", &value_type, &value)) {
1250 if (sscanf(value.addr, "%lu", &resource.double_click_interval) != 1)
1251 resource.double_click_interval = 250;
1253 resource.double_click_interval = 250;
1256 if (XrmGetResource(database, "session.autoRaiseDelay",
1257 "Session.AutoRaiseDelay", &value_type, &value)) {
1258 if (sscanf(value.addr, "%ld", &resource.auto_raise_delay.tv_usec) != 1)
1259 resource.auto_raise_delay.tv_usec = 400;
1261 resource.auto_raise_delay.tv_usec = 400;
1264 resource.auto_raise_delay.tv_sec = resource.auto_raise_delay.tv_usec / 1000;
1265 resource.auto_raise_delay.tv_usec -=
1266 (resource.auto_raise_delay.tv_sec * 1000);
1267 resource.auto_raise_delay.tv_usec *= 1000;
1269 if (XrmGetResource(database, "session.cacheLife", "Session.CacheLife",
1270 &value_type, &value)) {
1271 if (sscanf(value.addr, "%lu", &resource.cache_life) != 1)
1272 resource.cache_life = 5l;
1274 resource.cache_life = 5l;
1277 resource.cache_life *= 60000;
1279 if (XrmGetResource(database, "session.cacheMax", "Session.CacheMax",
1280 &value_type, &value)) {
1281 if (sscanf(value.addr, "%lu", &resource.cache_max) != 1)
1282 resource.cache_max = 200;
1284 resource.cache_max = 200;
1289 void Openbox::load_rc(BScreen *screen) {
1290 XrmDatabase database = (XrmDatabase) 0;
1292 database = XrmGetFileDatabase(rc_file);
1295 char *value_type, name_lookup[1024], class_lookup[1024];
1296 int screen_number = screen->getScreenNumber();
1298 sprintf(name_lookup, "session.screen%d.fullMaximization", screen_number);
1299 sprintf(class_lookup, "Session.Screen%d.FullMaximization", screen_number);
1300 if (XrmGetResource(database, name_lookup, class_lookup, &value_type,
1302 if (! strncasecmp(value.addr, "true", value.size))
1303 screen->saveFullMax(True);
1305 screen->saveFullMax(False);
1307 screen->saveFullMax(False);
1309 sprintf(name_lookup, "session.screen%d.focusNewWindows", screen_number);
1310 sprintf(class_lookup, "Session.Screen%d.FocusNewWindows", screen_number);
1311 if (XrmGetResource(database, name_lookup, class_lookup, &value_type,
1313 if (! strncasecmp(value.addr, "true", value.size))
1314 screen->saveFocusNew(True);
1316 screen->saveFocusNew(False);
1318 screen->saveFocusNew(False);
1320 sprintf(name_lookup, "session.screen%d.focusLastWindow", screen_number);
1321 sprintf(class_lookup, "Session.Screen%d.focusLastWindow", screen_number);
1322 if (XrmGetResource(database, name_lookup, class_lookup, &value_type,
1324 if (! strncasecmp(value.addr, "true", value.size))
1325 screen->saveFocusLast(True);
1327 screen->saveFocusLast(False);
1329 screen->saveFocusLast(False);
1331 sprintf(name_lookup, "session.screen%d.rowPlacementDirection",
1333 sprintf(class_lookup, "Session.Screen%d.RowPlacementDirection",
1335 if (XrmGetResource(database, name_lookup, class_lookup, &value_type,
1337 if (! strncasecmp(value.addr, "righttoleft", value.size))
1338 screen->saveRowPlacementDirection(BScreen::RightLeft);
1340 screen->saveRowPlacementDirection(BScreen::LeftRight);
1342 screen->saveRowPlacementDirection(BScreen::LeftRight);
1344 sprintf(name_lookup, "session.screen%d.colPlacementDirection",
1346 sprintf(class_lookup, "Session.Screen%d.ColPlacementDirection",
1348 if (XrmGetResource(database, name_lookup, class_lookup, &value_type,
1350 if (! strncasecmp(value.addr, "bottomtotop", value.size))
1351 screen->saveColPlacementDirection(BScreen::BottomTop);
1353 screen->saveColPlacementDirection(BScreen::TopBottom);
1355 screen->saveColPlacementDirection(BScreen::TopBottom);
1357 sprintf(name_lookup, "session.screen%d.workspaces", screen_number);
1358 sprintf(class_lookup, "Session.Screen%d.Workspaces", screen_number);
1359 if (XrmGetResource(database, name_lookup, class_lookup, &value_type,
1362 if (sscanf(value.addr, "%d", &i) != 1) i = 1;
1363 screen->saveWorkspaces(i);
1365 screen->saveWorkspaces(1);
1367 sprintf(name_lookup, "session.screen%d.toolbar.widthPercent",
1369 sprintf(class_lookup, "Session.Screen%d.Toolbar.WidthPercent",
1371 if (XrmGetResource(database, name_lookup, class_lookup, &value_type,
1374 if (sscanf(value.addr, "%d", &i) != 1) i = 66;
1376 if (i <= 0 || i > 100)
1379 screen->saveToolbarWidthPercent(i);
1381 screen->saveToolbarWidthPercent(66);
1383 sprintf(name_lookup, "session.screen%d.toolbar.placement", screen_number);
1384 sprintf(class_lookup, "Session.Screen%d.Toolbar.Placement", screen_number);
1385 if (XrmGetResource(database, name_lookup, class_lookup, &value_type,
1387 if (! strncasecmp(value.addr, "TopLeft", value.size))
1388 screen->saveToolbarPlacement(Toolbar::TopLeft);
1389 else if (! strncasecmp(value.addr, "BottomLeft", value.size))
1390 screen->saveToolbarPlacement(Toolbar::BottomLeft);
1391 else if (! strncasecmp(value.addr, "TopCenter", value.size))
1392 screen->saveToolbarPlacement(Toolbar::TopCenter);
1393 else if (! strncasecmp(value.addr, "TopRight", value.size))
1394 screen->saveToolbarPlacement(Toolbar::TopRight);
1395 else if (! strncasecmp(value.addr, "BottomRight", value.size))
1396 screen->saveToolbarPlacement(Toolbar::BottomRight);
1398 screen->saveToolbarPlacement(Toolbar::BottomCenter);
1400 screen->saveToolbarPlacement(Toolbar::BottomCenter);
1402 screen->removeWorkspaceNames();
1404 sprintf(name_lookup, "session.screen%d.workspaceNames", screen_number);
1405 sprintf(class_lookup, "Session.Screen%d.WorkspaceNames", screen_number);
1406 if (XrmGetResource(database, name_lookup, class_lookup, &value_type,
1408 char *search = bstrdup(value.addr);
1410 for (int i = 0; i < screen->getNumberOfWorkspaces(); i++) {
1413 if (! i) nn = strtok(search, ",");
1414 else nn = strtok(NULL, ",");
1416 if (nn) screen->addWorkspaceName(nn);
1423 sprintf(name_lookup, "session.screen%d.toolbar.onTop", screen_number);
1424 sprintf(class_lookup, "Session.Screen%d.Toolbar.OnTop", screen_number);
1425 if (XrmGetResource(database, name_lookup, class_lookup, &value_type,
1427 if (! strncasecmp(value.addr, "true", value.size))
1428 screen->saveToolbarOnTop(True);
1430 screen->saveToolbarOnTop(False);
1432 screen->saveToolbarOnTop(False);
1434 sprintf(name_lookup, "session.screen%d.toolbar.autoHide", screen_number);
1435 sprintf(class_lookup, "Session.Screen%d.Toolbar.autoHide", screen_number);
1436 if (XrmGetResource(database, name_lookup, class_lookup, &value_type,
1438 if (! strncasecmp(value.addr, "true", value.size))
1439 screen->saveToolbarAutoHide(True);
1441 screen->saveToolbarAutoHide(False);
1443 screen->saveToolbarAutoHide(False);
1445 sprintf(name_lookup, "session.screen%d.focusModel", screen_number);
1446 sprintf(class_lookup, "Session.Screen%d.FocusModel", screen_number);
1447 if (XrmGetResource(database, name_lookup, class_lookup, &value_type,
1449 if (! strncasecmp(value.addr, "clicktofocus", value.size)) {
1450 screen->saveAutoRaise(False);
1451 screen->saveSloppyFocus(False);
1452 } else if (! strncasecmp(value.addr, "autoraisesloppyfocus", value.size)) {
1453 screen->saveSloppyFocus(True);
1454 screen->saveAutoRaise(True);
1456 screen->saveSloppyFocus(True);
1457 screen->saveAutoRaise(False);
1460 screen->saveSloppyFocus(True);
1461 screen->saveAutoRaise(False);
1464 sprintf(name_lookup, "session.screen%d.windowZones", screen_number);
1465 sprintf(class_lookup, "Session.Screen%d.WindowZones", screen_number);
1466 if (XrmGetResource(database, name_lookup, class_lookup, &value_type,
1468 int i = atoi(value.addr);
1469 screen->saveWindowZones((i == 1 || i == 2 || i == 4) ? i : 1);
1471 screen->saveWindowZones(1);
1474 sprintf(name_lookup, "session.screen%d.windowPlacement", screen_number);
1475 sprintf(class_lookup, "Session.Screen%d.WindowPlacement", screen_number);
1476 if (XrmGetResource(database, name_lookup, class_lookup, &value_type,
1478 if (! strncasecmp(value.addr, "RowSmartPlacement", value.size))
1479 screen->savePlacementPolicy(BScreen::RowSmartPlacement);
1480 else if (! strncasecmp(value.addr, "ColSmartPlacement", value.size))
1481 screen->savePlacementPolicy(BScreen::ColSmartPlacement);
1483 screen->savePlacementPolicy(BScreen::CascadePlacement);
1485 screen->savePlacementPolicy(BScreen::RowSmartPlacement);
1488 sprintf(name_lookup, "session.screen%d.slit.placement", screen_number);
1489 sprintf(class_lookup, "Session.Screen%d.Slit.Placement", screen_number);
1490 if (XrmGetResource(database, name_lookup, class_lookup, &value_type,
1492 if (! strncasecmp(value.addr, "TopLeft", value.size))
1493 screen->saveSlitPlacement(Slit::TopLeft);
1494 else if (! strncasecmp(value.addr, "CenterLeft", value.size))
1495 screen->saveSlitPlacement(Slit::CenterLeft);
1496 else if (! strncasecmp(value.addr, "BottomLeft", value.size))
1497 screen->saveSlitPlacement(Slit::BottomLeft);
1498 else if (! strncasecmp(value.addr, "TopCenter", value.size))
1499 screen->saveSlitPlacement(Slit::TopCenter);
1500 else if (! strncasecmp(value.addr, "BottomCenter", value.size))
1501 screen->saveSlitPlacement(Slit::BottomCenter);
1502 else if (! strncasecmp(value.addr, "TopRight", value.size))
1503 screen->saveSlitPlacement(Slit::TopRight);
1504 else if (! strncasecmp(value.addr, "BottomRight", value.size))
1505 screen->saveSlitPlacement(Slit::BottomRight);
1507 screen->saveSlitPlacement(Slit::CenterRight);
1509 screen->saveSlitPlacement(Slit::CenterRight);
1511 sprintf(name_lookup, "session.screen%d.slit.direction", screen_number);
1512 sprintf(class_lookup, "Session.Screen%d.Slit.Direction", screen_number);
1513 if (XrmGetResource(database, name_lookup, class_lookup, &value_type,
1515 if (! strncasecmp(value.addr, "Horizontal", value.size))
1516 screen->saveSlitDirection(Slit::Horizontal);
1518 screen->saveSlitDirection(Slit::Vertical);
1520 screen->saveSlitDirection(Slit::Vertical);
1522 sprintf(name_lookup, "session.screen%d.slit.onTop", screen_number);
1523 sprintf(class_lookup, "Session.Screen%d.Slit.OnTop", screen_number);
1524 if (XrmGetResource(database, name_lookup, class_lookup, &value_type,
1526 if (! strncasecmp(value.addr, "True", value.size))
1527 screen->saveSlitOnTop(True);
1529 screen->saveSlitOnTop(False);
1531 screen->saveSlitOnTop(False);
1533 sprintf(name_lookup, "session.screen%d.slit.autoHide", screen_number);
1534 sprintf(class_lookup, "Session.Screen%d.Slit.AutoHide", screen_number);
1535 if (XrmGetResource(database, name_lookup, class_lookup, &value_type,
1537 if (! strncasecmp(value.addr, "True", value.size))
1538 screen->saveSlitAutoHide(True);
1540 screen->saveSlitAutoHide(False);
1542 screen->saveSlitAutoHide(False);
1546 #ifdef HAVE_STRFTIME
1547 sprintf(name_lookup, "session.screen%d.strftimeFormat", screen_number);
1548 sprintf(class_lookup, "Session.Screen%d.StrftimeFormat", screen_number);
1549 if (XrmGetResource(database, name_lookup, class_lookup, &value_type,
1551 screen->saveStrftimeFormat(value.addr);
1553 screen->saveStrftimeFormat("%I:%M %p");
1555 #else // HAVE_STRFTIME
1556 sprintf(name_lookup, "session.screen%d.dateFormat", screen_number);
1557 sprintf(class_lookup, "Session.Screen%d.DateFormat", screen_number);
1558 if (XrmGetResource(database, name_lookup, class_lookup, &value_type,
1560 if (strncasecmp(value.addr, "european", value.size))
1561 screen->saveDateFormat(B_AmericanDate);
1563 screen->saveDateFormat(B_EuropeanDate);
1565 screen->saveDateFormat(B_AmericanDate);
1567 sprintf(name_lookup, "session.screen%d.clockFormat", screen_number);
1568 sprintf(class_lookup, "Session.Screen%d.ClockFormat", screen_number);
1569 if (XrmGetResource(database, name_lookup, class_lookup, &value_type,
1572 if (sscanf(value.addr, "%d", &clock) != 1) screen->saveClock24Hour(False);
1573 else if (clock == 24) screen->saveClock24Hour(True);
1574 else screen->saveClock24Hour(False);
1576 screen->saveClock24Hour(False);
1578 #endif // HAVE_STRFTIME
1580 sprintf(name_lookup, "session.screen%d.edgeSnapThreshold", screen_number);
1581 sprintf(class_lookup, "Session.Screen%d.EdgeSnapThreshold", screen_number);
1582 if (XrmGetResource(database, name_lookup, class_lookup, &value_type,
1585 if (sscanf(value.addr, "%d", &threshold) != 1)
1586 screen->saveEdgeSnapThreshold(0);
1588 screen->saveEdgeSnapThreshold(threshold);
1590 screen->saveEdgeSnapThreshold(0);
1592 sprintf(name_lookup, "session.screen%d.imageDither", screen_number);
1593 sprintf(class_lookup, "Session.Screen%d.ImageDither", screen_number);
1594 if (XrmGetResource(database, "session.imageDither", "Session.ImageDither",
1595 &value_type, &value)) {
1596 if (! strncasecmp("true", value.addr, value.size))
1597 screen->saveImageDither(True);
1599 screen->saveImageDither(False);
1601 screen->saveImageDither(True);
1604 sprintf(name_lookup, "session.screen%d.rootCommand", screen_number);
1605 sprintf(class_lookup, "Session.Screen%d.RootCommand", screen_number);
1606 if (XrmGetResource(database, name_lookup, class_lookup, &value_type,
1608 screen->saveRootCommand(value.addr);
1610 screen->saveRootCommand(NULL);
1612 if (XrmGetResource(database, "session.opaqueMove", "Session.OpaqueMove",
1613 &value_type, &value)) {
1614 if (! strncasecmp("true", value.addr, value.size))
1615 screen->saveOpaqueMove(True);
1617 screen->saveOpaqueMove(False);
1619 screen->saveOpaqueMove(False);
1621 XrmDestroyDatabase(database);
1625 void Openbox::reload_rc(void) {
1631 void Openbox::reconfigure(void) {
1632 reconfigure_wait = True;
1634 if (! timer->isTiming()) timer->start();
1638 void Openbox::real_reconfigure(void) {
1641 XrmDatabase new_openboxrc = (XrmDatabase) 0;
1642 char style[MAXPATHLEN + 64];
1644 sprintf(style, "session.styleFile: %s", resource.style_file);
1645 XrmPutLineResource(&new_openboxrc, style);
1647 XrmDatabase old_openboxrc = XrmGetFileDatabase(rc_file);
1649 XrmMergeDatabases(new_openboxrc, &old_openboxrc);
1650 XrmPutFileDatabase(old_openboxrc, rc_file);
1651 if (old_openboxrc) XrmDestroyDatabase(old_openboxrc);
1653 for (int i = 0, n = menuTimestamps->count(); i < n; i++) {
1654 MenuTimestamp *ts = menuTimestamps->remove(0);
1658 delete [] ts->filename;
1664 LinkedListIterator<BScreen> it(screenList);
1665 for (BScreen *screen = it.current(); screen; it++, screen = it.current()) {
1666 screen->reconfigure();
1673 void Openbox::checkMenu(void) {
1674 Bool reread = False;
1675 LinkedListIterator<MenuTimestamp> it(menuTimestamps);
1676 for (MenuTimestamp *tmp = it.current(); tmp && (! reread);
1677 it++, tmp = it.current()) {
1680 if (! stat(tmp->filename, &buf)) {
1681 if (tmp->timestamp != buf.st_ctime)
1688 if (reread) rereadMenu();
1692 void Openbox::rereadMenu(void) {
1693 reread_menu_wait = True;
1695 if (! timer->isTiming()) timer->start();
1699 void Openbox::real_rereadMenu(void) {
1700 for (int i = 0, n = menuTimestamps->count(); i < n; i++) {
1701 MenuTimestamp *ts = menuTimestamps->remove(0);
1705 delete [] ts->filename;
1711 LinkedListIterator<BScreen> it(screenList);
1712 for (BScreen *screen = it.current(); screen; it++, screen = it.current())
1713 screen->rereadMenu();
1717 void Openbox::saveStyleFilename(const char *filename) {
1718 if (resource.style_file)
1719 delete [] resource.style_file;
1721 resource.style_file = bstrdup(filename);
1725 void Openbox::saveMenuFilename(const char *filename) {
1728 LinkedListIterator<MenuTimestamp> it(menuTimestamps);
1729 for (MenuTimestamp *tmp = it.current(); tmp && (! found);
1730 it++, tmp = it.current()) {
1731 if (! strcmp(tmp->filename, filename)) found = True;
1736 if (! stat(filename, &buf)) {
1737 MenuTimestamp *ts = new MenuTimestamp;
1739 ts->filename = bstrdup(filename);
1740 ts->timestamp = buf.st_ctime;
1742 menuTimestamps->insert(ts);
1748 void Openbox::timeout(void) {
1749 if (reconfigure_wait)
1752 if (reread_menu_wait)
1755 reconfigure_wait = reread_menu_wait = False;
1759 void Openbox::setFocusedWindow(OpenboxWindow *win) {
1760 BScreen *old_screen = (BScreen *) 0, *screen = (BScreen *) 0;
1761 OpenboxWindow *old_win = (OpenboxWindow *) 0;
1762 Toolbar *old_tbar = (Toolbar *) 0, *tbar = (Toolbar *) 0;
1763 Workspace *old_wkspc = (Workspace *) 0, *wkspc = (Workspace *) 0;
1765 if (focused_window) {
1766 old_win = focused_window;
1767 old_screen = old_win->getScreen();
1768 old_tbar = old_screen->getToolbar();
1769 old_wkspc = old_screen->getWorkspace(old_win->getWorkspaceNumber());
1771 old_win->setFocusFlag(False);
1772 old_wkspc->getMenu()->setItemSelected(old_win->getWindowNumber(), False);
1775 if (win && ! win->isIconic()) {
1776 screen = win->getScreen();
1777 tbar = screen->getToolbar();
1778 wkspc = screen->getWorkspace(win->getWorkspaceNumber());
1780 focused_window = win;
1782 win->setFocusFlag(True);
1783 wkspc->getMenu()->setItemSelected(win->getWindowNumber(), True);
1785 focused_window = (OpenboxWindow *) 0;
1789 tbar->redrawWindowLabel(True);
1791 screen->updateNetizenWindowFocus();
1793 if (old_tbar && old_tbar != tbar)
1794 old_tbar->redrawWindowLabel(True);
1795 if (old_screen && old_screen != screen)
1796 old_screen->updateNetizenWindowFocus();