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();