]> Dogcows Code - chaz/openbox/blob - src/openbox.cc
Initial revision
[chaz/openbox] / src / openbox.cc
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)
4 //
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:
11 //
12 // The above copyright notice and this permission notice shall be included in
13 // all copies or substantial portions of the Software.
14 //
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.
22
23 // stupid macros needed to access some functions in version 2 of the GNU C
24 // library
25 #ifndef _GNU_SOURCE
26 #define _GNU_SOURCE
27 #endif // _GNU_SOURCE
28
29 #ifdef HAVE_CONFIG_H
30 # include "../config.h"
31 #endif // HAVE_CONFIG_H
32
33 #include <X11/Xlib.h>
34 #include <X11/Xutil.h>
35 #include <X11/Xresource.h>
36 #include <X11/Xatom.h>
37 #include <X11/keysym.h>
38
39 #ifdef SHAPE
40 #include <X11/extensions/shape.h>
41 #endif // SHAPE
42
43 #include "i18n.h"
44 #include "openbox.h"
45 #include "Basemenu.h"
46 #include "Clientmenu.h"
47 #include "Rootmenu.h"
48 #include "Screen.h"
49
50 #ifdef SLIT
51 #include "Slit.h"
52 #endif // SLIT
53
54 #include "Toolbar.h"
55 #include "Window.h"
56 #include "Workspace.h"
57 #include "Workspacemenu.h"
58
59 #ifdef HAVE_STDIO_H
60 # include <stdio.h>
61 #endif // HAVE_STDIO_H
62
63 #ifdef STDC_HEADERS
64 # include <stdlib.h>
65 # include <string.h>
66 #endif // STDC_HEADERS
67
68 #ifdef HAVE_UNISTD_H
69 # include <sys/types.h>
70 # include <unistd.h>
71 #endif // HAVE_UNISTD_H
72
73 #ifdef HAVE_SYS_PARAM_H
74 # include <sys/param.h>
75 #endif // HAVE_SYS_PARAM_H
76
77 #ifndef MAXPATHLEN
78 #define MAXPATHLEN 255
79 #endif // MAXPATHLEN
80
81 #ifdef HAVE_SYS_SELECT_H
82 # include <sys/select.h>
83 #endif // HAVE_SYS_SELECT_H
84
85 #ifdef HAVE_SIGNAL_H
86 # include <signal.h>
87 #endif // HAVE_SIGNAL_H
88
89 #ifdef HAVE_SYS_SIGNAL_H
90 # include <sys/signal.h>
91 #endif // HAVE_SYS_SIGNAL_H
92
93 #ifdef HAVE_SYS_STAT_H
94 # include <sys/types.h>
95 # include <sys/stat.h>
96 #endif // HAVE_SYS_STAT_H
97
98 #ifdef TIME_WITH_SYS_TIME
99 # include <sys/time.h>
100 # include <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
105 # include <time.h>
106 # endif // HAVE_SYS_TIME_H
107 #endif // TIME_WITH_SYS_TIME
108
109 #ifdef HAVE_LIBGEN_H
110 # include <libgen.h>
111 #endif // HAVE_LIBGEN_H
112
113 #ifndef HAVE_BASENAME
114 static inline char *basename (char *s) {
115 char *save = s;
116
117 while (*s) if (*s++ == '/') save = s;
118
119 return save;
120 }
121 #endif // HAVE_BASENAME
122
123
124 // X event scanner for enter/leave notifies - adapted from twm
125 typedef struct scanargs {
126 Window w;
127 Bool leave, inferior, enter;
128 } scanargs;
129
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;
139 }
140
141 return False;
142 }
143
144 Openbox *openbox;
145
146
147 Openbox::Openbox(int m_argc, char **m_argv, char *dpy_name, char *rc)
148 : BaseDisplay(m_argv[0], dpy_name) {
149 grab();
150
151 if (! XSupportsLocale())
152 fprintf(stderr, "X server does not support locale\n");
153
154 if (XSetLocaleModifiers("") == NULL)
155 fprintf(stderr, "cannot set locale modifiers\n");
156
157 ::openbox = this;
158 argc = m_argc;
159 argv = m_argv;
160 if (rc == NULL) {
161 char *homedir = getenv("HOME");
162
163 rc_file = new char[strlen(homedir) + strlen("/.openbox/rc") + 1];
164 sprintf(rc_file, "%s/.openbox", homedir);
165
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);
169
170 sprintf(rc_file, "%s/.openbox/rc", homedir);
171 } else {
172 rc_file = bstrdup(rc);
173 }
174
175 no_focus = False;
176
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;
180
181 focused_window = masked_window = (OpenboxWindow *) 0;
182 masked = None;
183
184 windowSearchList = new LinkedList<WindowSearch>;
185 menuSearchList = new LinkedList<MenuSearch>;
186
187 #ifdef SLIT
188 slitSearchList = new LinkedList<SlitSearch>;
189 #endif // SLIT
190
191 toolbarSearchList = new LinkedList<ToolbarSearch>;
192 groupSearchList = new LinkedList<WindowSearch>;
193
194 menuTimestamps = new LinkedList<MenuTimestamp>;
195
196 XrmInitialize();
197 load_rc();
198
199 #ifdef HAVE_GETPID
200 openbox_pid = XInternAtom(getXDisplay(), "_BLACKBOX_PID", False);
201 #endif // HAVE_GETPID
202
203 screenList = new LinkedList<BScreen>;
204 for (int i = 0; i < getNumberOfScreens(); i++) {
205 BScreen *screen = new BScreen(this, i);
206
207 if (! screen->isScreenManaged()) {
208 delete screen;
209 continue;
210 }
211
212 screenList->insert(screen);
213 }
214
215 if (! screenList->count()) {
216 fprintf(stderr,
217 i18n->getMessage(openboxSet, openboxNoManagableScreens,
218 "Openbox::Openbox: no managable screens found, aborting.\n"));
219 ::exit(3);
220 }
221
222 XSynchronize(getXDisplay(), False);
223 XSync(getXDisplay(), False);
224
225 reconfigure_wait = reread_menu_wait = False;
226
227 timer = new BTimer(this, this);
228 timer->setTimeout(0);
229 timer->fireOnce(True);
230
231 ungrab();
232 }
233
234
235 Openbox::~Openbox(void) {
236 while (screenList->count())
237 delete screenList->remove(0);
238
239 while (menuTimestamps->count()) {
240 MenuTimestamp *ts = menuTimestamps->remove(0);
241
242 if (ts->filename)
243 delete [] ts->filename;
244
245 delete ts;
246 }
247
248 if (resource.menu_file)
249 delete [] resource.menu_file;
250
251 if (resource.style_file)
252 delete [] resource.style_file;
253
254 delete timer;
255
256 delete screenList;
257 delete menuTimestamps;
258
259 delete windowSearchList;
260 delete menuSearchList;
261 delete toolbarSearchList;
262 delete groupSearchList;
263
264 delete [] rc_file;
265
266 #ifdef SLIT
267 delete slitSearchList;
268 #endif // SLIT
269 }
270
271
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);
277
278 return;
279 }
280
281 switch (e->type) {
282 case ButtonPress: {
283 // strip the lock key modifiers
284 e->xbutton.state &= ~(NumLockMask | ScrollLockMask | LockMask);
285
286 last_time = e->xbutton.time;
287
288 OpenboxWindow *win = (OpenboxWindow *) 0;
289 Basemenu *menu = (Basemenu *) 0;
290
291 #ifdef SLIT
292 Slit *slit = (Slit *) 0;
293 #endif // SLIT
294
295 Toolbar *tbar = (Toolbar *) 0;
296
297 if ((win = searchWindow(e->xbutton.window))) {
298 win->buttonPressEvent(&e->xbutton);
299
300 if (e->xbutton.button == 1)
301 win->installColormap(True);
302 } else if ((menu = searchMenu(e->xbutton.window))) {
303 menu->buttonPressEvent(&e->xbutton);
304
305 #ifdef SLIT
306 } else if ((slit = searchSlit(e->xbutton.window))) {
307 slit->buttonPressEvent(&e->xbutton);
308 #endif // SLIT
309
310 } else if ((tbar = searchToolbar(e->xbutton.window))) {
311 tbar->buttonPressEvent(&e->xbutton);
312 } else {
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();
320
321 if (screen->getWorkspacemenu()->isVisible())
322 screen->getWorkspacemenu()->hide();
323
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);
331
332 if (mx < 0) mx = 0;
333 if (my < 0) my = 0;
334
335 if (mx + screen->getWorkspacemenu()->getWidth() >
336 screen->getWidth())
337 mx = screen->getWidth() -
338 screen->getWorkspacemenu()->getWidth() -
339 screen->getBorderWidth();
340
341 if (my + screen->getWorkspacemenu()->getHeight() >
342 screen->getHeight())
343 my = screen->getHeight() -
344 screen->getWorkspacemenu()->getHeight() -
345 screen->getBorderWidth();
346
347 screen->getWorkspacemenu()->move(mx, my);
348
349 if (! screen->getWorkspacemenu()->isVisible()) {
350 screen->getWorkspacemenu()->removeParent();
351 screen->getWorkspacemenu()->show();
352 }
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);
358
359 if (mx < 0) mx = 0;
360 if (my < 0) my = 0;
361
362 if (mx + screen->getRootmenu()->getWidth() > screen->getWidth())
363 mx = screen->getWidth() -
364 screen->getRootmenu()->getWidth() -
365 screen->getBorderWidth();
366
367 if (my + screen->getRootmenu()->getHeight() > screen->getHeight())
368 my = screen->getHeight() -
369 screen->getRootmenu()->getHeight() -
370 screen->getBorderWidth();
371
372 screen->getRootmenu()->move(mx, my);
373
374 if (! screen->getRootmenu()->isVisible()) {
375 checkMenu();
376 screen->getRootmenu()->show();
377 }
378 } else if (e->xbutton.button == 4) {
379 if ((screen->getCurrentWorkspaceID()-1)<0)
380 screen->changeWorkspaceID(screen->getCount()-1);
381 else
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);
386 else
387 screen->changeWorkspaceID(screen->getCurrentWorkspaceID()+1);
388 }
389 }
390 }
391 }
392
393 break;
394 }
395
396 case ButtonRelease: {
397 // strip the lock key modifiers
398 e->xbutton.state &= ~(NumLockMask | ScrollLockMask | LockMask);
399
400 last_time = e->xbutton.time;
401
402 OpenboxWindow *win = (OpenboxWindow *) 0;
403 Basemenu *menu = (Basemenu *) 0;
404 Toolbar *tbar = (Toolbar *) 0;
405
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);
412
413 break;
414 }
415
416 case ConfigureRequest: {
417 OpenboxWindow *win = (OpenboxWindow *) 0;
418
419 #ifdef SLIT
420 Slit *slit = (Slit *) 0;
421 #endif // SLIT
422
423 if ((win = searchWindow(e->xconfigurerequest.window))) {
424 win->configureRequestEvent(&e->xconfigurerequest);
425
426 #ifdef SLIT
427 } else if ((slit = searchSlit(e->xconfigurerequest.window))) {
428 slit->configureRequestEvent(&e->xconfigurerequest);
429 #endif // SLIT
430
431 } else {
432 grab();
433
434 if (validateWindow(e->xconfigurerequest.window)) {
435 XWindowChanges xwc;
436
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;
444
445 XConfigureWindow(getXDisplay(), e->xconfigurerequest.window,
446 e->xconfigurerequest.value_mask, &xwc);
447 }
448
449 ungrab();
450 }
451
452 break;
453 }
454
455 case MapRequest: {
456 #ifdef DEBUG
457 fprintf(stderr,
458 i18n->getMessage(openboxSet, openboxMapRequest,
459 "Openbox::process_event(): MapRequest for 0x%lx\n"),
460 e->xmaprequest.window);
461 #endif // DEBUG
462
463 OpenboxWindow *win = searchWindow(e->xmaprequest.window);
464
465 if (! win)
466 win = new OpenboxWindow(this, e->xmaprequest.window);
467
468 if ((win = searchWindow(e->xmaprequest.window)))
469 win->mapRequestEvent(&e->xmaprequest);
470
471 break;
472 }
473
474 case MapNotify: {
475 OpenboxWindow *win = searchWindow(e->xmap.window);
476
477 if (win)
478 win->mapNotifyEvent(&e->xmap);
479
480 break;
481 }
482
483 case UnmapNotify: {
484 OpenboxWindow *win = (OpenboxWindow *) 0;
485
486 #ifdef SLIT
487 Slit *slit = (Slit *) 0;
488 #endif // SLIT
489
490 if ((win = searchWindow(e->xunmap.window))) {
491 win->unmapNotifyEvent(&e->xunmap);
492 if (focused_window == win)
493 focused_window = (OpenboxWindow *) 0;
494 #ifdef SLIT
495 } else if ((slit = searchSlit(e->xunmap.window))) {
496 slit->removeClient(e->xunmap.window);
497 #endif // SLIT
498
499 }
500
501 break;
502 }
503
504 case DestroyNotify: {
505 OpenboxWindow *win = (OpenboxWindow *) 0;
506
507 #ifdef SLIT
508 Slit *slit = (Slit *) 0;
509 #endif // SLIT
510
511 if ((win = searchWindow(e->xdestroywindow.window))) {
512 win->destroyNotifyEvent(&e->xdestroywindow);
513 if (focused_window == win)
514 focused_window = (OpenboxWindow *) 0;
515 #ifdef SLIT
516 } else if ((slit = searchSlit(e->xdestroywindow.window))) {
517 slit->removeClient(e->xdestroywindow.window, False);
518 #endif // SLIT
519 }
520
521 break;
522 }
523
524 case MotionNotify: {
525 // strip the lock key modifiers
526 e->xbutton.state &= ~(NumLockMask | ScrollLockMask | LockMask);
527
528 last_time = e->xmotion.time;
529
530 OpenboxWindow *win = (OpenboxWindow *) 0;
531 Basemenu *menu = (Basemenu *) 0;
532
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);
537
538 break;
539 }
540
541 case PropertyNotify: {
542 last_time = e->xproperty.time;
543
544 if (e->xproperty.state != PropertyDelete) {
545 OpenboxWindow *win = searchWindow(e->xproperty.window);
546
547 if (win)
548 win->propertyNotifyEvent(e->xproperty.atom);
549 }
550
551 break;
552 }
553
554 case EnterNotify: {
555 last_time = e->xcrossing.time;
556
557 BScreen *screen = (BScreen *) 0;
558 OpenboxWindow *win = (OpenboxWindow *) 0;
559 Basemenu *menu = (Basemenu *) 0;
560 Toolbar *tbar = (Toolbar *) 0;
561
562 #ifdef SLIT
563 Slit *slit = (Slit *) 0;
564 #endif // SLIT
565
566 if (e->xcrossing.mode == NotifyGrab) break;
567
568 XEvent dummy;
569 scanargs sa;
570 sa.w = e->xcrossing.window;
571 sa.enter = sa.leave = False;
572 XCheckIfEvent(getXDisplay(), &dummy, queueScanner, (char *) &sa);
573
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)) {
580 grab();
581
582 if (((! sa.leave) || sa.inferior) && win->isVisible() &&
583 win->setInputFocus())
584 win->installColormap(True);
585
586 ungrab();
587 }
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);
592 #ifdef SLIT
593 } else if ((slit = searchSlit(e->xcrossing.window))) {
594 slit->enterNotifyEvent(&e->xcrossing);
595 #endif // SLIT
596 }
597 break;
598 }
599
600 case LeaveNotify: {
601 last_time = e->xcrossing.time;
602
603 OpenboxWindow *win = (OpenboxWindow *) 0;
604 Basemenu *menu = (Basemenu *) 0;
605 Toolbar *tbar = (Toolbar *) 0;
606
607 #ifdef SLIT
608 Slit *slit = (Slit *) 0;
609 #endif // SLIT
610
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);
617 #ifdef SLIT
618 else if ((slit = searchSlit(e->xcrossing.window)))
619 slit->leaveNotifyEvent(&e->xcrossing);
620 #endif // SLIT
621
622 break;
623 }
624
625 case Expose: {
626 OpenboxWindow *win = (OpenboxWindow *) 0;
627 Basemenu *menu = (Basemenu *) 0;
628 Toolbar *tbar = (Toolbar *) 0;
629
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);
636
637 break;
638 }
639
640 case KeyPress: {
641 Toolbar *tbar = searchToolbar(e->xkey.window);
642
643 if (tbar && tbar->isEditing())
644 tbar->keyPressEvent(&e->xkey);
645
646 break;
647 }
648
649 case ColormapNotify: {
650 BScreen *screen = searchScreen(e->xcolormap.window);
651
652 if (screen)
653 screen->setRootColormapInstalled((e->xcolormap.state ==
654 ColormapInstalled) ? True : False);
655
656 break;
657 }
658
659 case FocusIn: {
660 if (e->xfocus.mode == NotifyUngrab || e->xfocus.detail == NotifyPointer)
661 break;
662
663 OpenboxWindow *win = searchWindow(e->xfocus.window);
664 if (win && ! win->isFocused())
665 setFocusedWindow(win);
666
667 break;
668 }
669
670 case FocusOut:
671 break;
672
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;
678
679 if (e->xclient.data.l[0] == IconicState)
680 win->iconify();
681 if (e->xclient.data.l[0] == NormalState)
682 win->deiconify();
683 } else if (e->xclient.message_type == getOpenboxChangeWorkspaceAtom()) {
684 BScreen *screen = searchScreen(e->xclient.window);
685
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);
691
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);
696
697 if (screen) {
698 if (! e->xclient.data.l[0])
699 screen->prevFocus();
700 else
701 screen->nextFocus();
702 }
703 } else if (e->xclient.message_type == getOpenboxChangeAttributesAtom()) {
704 OpenboxWindow *win = searchWindow(e->xclient.window);
705
706 if (win && win->validateClient()) {
707 OpenboxHints net;
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];
713
714 win->changeOpenboxHints(&net);
715 }
716 }
717 }
718
719 break;
720 }
721
722
723 default: {
724 #ifdef SHAPE
725 if (e->type == getShapeEventBase()) {
726 XShapeEvent *shape_event = (XShapeEvent *) e;
727 OpenboxWindow *win = (OpenboxWindow *) 0;
728
729 if ((win = searchWindow(e->xany.window)) ||
730 (shape_event->kind != ShapeBounding))
731 win->shapeEvent(shape_event);
732 }
733 #endif // SHAPE
734
735 }
736 } // switch
737 }
738
739
740 Bool Openbox::handleSignal(int sig) {
741 switch (sig) {
742 case SIGHUP:
743 reconfigure();
744 break;
745
746 case SIGUSR1:
747 reload_rc();
748 break;
749
750 case SIGUSR2:
751 rereadMenu();
752 break;
753
754 case SIGPIPE:
755 case SIGSEGV:
756 case SIGFPE:
757 case SIGINT:
758 case SIGTERM:
759 shutdown();
760
761 default:
762 return False;
763 }
764
765 return True;
766 }
767
768
769 BScreen *Openbox::searchScreen(Window window) {
770 LinkedListIterator<BScreen> it(screenList);
771
772 for (BScreen *curr = it.current(); curr; it++, curr = it.current()) {
773 if (curr->getRootWindow() == window) {
774 return curr;
775 }
776 }
777
778 return (BScreen *) 0;
779 }
780
781
782 OpenboxWindow *Openbox::searchWindow(Window window) {
783 LinkedListIterator<WindowSearch> it(windowSearchList);
784
785 for (WindowSearch *tmp = it.current(); tmp; it++, tmp = it.current()) {
786 if (tmp->getWindow() == window) {
787 return tmp->getData();
788 }
789 }
790
791 return (OpenboxWindow *) 0;
792 }
793
794
795 OpenboxWindow *Openbox::searchGroup(Window window, OpenboxWindow *win) {
796 OpenboxWindow *w = (OpenboxWindow *) 0;
797 LinkedListIterator<WindowSearch> it(groupSearchList);
798
799 for (WindowSearch *tmp = it.current(); tmp; it++, tmp = it.current()) {
800 if (tmp->getWindow() == window) {
801 w = tmp->getData();
802 if (w->getClientWindow() != win->getClientWindow())
803 return win;
804 }
805 }
806
807 return (OpenboxWindow *) 0;
808 }
809
810
811 Basemenu *Openbox::searchMenu(Window window) {
812 LinkedListIterator<MenuSearch> it(menuSearchList);
813
814 for (MenuSearch *tmp = it.current(); tmp; it++, tmp = it.current()) {
815 if (tmp->getWindow() == window)
816 return tmp->getData();
817 }
818
819 return (Basemenu *) 0;
820 }
821
822
823 Toolbar *Openbox::searchToolbar(Window window) {
824 LinkedListIterator<ToolbarSearch> it(toolbarSearchList);
825
826 for (ToolbarSearch *tmp = it.current(); tmp; it++, tmp = it.current()) {
827 if (tmp->getWindow() == window)
828 return tmp->getData();
829 }
830
831 return (Toolbar *) 0;
832 }
833
834
835 #ifdef SLIT
836 Slit *Openbox::searchSlit(Window window) {
837 LinkedListIterator<SlitSearch> it(slitSearchList);
838
839 for (SlitSearch *tmp = it.current(); tmp; it++, tmp = it.current()) {
840 if (tmp->getWindow() == window)
841 return tmp->getData();
842 }
843
844 return (Slit *) 0;
845 }
846 #endif // SLIT
847
848
849 void Openbox::saveWindowSearch(Window window, OpenboxWindow *data) {
850 windowSearchList->insert(new WindowSearch(window, data));
851 }
852
853
854 void Openbox::saveGroupSearch(Window window, OpenboxWindow *data) {
855 groupSearchList->insert(new WindowSearch(window, data));
856 }
857
858
859 void Openbox::saveMenuSearch(Window window, Basemenu *data) {
860 menuSearchList->insert(new MenuSearch(window, data));
861 }
862
863
864 void Openbox::saveToolbarSearch(Window window, Toolbar *data) {
865 toolbarSearchList->insert(new ToolbarSearch(window, data));
866 }
867
868
869 #ifdef SLIT
870 void Openbox::saveSlitSearch(Window window, Slit *data) {
871 slitSearchList->insert(new SlitSearch(window, data));
872 }
873 #endif // SLIT
874
875
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);
881 delete tmp;
882 break;
883 }
884 }
885 }
886
887
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);
893 delete tmp;
894 break;
895 }
896 }
897 }
898
899
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);
905 delete tmp;
906 break;
907 }
908 }
909 }
910
911
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);
917 delete tmp;
918 break;
919 }
920 }
921 }
922
923
924 #ifdef SLIT
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);
930 delete tmp;
931 break;
932 }
933 }
934 }
935 #endif // SLIT
936
937
938 void Openbox::restart(const char *prog) {
939 shutdown();
940
941 if (prog) {
942 execlp(prog, prog, NULL);
943 perror(prog);
944 }
945
946 // fall back in case the above execlp doesn't work
947 execvp(argv[0], argv);
948 execvp(basename(argv[0]), argv);
949 }
950
951
952 void Openbox::shutdown(void) {
953 BaseDisplay::shutdown();
954
955 XSetInputFocus(getXDisplay(), PointerRoot, None, CurrentTime);
956
957 LinkedListIterator<BScreen> it(screenList);
958 for (BScreen *s = it.current(); s; it++, s = it.current())
959 s->shutdown();
960
961 XSync(getXDisplay(), False);
962
963 save_rc();
964 }
965
966
967 void Openbox::save_rc(void) {
968 XrmDatabase new_openboxrc = (XrmDatabase) 0;
969 char rc_string[1024];
970
971 load_rc();
972
973 sprintf(rc_string, "session.menuFile: %s", resource.menu_file);
974 XrmPutLineResource(&new_openboxrc, rc_string);
975
976 sprintf(rc_string, "session.colorsPerChannel: %d",
977 resource.colors_per_channel);
978 XrmPutLineResource(&new_openboxrc, rc_string);
979
980 sprintf(rc_string, "session.titlebarLayout: %s",
981 resource.titlebar_layout);
982 XrmPutLineResource(&new_openboxrc, rc_string);
983
984 sprintf(rc_string, "session.doubleClickInterval: %lu",
985 resource.double_click_interval);
986 XrmPutLineResource(&new_openboxrc, rc_string);
987
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);
992
993 sprintf(rc_string, "session.cacheLife: %lu", resource.cache_life / 60000);
994 XrmPutLineResource(&new_openboxrc, rc_string);
995
996 sprintf(rc_string, "session.cacheMax: %lu", resource.cache_max);
997 XrmPutLineResource(&new_openboxrc, rc_string);
998
999 LinkedListIterator<BScreen> it(screenList);
1000 for (BScreen *screen = it.current(); screen; it++, screen = it.current()) {
1001 int screen_number = screen->getScreenNumber();
1002
1003 #ifdef SLIT
1004 char *slit_placement = (char *) 0;
1005
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;
1015 }
1016
1017 sprintf(rc_string, "session.screen%d.slit.placement: %s", screen_number,
1018 slit_placement);
1019 XrmPutLineResource(&new_openboxrc, rc_string);
1020
1021 sprintf(rc_string, "session.screen%d.slit.direction: %s", screen_number,
1022 ((screen->getSlitDirection() == Slit::Horizontal) ? "Horizontal" :
1023 "Vertical"));
1024 XrmPutLineResource(&new_openboxrc, rc_string);
1025
1026 const char *rootcmd;
1027 if ((rootcmd = screen->getRootCommand()) != NULL) {
1028 sprintf(rc_string, "session.screen%d.rootCommand: %s", screen_number,
1029 rootcmd);
1030 XrmPutLineResource(&new_openboxrc, rc_string);
1031 }
1032
1033 sprintf(rc_string, "session.screen%d.slit.onTop: %s", screen_number,
1034 ((screen->getSlit()->isOnTop()) ? "True" : "False"));
1035 XrmPutLineResource(&new_openboxrc, rc_string);
1036
1037 sprintf(rc_string, "session.screen%d.slit.autoHide: %s", screen_number,
1038 ((screen->getSlit()->doAutoHide()) ? "True" : "False"));
1039 XrmPutLineResource(&new_openboxrc, rc_string);
1040 #endif // SLIT
1041
1042 sprintf(rc_string, "session.opaqueMove: %s",
1043 ((screen->doOpaqueMove()) ? "True" : "False"));
1044 XrmPutLineResource(&new_openboxrc, rc_string);
1045
1046 sprintf(rc_string, "session.imageDither: %s",
1047 ((screen->getImageControl()->doDither()) ? "True" : "False"));
1048 XrmPutLineResource(&new_openboxrc, rc_string);
1049
1050 sprintf(rc_string, "session.screen%d.fullMaximization: %s", screen_number,
1051 ((screen->doFullMax()) ? "True" : "False"));
1052 XrmPutLineResource(&new_openboxrc, rc_string);
1053
1054 sprintf(rc_string, "session.screen%d.focusNewWindows: %s", screen_number,
1055 ((screen->doFocusNew()) ? "True" : "False"));
1056 XrmPutLineResource(&new_openboxrc, rc_string);
1057
1058 sprintf(rc_string, "session.screen%d.focusLastWindow: %s", screen_number,
1059 ((screen->doFocusLast()) ? "True" : "False"));
1060 XrmPutLineResource(&new_openboxrc, rc_string);
1061
1062 sprintf(rc_string, "session.screen%d.rowPlacementDirection: %s",
1063 screen_number,
1064 ((screen->getRowPlacementDirection() == BScreen::LeftRight) ?
1065 "LeftToRight" : "RightToLeft"));
1066 XrmPutLineResource(&new_openboxrc, rc_string);
1067
1068 sprintf(rc_string, "session.screen%d.colPlacementDirection: %s",
1069 screen_number,
1070 ((screen->getColPlacementDirection() == BScreen::TopBottom) ?
1071 "TopToBottom" : "BottomToTop"));
1072 XrmPutLineResource(&new_openboxrc, rc_string);
1073
1074 char *placement = (char *) 0;
1075 switch (screen->getPlacementPolicy()) {
1076 case BScreen::CascadePlacement:
1077 placement = "CascadePlacement";
1078 break;
1079
1080 case BScreen::ColSmartPlacement:
1081 placement = "ColSmartPlacement";
1082 break;
1083
1084 case BScreen::RowSmartPlacement:
1085 default:
1086 placement = "RowSmartPlacement";
1087 break;
1088 }
1089 sprintf(rc_string, "session.screen%d.windowPlacement: %s", screen_number,
1090 placement);
1091 XrmPutLineResource(&new_openboxrc, rc_string);
1092
1093 sprintf(rc_string, "session.screen%d.windowZones: %i", screen_number,
1094 screen->getWindowZones());
1095 XrmPutLineResource(&new_openboxrc, rc_string);
1096
1097 sprintf(rc_string, "session.screen%d.focusModel: %s", screen_number,
1098 ((screen->isSloppyFocus()) ?
1099 ((screen->doAutoRaise()) ? "AutoRaiseSloppyFocus" :
1100 "SloppyFocus") :
1101 "ClickToFocus"));
1102 XrmPutLineResource(&new_openboxrc, rc_string);
1103
1104 sprintf(rc_string, "session.screen%d.workspaces: %d", screen_number,
1105 screen->getCount());
1106 XrmPutLineResource(&new_openboxrc, rc_string);
1107
1108 sprintf(rc_string, "session.screen%d.toolbar.onTop: %s", screen_number,
1109 ((screen->getToolbar()->isOnTop()) ? "True" : "False"));
1110 XrmPutLineResource(&new_openboxrc, rc_string);
1111
1112 sprintf(rc_string, "session.screen%d.toolbar.autoHide: %s", screen_number,
1113 ((screen->getToolbar()->doAutoHide()) ? "True" : "False"));
1114 XrmPutLineResource(&new_openboxrc, rc_string);
1115
1116 char *toolbar_placement = (char *) 0;
1117
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;
1126 }
1127
1128 sprintf(rc_string, "session.screen%d.toolbar.placement: %s", screen_number,
1129 toolbar_placement);
1130 XrmPutLineResource(&new_openboxrc, rc_string);
1131
1132 load_rc(screen);
1133
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
1137 // users changes...
1138
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);
1148
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
1153
1154 sprintf(rc_string, "session.screen%d.edgeSnapThreshold: %d", screen_number,
1155 screen->getEdgeSnapThreshold());
1156 XrmPutLineResource(&new_openboxrc, rc_string);
1157
1158 sprintf(rc_string, "session.screen%d.toolbar.widthPercent: %d",
1159 screen_number, screen->getToolbarWidthPercent());
1160 XrmPutLineResource(&new_openboxrc, rc_string);
1161
1162 // write out the users workspace names
1163 int i, len = 0;
1164 for (i = 0; i < screen->getCount(); i++)
1165 len += strlen((screen->getWorkspace(i)->getName()) ?
1166 screen->getWorkspace(i)->getName() : "Null") + 1;
1167
1168 char *resource_string = new char[len + 1024],
1169 *save_string = new char[len], *save_string_pos = save_string,
1170 *name_string_pos;
1171 if (save_string) {
1172 for (i = 0; i < screen->getCount(); i++) {
1173 len = strlen((screen->getWorkspace(i)->getName()) ?
1174 screen->getWorkspace(i)->getName() : "Null") + 1;
1175 name_string_pos =
1176 (char *) ((screen->getWorkspace(i)->getName()) ?
1177 screen->getWorkspace(i)->getName() : "Null");
1178
1179 while (--len) *(save_string_pos++) = *(name_string_pos++);
1180 *(save_string_pos++) = ',';
1181 }
1182 }
1183
1184 *(--save_string_pos) = '\0';
1185
1186 sprintf(resource_string, "session.screen%d.workspaceNames: %s",
1187 screen_number, save_string);
1188 XrmPutLineResource(&new_openboxrc, resource_string);
1189
1190 delete [] resource_string;
1191 delete [] save_string;
1192 }
1193
1194 XrmDatabase old_openboxrc = XrmGetFileDatabase(rc_file);
1195
1196 XrmMergeDatabases(new_openboxrc, &old_openboxrc);
1197 XrmPutFileDatabase(old_openboxrc, rc_file);
1198 XrmDestroyDatabase(old_openboxrc);
1199 }
1200
1201
1202 void Openbox::load_rc(void) {
1203 XrmDatabase database = (XrmDatabase) 0;
1204
1205 database = XrmGetFileDatabase(rc_file);
1206
1207 XrmValue value;
1208 char *value_type;
1209
1210 if (resource.menu_file)
1211 delete [] resource.menu_file;
1212
1213 if (XrmGetResource(database, "session.menuFile", "Session.MenuFile",
1214 &value_type, &value))
1215 resource.menu_file = bstrdup(value.addr);
1216 else
1217 resource.menu_file = bstrdup(DEFAULTMENU);
1218
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;
1223 } else {
1224 if (resource.colors_per_channel < 2) resource.colors_per_channel = 2;
1225 if (resource.colors_per_channel > 6) resource.colors_per_channel = 6;
1226 }
1227 } else {
1228 resource.colors_per_channel = 4;
1229 }
1230
1231 if (resource.style_file)
1232 delete [] resource.style_file;
1233
1234 if (XrmGetResource(database, "session.styleFile", "Session.StyleFile",
1235 &value_type, &value))
1236 resource.style_file = bstrdup(value.addr);
1237 else
1238 resource.style_file = bstrdup(DEFAULTSTYLE);
1239
1240 if (XrmGetResource(database, "session.titlebarLayout",
1241 "Session.TitlebarLayout", &value_type, &value)) {
1242 resource.titlebar_layout = bstrdup(value.addr == NULL ? "ILMC" :
1243 value.addr);
1244 } else {
1245 resource.titlebar_layout = bstrdup("ILMC");
1246 }
1247
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;
1252 } else {
1253 resource.double_click_interval = 250;
1254 }
1255
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;
1260 } else {
1261 resource.auto_raise_delay.tv_usec = 400;
1262 }
1263
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;
1268
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;
1273 } else {
1274 resource.cache_life = 5l;
1275 }
1276
1277 resource.cache_life *= 60000;
1278
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;
1283 } else {
1284 resource.cache_max = 200;
1285 }
1286 }
1287
1288
1289 void Openbox::load_rc(BScreen *screen) {
1290 XrmDatabase database = (XrmDatabase) 0;
1291
1292 database = XrmGetFileDatabase(rc_file);
1293
1294 XrmValue value;
1295 char *value_type, name_lookup[1024], class_lookup[1024];
1296 int screen_number = screen->getScreenNumber();
1297
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,
1301 &value)) {
1302 if (! strncasecmp(value.addr, "true", value.size))
1303 screen->saveFullMax(True);
1304 else
1305 screen->saveFullMax(False);
1306 } else {
1307 screen->saveFullMax(False);
1308 }
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,
1312 &value)) {
1313 if (! strncasecmp(value.addr, "true", value.size))
1314 screen->saveFocusNew(True);
1315 else
1316 screen->saveFocusNew(False);
1317 } else {
1318 screen->saveFocusNew(False);
1319 }
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,
1323 &value)) {
1324 if (! strncasecmp(value.addr, "true", value.size))
1325 screen->saveFocusLast(True);
1326 else
1327 screen->saveFocusLast(False);
1328 } else {
1329 screen->saveFocusLast(False);
1330 }
1331 sprintf(name_lookup, "session.screen%d.rowPlacementDirection",
1332 screen_number);
1333 sprintf(class_lookup, "Session.Screen%d.RowPlacementDirection",
1334 screen_number);
1335 if (XrmGetResource(database, name_lookup, class_lookup, &value_type,
1336 &value)) {
1337 if (! strncasecmp(value.addr, "righttoleft", value.size))
1338 screen->saveRowPlacementDirection(BScreen::RightLeft);
1339 else
1340 screen->saveRowPlacementDirection(BScreen::LeftRight);
1341 } else {
1342 screen->saveRowPlacementDirection(BScreen::LeftRight);
1343 }
1344 sprintf(name_lookup, "session.screen%d.colPlacementDirection",
1345 screen_number);
1346 sprintf(class_lookup, "Session.Screen%d.ColPlacementDirection",
1347 screen_number);
1348 if (XrmGetResource(database, name_lookup, class_lookup, &value_type,
1349 &value)) {
1350 if (! strncasecmp(value.addr, "bottomtotop", value.size))
1351 screen->saveColPlacementDirection(BScreen::BottomTop);
1352 else
1353 screen->saveColPlacementDirection(BScreen::TopBottom);
1354 } else {
1355 screen->saveColPlacementDirection(BScreen::TopBottom);
1356 }
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,
1360 &value)) {
1361 int i;
1362 if (sscanf(value.addr, "%d", &i) != 1) i = 1;
1363 screen->saveWorkspaces(i);
1364 } else {
1365 screen->saveWorkspaces(1);
1366 }
1367 sprintf(name_lookup, "session.screen%d.toolbar.widthPercent",
1368 screen_number);
1369 sprintf(class_lookup, "Session.Screen%d.Toolbar.WidthPercent",
1370 screen_number);
1371 if (XrmGetResource(database, name_lookup, class_lookup, &value_type,
1372 &value)) {
1373 int i;
1374 if (sscanf(value.addr, "%d", &i) != 1) i = 66;
1375
1376 if (i <= 0 || i > 100)
1377 i = 66;
1378
1379 screen->saveToolbarWidthPercent(i);
1380 } else {
1381 screen->saveToolbarWidthPercent(66);
1382 }
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,
1386 &value)) {
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);
1397 else
1398 screen->saveToolbarPlacement(Toolbar::BottomCenter);
1399 } else {
1400 screen->saveToolbarPlacement(Toolbar::BottomCenter);
1401 }
1402 screen->removeWorkspaceNames();
1403
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,
1407 &value)) {
1408 char *search = bstrdup(value.addr);
1409
1410 for (int i = 0; i < screen->getNumberOfWorkspaces(); i++) {
1411 char *nn;
1412
1413 if (! i) nn = strtok(search, ",");
1414 else nn = strtok(NULL, ",");
1415
1416 if (nn) screen->addWorkspaceName(nn);
1417 else break;
1418 }
1419
1420 delete [] search;
1421 }
1422
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,
1426 &value)) {
1427 if (! strncasecmp(value.addr, "true", value.size))
1428 screen->saveToolbarOnTop(True);
1429 else
1430 screen->saveToolbarOnTop(False);
1431 } else {
1432 screen->saveToolbarOnTop(False);
1433 }
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,
1437 &value)) {
1438 if (! strncasecmp(value.addr, "true", value.size))
1439 screen->saveToolbarAutoHide(True);
1440 else
1441 screen->saveToolbarAutoHide(False);
1442 } else {
1443 screen->saveToolbarAutoHide(False);
1444 }
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,
1448 &value)) {
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);
1455 } else {
1456 screen->saveSloppyFocus(True);
1457 screen->saveAutoRaise(False);
1458 }
1459 } else {
1460 screen->saveSloppyFocus(True);
1461 screen->saveAutoRaise(False);
1462 }
1463
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,
1467 &value)) {
1468 int i = atoi(value.addr);
1469 screen->saveWindowZones((i == 1 || i == 2 || i == 4) ? i : 1);
1470 } else {
1471 screen->saveWindowZones(1);
1472 }
1473
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,
1477 &value)) {
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);
1482 else
1483 screen->savePlacementPolicy(BScreen::CascadePlacement);
1484 } else {
1485 screen->savePlacementPolicy(BScreen::RowSmartPlacement);
1486 }
1487 #ifdef SLIT
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,
1491 &value)) {
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);
1506 else
1507 screen->saveSlitPlacement(Slit::CenterRight);
1508 } else {
1509 screen->saveSlitPlacement(Slit::CenterRight);
1510 }
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,
1514 &value)) {
1515 if (! strncasecmp(value.addr, "Horizontal", value.size))
1516 screen->saveSlitDirection(Slit::Horizontal);
1517 else
1518 screen->saveSlitDirection(Slit::Vertical);
1519 } else {
1520 screen->saveSlitDirection(Slit::Vertical);
1521 }
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,
1525 &value)) {
1526 if (! strncasecmp(value.addr, "True", value.size))
1527 screen->saveSlitOnTop(True);
1528 else
1529 screen->saveSlitOnTop(False);
1530 } else {
1531 screen->saveSlitOnTop(False);
1532 }
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,
1536 &value)) {
1537 if (! strncasecmp(value.addr, "True", value.size))
1538 screen->saveSlitAutoHide(True);
1539 else
1540 screen->saveSlitAutoHide(False);
1541 } else {
1542 screen->saveSlitAutoHide(False);
1543 }
1544 #endif // SLIT
1545
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,
1550 &value)) {
1551 screen->saveStrftimeFormat(value.addr);
1552 } else {
1553 screen->saveStrftimeFormat("%I:%M %p");
1554 }
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,
1559 &value)) {
1560 if (strncasecmp(value.addr, "european", value.size))
1561 screen->saveDateFormat(B_AmericanDate);
1562 else
1563 screen->saveDateFormat(B_EuropeanDate);
1564 } else {
1565 screen->saveDateFormat(B_AmericanDate);
1566 }
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,
1570 &value)) {
1571 int clock;
1572 if (sscanf(value.addr, "%d", &clock) != 1) screen->saveClock24Hour(False);
1573 else if (clock == 24) screen->saveClock24Hour(True);
1574 else screen->saveClock24Hour(False);
1575 } else {
1576 screen->saveClock24Hour(False);
1577 }
1578 #endif // HAVE_STRFTIME
1579
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,
1583 &value)) {
1584 int threshold;
1585 if (sscanf(value.addr, "%d", &threshold) != 1)
1586 screen->saveEdgeSnapThreshold(0);
1587 else
1588 screen->saveEdgeSnapThreshold(threshold);
1589 } else {
1590 screen->saveEdgeSnapThreshold(0);
1591 }
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);
1598 else
1599 screen->saveImageDither(False);
1600 } else {
1601 screen->saveImageDither(True);
1602 }
1603
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,
1607 &value)) {
1608 screen->saveRootCommand(value.addr);
1609 } else
1610 screen->saveRootCommand(NULL);
1611
1612 if (XrmGetResource(database, "session.opaqueMove", "Session.OpaqueMove",
1613 &value_type, &value)) {
1614 if (! strncasecmp("true", value.addr, value.size))
1615 screen->saveOpaqueMove(True);
1616 else
1617 screen->saveOpaqueMove(False);
1618 } else {
1619 screen->saveOpaqueMove(False);
1620 }
1621 XrmDestroyDatabase(database);
1622 }
1623
1624
1625 void Openbox::reload_rc(void) {
1626 load_rc();
1627 reconfigure();
1628 }
1629
1630
1631 void Openbox::reconfigure(void) {
1632 reconfigure_wait = True;
1633
1634 if (! timer->isTiming()) timer->start();
1635 }
1636
1637
1638 void Openbox::real_reconfigure(void) {
1639 grab();
1640
1641 XrmDatabase new_openboxrc = (XrmDatabase) 0;
1642 char style[MAXPATHLEN + 64];
1643
1644 sprintf(style, "session.styleFile: %s", resource.style_file);
1645 XrmPutLineResource(&new_openboxrc, style);
1646
1647 XrmDatabase old_openboxrc = XrmGetFileDatabase(rc_file);
1648
1649 XrmMergeDatabases(new_openboxrc, &old_openboxrc);
1650 XrmPutFileDatabase(old_openboxrc, rc_file);
1651 if (old_openboxrc) XrmDestroyDatabase(old_openboxrc);
1652
1653 for (int i = 0, n = menuTimestamps->count(); i < n; i++) {
1654 MenuTimestamp *ts = menuTimestamps->remove(0);
1655
1656 if (ts) {
1657 if (ts->filename)
1658 delete [] ts->filename;
1659
1660 delete ts;
1661 }
1662 }
1663
1664 LinkedListIterator<BScreen> it(screenList);
1665 for (BScreen *screen = it.current(); screen; it++, screen = it.current()) {
1666 screen->reconfigure();
1667 }
1668
1669 ungrab();
1670 }
1671
1672
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()) {
1678 struct stat buf;
1679
1680 if (! stat(tmp->filename, &buf)) {
1681 if (tmp->timestamp != buf.st_ctime)
1682 reread = True;
1683 } else {
1684 reread = True;
1685 }
1686 }
1687
1688 if (reread) rereadMenu();
1689 }
1690
1691
1692 void Openbox::rereadMenu(void) {
1693 reread_menu_wait = True;
1694
1695 if (! timer->isTiming()) timer->start();
1696 }
1697
1698
1699 void Openbox::real_rereadMenu(void) {
1700 for (int i = 0, n = menuTimestamps->count(); i < n; i++) {
1701 MenuTimestamp *ts = menuTimestamps->remove(0);
1702
1703 if (ts) {
1704 if (ts->filename)
1705 delete [] ts->filename;
1706
1707 delete ts;
1708 }
1709 }
1710
1711 LinkedListIterator<BScreen> it(screenList);
1712 for (BScreen *screen = it.current(); screen; it++, screen = it.current())
1713 screen->rereadMenu();
1714 }
1715
1716
1717 void Openbox::saveStyleFilename(const char *filename) {
1718 if (resource.style_file)
1719 delete [] resource.style_file;
1720
1721 resource.style_file = bstrdup(filename);
1722 }
1723
1724
1725 void Openbox::saveMenuFilename(const char *filename) {
1726 Bool found = False;
1727
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;
1732 }
1733 if (! found) {
1734 struct stat buf;
1735
1736 if (! stat(filename, &buf)) {
1737 MenuTimestamp *ts = new MenuTimestamp;
1738
1739 ts->filename = bstrdup(filename);
1740 ts->timestamp = buf.st_ctime;
1741
1742 menuTimestamps->insert(ts);
1743 }
1744 }
1745 }
1746
1747
1748 void Openbox::timeout(void) {
1749 if (reconfigure_wait)
1750 real_reconfigure();
1751
1752 if (reread_menu_wait)
1753 real_rereadMenu();
1754
1755 reconfigure_wait = reread_menu_wait = False;
1756 }
1757
1758
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;
1764
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());
1770
1771 old_win->setFocusFlag(False);
1772 old_wkspc->getMenu()->setItemSelected(old_win->getWindowNumber(), False);
1773 }
1774
1775 if (win && ! win->isIconic()) {
1776 screen = win->getScreen();
1777 tbar = screen->getToolbar();
1778 wkspc = screen->getWorkspace(win->getWorkspaceNumber());
1779
1780 focused_window = win;
1781
1782 win->setFocusFlag(True);
1783 wkspc->getMenu()->setItemSelected(win->getWindowNumber(), True);
1784 } else {
1785 focused_window = (OpenboxWindow *) 0;
1786 }
1787
1788 if (tbar)
1789 tbar->redrawWindowLabel(True);
1790 if (screen)
1791 screen->updateNetizenWindowFocus();
1792
1793 if (old_tbar && old_tbar != tbar)
1794 old_tbar->redrawWindowLabel(True);
1795 if (old_screen && old_screen != screen)
1796 old_screen->updateNetizenWindowFocus();
1797 }
This page took 0.116529 seconds and 4 git commands to generate.