]> Dogcows Code - chaz/openbox/blob - src/Screen.cc
Added style resources for window.button.pressed.focus: and
[chaz/openbox] / src / Screen.cc
1 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
2 // Screen.cc for Blackbox - an X11 Window manager
3 // Copyright (c) 2001 - 2002 Sean 'Shaleh' Perry <shaleh@debian.org>
4 // Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
5 //
6 // Permission is hereby granted, free of charge, to any person obtaining a
7 // copy of this software and associated documentation files (the "Software"),
8 // to deal in the Software without restriction, including without limitation
9 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 // and/or sell copies of the Software, and to permit persons to whom the
11 // Software is furnished to do so, subject to the following conditions:
12 //
13 // The above copyright notice and this permission notice shall be included in
14 // all copies or substantial portions of the Software.
15 //
16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 // DEALINGS IN THE SOFTWARE.
23
24 #ifdef HAVE_CONFIG_H
25 #include "../config.h"
26 #endif // HAVE_CONFIG_H
27
28 extern "C" {
29 #include <X11/Xatom.h>
30 #include <X11/keysym.h>
31
32 #ifdef XINERAMA
33 # include <X11/Xlib.h>
34 # include <X11/extensions/Xinerama.h>
35 #endif // XINERAMA
36
37 #ifdef HAVE_STDLIB_H
38 # include <stdlib.h>
39 #endif // HAVE_STDLIB_H
40
41 #ifdef HAVE_STRING_H
42 # include <string.h>
43 #endif // HAVE_STRING_H
44
45 #ifdef HAVE_CTYPE_H
46 # include <ctype.h>
47 #endif // HAVE_CTYPE_H
48
49 #ifdef HAVE_UNISTD_H
50 # include <sys/types.h>
51 # include <unistd.h>
52 #endif // HAVE_UNISTD_H
53
54 #ifdef HAVE_DIRENT_H
55 # include <dirent.h>
56 #endif // HAVE_DIRENT_H
57
58 #ifdef HAVE_LOCALE_H
59 # include <locale.h>
60 #endif // HAVE_LOCALE_H
61
62 #ifdef HAVE_SYS_STAT_H
63 # include <sys/stat.h>
64 #endif // HAVE_SYS_STAT_H
65
66 #ifdef HAVE_STDARG_H
67 # include <stdarg.h>
68 #endif // HAVE_STDARG_H
69 }
70
71 #include <assert.h>
72
73 #include <algorithm>
74 #include <functional>
75 #include <string>
76 using std::string;
77
78 #include "i18n.hh"
79 #include "blackbox.hh"
80 #include "Clientmenu.hh"
81 #include "Font.hh"
82 #include "GCCache.hh"
83 #include "Iconmenu.hh"
84 #include "Image.hh"
85 #include "Screen.hh"
86 #include "Slit.hh"
87 #include "Rootmenu.hh"
88 #include "Toolbar.hh"
89 #include "Util.hh"
90 #include "Window.hh"
91 #include "Workspace.hh"
92 #include "Workspacemenu.hh"
93 #include "Util.hh"
94 #include "XAtom.hh"
95
96 #ifndef FONT_ELEMENT_SIZE
97 #define FONT_ELEMENT_SIZE 50
98 #endif // FONT_ELEMENT_SIZE
99
100
101 static bool running = True;
102
103 static int anotherWMRunning(Display *display, XErrorEvent *) {
104 fprintf(stderr, i18n(ScreenSet, ScreenAnotherWMRunning,
105 "BScreen::BScreen: an error occured while querying the X server.\n"
106 " another window manager already running on display %s.\n"),
107 DisplayString(display));
108
109 running = False;
110
111 return(-1);
112 }
113
114
115 BScreen::BScreen(Blackbox *bb, unsigned int scrn) : ScreenInfo(bb, scrn) {
116 blackbox = bb;
117 screenstr = "session.screen" + itostring(scrn) + '.';
118 config = blackbox->getConfig();
119 xatom = blackbox->getXAtom();
120
121 event_mask = ColormapChangeMask | EnterWindowMask | PropertyChangeMask |
122 SubstructureRedirectMask | ButtonPressMask | ButtonReleaseMask;
123
124 XErrorHandler old = XSetErrorHandler((XErrorHandler) anotherWMRunning);
125 XSelectInput(getBaseDisplay()->getXDisplay(), getRootWindow(), event_mask);
126 XSync(getBaseDisplay()->getXDisplay(), False);
127 XSetErrorHandler((XErrorHandler) old);
128
129 managed = running;
130 if (! managed) return;
131
132 fprintf(stderr, i18n(ScreenSet, ScreenManagingScreen,
133 "BScreen::BScreen: managing screen %d "
134 "using visual 0x%lx, depth %d\n"),
135 getScreenNumber(), XVisualIDFromVisual(getVisual()),
136 getDepth());
137
138 rootmenu = 0;
139
140 resource.mstyle.t_font = resource.mstyle.f_font = resource.tstyle.font =
141 resource.wstyle.font = (BFont *) 0;
142
143 geom_pixmap = None;
144
145 xatom->setSupported(this); // set-up netwm support
146 #ifdef HAVE_GETPID
147 xatom->setValue(getRootWindow(), XAtom::blackbox_pid, XAtom::cardinal,
148 (unsigned long) getpid());
149 #endif // HAVE_GETPID
150 unsigned long geometry[] = { getWidth(),
151 getHeight()};
152 xatom->setValue(getRootWindow(), XAtom::net_desktop_geometry,
153 XAtom::cardinal, geometry, 2);
154 unsigned long viewport[] = {0,0};
155 xatom->setValue(getRootWindow(), XAtom::net_desktop_viewport,
156 XAtom::cardinal, viewport, 2);
157
158
159 XDefineCursor(blackbox->getXDisplay(), getRootWindow(),
160 blackbox->getSessionCursor());
161
162 updateAvailableArea();
163
164 image_control =
165 new BImageControl(blackbox, this, True, blackbox->getColorsPerChannel(),
166 blackbox->getCacheLife(), blackbox->getCacheMax());
167 image_control->installRootColormap();
168 root_colormap_installed = True;
169
170 load_rc();
171 LoadStyle();
172
173 XGCValues gcv;
174 gcv.foreground = WhitePixel(blackbox->getXDisplay(), getScreenNumber())
175 ^ BlackPixel(blackbox->getXDisplay(), getScreenNumber());
176 gcv.function = GXxor;
177 gcv.subwindow_mode = IncludeInferiors;
178 opGC = XCreateGC(blackbox->getXDisplay(), getRootWindow(),
179 GCForeground | GCFunction | GCSubwindowMode, &gcv);
180
181 const char *s = i18n(ScreenSet, ScreenPositionLength,
182 "0: 0000 x 0: 0000");
183 geom_w = resource.wstyle.font->measureString(s) + resource.bevel_width * 2;
184 geom_h = resource.wstyle.font->height() + resource.bevel_width * 2;
185
186 XSetWindowAttributes attrib;
187 unsigned long mask = CWBorderPixel | CWColormap | CWSaveUnder;
188 attrib.border_pixel = getBorderColor()->pixel();
189 attrib.colormap = getColormap();
190 attrib.save_under = True;
191
192 geom_window = XCreateWindow(blackbox->getXDisplay(), getRootWindow(),
193 0, 0, geom_w, geom_h, resource.border_width,
194 getDepth(), InputOutput, getVisual(),
195 mask, &attrib);
196 geom_visible = False;
197
198 BTexture* texture = &(resource.wstyle.l_focus);
199 geom_pixmap = texture->render(geom_w, geom_h, geom_pixmap);
200 if (geom_pixmap == ParentRelative) {
201 texture = &(resource.wstyle.t_focus);
202 geom_pixmap = texture->render(geom_w, geom_h, geom_pixmap);
203 }
204 if (! geom_pixmap)
205 XSetWindowBackground(blackbox->getXDisplay(), geom_window,
206 texture->color().pixel());
207 else
208 XSetWindowBackgroundPixmap(blackbox->getXDisplay(),
209 geom_window, geom_pixmap);
210
211 workspacemenu = new Workspacemenu(this);
212 iconmenu = new Iconmenu(this);
213 configmenu = new Configmenu(this);
214
215 if (resource.workspaces > 0) {
216 for (unsigned int i = 0; i < resource.workspaces; ++i) {
217 Workspace *wkspc = new Workspace(this, workspacesList.size());
218 workspacesList.push_back(wkspc);
219 workspacemenu->insertWorkspace(wkspc);
220 workspacemenu->update();
221
222 }
223 } else {
224 Workspace *wkspc = new Workspace(this, workspacesList.size());
225 workspacesList.push_back(wkspc);
226 workspacemenu->insertWorkspace(wkspc);
227 workspacemenu->update();
228 }
229 saveWorkspaceNames();
230
231 updateNetizenWorkspaceCount();
232
233 workspacemenu->insert(i18n(IconSet, IconIcons, "Icons"), iconmenu);
234 workspacemenu->update();
235
236 current_workspace = workspacesList.front();
237
238 xatom->setValue(getRootWindow(), XAtom::net_current_desktop,
239 XAtom::cardinal, 0); //first workspace
240
241 workspacemenu->setItemSelected(2, True);
242
243 toolbar = new Toolbar(this);
244
245 slit = new Slit(this);
246
247 InitMenu();
248
249 raiseWindows(0, 0); // this also initializes the empty stacking list
250 rootmenu->update();
251
252 updateClientList(); // initialize the client lists, which will be empty
253 updateAvailableArea();
254
255 changeWorkspaceID(0);
256
257 unsigned int i, j, nchild;
258 Window r, p, *children;
259 XQueryTree(blackbox->getXDisplay(), getRootWindow(), &r, &p,
260 &children, &nchild);
261
262 // preen the window list of all icon windows... for better dockapp support
263 for (i = 0; i < nchild; i++) {
264 if (children[i] == None) continue;
265
266 XWMHints *wmhints = XGetWMHints(blackbox->getXDisplay(),
267 children[i]);
268
269 if (wmhints) {
270 if ((wmhints->flags & IconWindowHint) &&
271 (wmhints->icon_window != children[i])) {
272 for (j = 0; j < nchild; j++) {
273 if (children[j] == wmhints->icon_window) {
274 children[j] = None;
275 break;
276 }
277 }
278 }
279
280 XFree(wmhints);
281 }
282 }
283
284 // manage shown windows
285 for (i = 0; i < nchild; ++i) {
286 if (children[i] == None || ! blackbox->validateWindow(children[i]))
287 continue;
288
289 XWindowAttributes attrib;
290 if (XGetWindowAttributes(blackbox->getXDisplay(), children[i], &attrib)) {
291 if (attrib.override_redirect) continue;
292
293 if (attrib.map_state != IsUnmapped) {
294 manageWindow(children[i]);
295 }
296 }
297 }
298
299 XFree(children);
300
301 // call this again just in case a window we found updates the Strut list
302 updateAvailableArea();
303 }
304
305
306 BScreen::~BScreen(void) {
307 if (! managed) return;
308
309 if (geom_pixmap != None)
310 image_control->removeImage(geom_pixmap);
311
312 if (geom_window != None)
313 XDestroyWindow(blackbox->getXDisplay(), geom_window);
314
315 std::for_each(workspacesList.begin(), workspacesList.end(),
316 PointerAssassin());
317
318 std::for_each(iconList.begin(), iconList.end(), PointerAssassin());
319
320 std::for_each(netizenList.begin(), netizenList.end(), PointerAssassin());
321
322 while (! systrayWindowList.empty())
323 removeSystrayWindow(systrayWindowList[0]);
324
325 delete rootmenu;
326 delete workspacemenu;
327 delete iconmenu;
328 delete configmenu;
329 delete slit;
330 delete toolbar;
331 delete image_control;
332
333 if (resource.wstyle.font)
334 delete resource.wstyle.font;
335 if (resource.mstyle.t_font)
336 delete resource.mstyle.t_font;
337 if (resource.mstyle.f_font)
338 delete resource.mstyle.f_font;
339 if (resource.tstyle.font)
340 delete resource.tstyle.font;
341
342 #ifdef BITMAPBUTTONS
343 if (resource.wstyle.close_button.mask != None)
344 XFreePixmap(blackbox->getXDisplay(), resource.wstyle.close_button.mask);
345 if (resource.wstyle.max_button.mask != None)
346 XFreePixmap(blackbox->getXDisplay(), resource.wstyle.max_button.mask);
347 if (resource.wstyle.icon_button.mask != None)
348 XFreePixmap(blackbox->getXDisplay(), resource.wstyle.icon_button.mask);
349 if (resource.wstyle.stick_button.mask != None)
350 XFreePixmap(blackbox->getXDisplay(), resource.wstyle.stick_button.mask);
351
352 if (resource.tstyle.left_button.mask != None)
353 XFreePixmap(blackbox->getXDisplay(), resource.tstyle.left_button.mask);
354 if (resource.tstyle.right_button.mask != None)
355 XFreePixmap(blackbox->getXDisplay(), resource.tstyle.right_button.mask);
356
357 if (resource.mstyle.bullet_image.mask != None)
358 XFreePixmap(blackbox->getXDisplay(), resource.mstyle.bullet_image.mask);
359 if (resource.mstyle.tick_image.mask != None)
360 XFreePixmap(blackbox->getXDisplay(), resource.mstyle.tick_image.mask);
361
362 resource.wstyle.max_button.mask = resource.wstyle.close_button.mask =
363 resource.wstyle.icon_button.mask =
364 resource.wstyle.stick_button.mask = None;
365 resource.tstyle.left_button.mask = resource.tstyle.right_button.mask = None;
366 resource.mstyle.bullet_image.mask = resource.mstyle.tick_image.mask = None;
367 #endif // BITMAPBUTTONS
368
369 XFreeGC(blackbox->getXDisplay(), opGC);
370 }
371
372
373 void BScreen::saveSloppyFocus(bool s) {
374 resource.sloppy_focus = s;
375
376 string fmodel;
377 if (resource.sloppy_focus) {
378 fmodel = "SloppyFocus";
379 if (resource.auto_raise) fmodel += " AutoRaise";
380 if (resource.click_raise) fmodel += " ClickRaise";
381 } else {
382 fmodel = "ClickToFocus";
383 }
384 config->setValue(screenstr + "focusModel", fmodel);
385 }
386
387
388 void BScreen::saveAutoRaise(bool a) {
389 resource.auto_raise = a;
390 saveSloppyFocus(resource.sloppy_focus);
391 }
392
393
394 void BScreen::saveClickRaise(bool c) {
395 resource.click_raise = c;
396 saveSloppyFocus(resource.sloppy_focus);
397 }
398
399
400 void BScreen::saveImageDither(bool d) {
401 image_control->setDither(d);
402 config->setValue(screenstr + "imageDither", doImageDither());
403 }
404
405
406 void BScreen::saveOpaqueMove(bool o) {
407 resource.opaque_move = o;
408 config->setValue(screenstr + "opaqueMove", resource.opaque_move);
409 }
410
411
412 void BScreen::saveFullMax(bool f) {
413 resource.full_max = f;
414 config->setValue(screenstr + "fullMaximization", resource.full_max);
415 }
416
417
418 void BScreen::saveFocusNew(bool f) {
419 resource.focus_new = f;
420 config->setValue(screenstr + "focusNewWindows", resource.focus_new);
421 }
422
423
424 void BScreen::saveFocusLast(bool f) {
425 resource.focus_last = f;
426 config->setValue(screenstr + "focusLastWindow", resource.focus_last);
427 }
428
429
430 void BScreen::saveAAFonts(bool f) {
431 resource.aa_fonts = f;
432 config->setValue(screenstr + "antialiasFonts", resource.aa_fonts);
433 reconfigure();
434 }
435
436
437 void BScreen::saveShadowFonts(bool f) {
438 resource.shadow_fonts = f;
439 config->setValue(screenstr + "dropShadowFonts", resource.shadow_fonts);
440 reconfigure();
441 }
442
443
444 void BScreen::saveHideToolbar(bool h) {
445 resource.hide_toolbar = h;
446 if (resource.hide_toolbar)
447 toolbar->unmapToolbar();
448 else
449 toolbar->mapToolbar();
450 config->setValue(screenstr + "hideToolbar", resource.hide_toolbar);
451 }
452
453
454 void BScreen::saveWindowToEdgeSnap(int s) {
455 resource.snap_to_edges = s;
456
457 const char *snap;
458 switch (resource.snap_to_edges) {
459 case WindowNoSnap: snap = "NoSnap"; break;
460 case WindowResistance: snap = "Resistance"; break;
461 case WindowSnap: default: snap = "Snap"; break;
462 }
463 config->setValue(screenstr + "windowToEdgeSnap", snap);
464 }
465
466
467 void BScreen::saveWindowToWindowSnap(int s) {
468 resource.snap_to_windows = s;
469
470 const char *snap;
471 switch (resource.snap_to_windows) {
472 case WindowNoSnap: snap = "NoSnap"; break;
473 case WindowResistance: snap = "Resistance"; break;
474 case WindowSnap: default: snap = "Snap"; break;
475 }
476 config->setValue(screenstr + "windowToWindowSnap", snap);
477 }
478
479
480 void BScreen::saveResizeZones(unsigned int z) {
481 resource.resize_zones = z;
482 config->setValue(screenstr + "resizeZones", resource.resize_zones);
483 }
484
485
486 void BScreen::saveWindowCornerSnap(bool s) {
487 resource.window_corner_snap = s;
488 config->setValue(screenstr + "windowCornerSnap",
489 resource.window_corner_snap);
490 }
491
492
493 void BScreen::saveWorkspaces(unsigned int w) {
494 resource.workspaces = w;
495 config->setValue(screenstr + "workspaces", resource.workspaces);
496 }
497
498
499 void BScreen::savePlacementPolicy(int p) {
500 resource.placement_policy = p;
501 const char *placement;
502 switch (resource.placement_policy) {
503 case CascadePlacement: placement = "CascadePlacement"; break;
504 case UnderMousePlacement: placement = "UnderMousePlacement"; break;
505 case ClickMousePlacement: placement = "ClickMousePlacement"; break;
506 case ColSmartPlacement: placement = "ColSmartPlacement"; break;
507 case RowSmartPlacement: default: placement = "RowSmartPlacement"; break;
508 }
509 config->setValue(screenstr + "windowPlacement", placement);
510 }
511
512
513 void BScreen::saveResistanceSize(int s) {
514 resource.resistance_size = s;
515 config->setValue(screenstr + "resistanceSize",
516 resource.resistance_size);
517 }
518
519
520 void BScreen::saveSnapThreshold(int t) {
521 resource.snap_threshold = t;
522 config->setValue(screenstr + "edgeSnapThreshold",
523 resource.snap_threshold);
524 }
525
526
527 void BScreen::saveSnapOffset(int t) {
528 resource.snap_offset = t;
529 config->setValue(screenstr + "edgeSnapOffset",
530 resource.snap_offset);
531 }
532
533
534 void BScreen::saveRowPlacementDirection(int d) {
535 resource.row_direction = d;
536 config->setValue(screenstr + "rowPlacementDirection",
537 resource.row_direction == LeftRight ?
538 "LeftToRight" : "RightToLeft");
539 }
540
541
542 void BScreen::saveColPlacementDirection(int d) {
543 resource.col_direction = d;
544 config->setValue(screenstr + "colPlacementDirection",
545 resource.col_direction == TopBottom ?
546 "TopToBottom" : "BottomToTop");
547 }
548
549
550 #ifdef HAVE_STRFTIME
551 void BScreen::saveStrftimeFormat(const std::string& format) {
552 resource.strftime_format = format;
553 config->setValue(screenstr + "strftimeFormat", resource.strftime_format);
554 }
555
556 #else // !HAVE_STRFTIME
557
558 void BScreen::saveDateFormat(int f) {
559 resource.date_format = f;
560 config->setValue(screenstr + "dateFormat",
561 resource.date_format == B_EuropeanDate ?
562 "European" : "American");
563 }
564
565
566 void BScreen::saveClock24Hour(bool c) {
567 resource.clock24hour = c;
568 config->setValue(screenstr + "clockFormat", resource.clock24hour ? 24 : 12);
569 }
570 #endif // HAVE_STRFTIME
571
572
573 void BScreen::saveWorkspaceNames() {
574 string names;
575
576 for (unsigned int i = 0; i < workspacesList.size(); ++i) {
577 names += workspacesList[i]->getName();
578 if (i < workspacesList.size() - 1)
579 names += ',';
580 }
581
582 config->setValue(screenstr + "workspaceNames", names);
583 }
584
585
586 void BScreen::savePlaceIgnoreShaded(bool i) {
587 resource.ignore_shaded = i;
588 config->setValue(screenstr + "placementIgnoreShaded",
589 resource.ignore_shaded);
590 }
591
592
593 void BScreen::savePlaceIgnoreMaximized(bool i) {
594 resource.ignore_maximized = i;
595 config->setValue(screenstr + "placementIgnoreMaximized",
596 resource.ignore_maximized);
597 }
598
599
600 void BScreen::saveAllowScrollLock(bool a) {
601 resource.allow_scroll_lock = a;
602 config->setValue(screenstr + "disableBindingsWithScrollLock",
603 resource.allow_scroll_lock);
604 }
605
606
607 void BScreen::saveWorkspaceWarping(bool w) {
608 resource.workspace_warping = w;
609 config->setValue(screenstr + "workspaceWarping",
610 resource.workspace_warping);
611 }
612
613
614 void BScreen::saveRootScrollDirection(int d) {
615 resource.root_scroll = d;
616 const char *dir;
617 switch (resource.root_scroll) {
618 case NoScroll: dir = "None"; break;
619 case ReverseScroll: dir = "Reverse"; break;
620 case NormalScroll: default: dir = "Normal"; break;
621 }
622 config->setValue(screenstr + "rootScrollDirection", dir);
623 }
624
625
626 void BScreen::saveRootMenuButton(unsigned int b) {
627 resource.root_menu_button = b;
628 const char *but;
629 switch (resource.root_menu_button) {
630 case 0: but = "None"; break;
631 case 1: but = "Left"; break;
632 case 2: but = "Middle"; break;
633 case 3: default: but = "Right"; break;
634 }
635 config->setValue(screenstr + "rootMenuButton", but);
636 }
637
638
639 void BScreen::saveWorkspaceMenuButton(unsigned int b) {
640 resource.workspace_menu_button = b;
641 const char *but;
642 switch (resource.workspace_menu_button) {
643 case 0: but = "None"; break;
644 case 1: but = "Left"; break;
645 case 2: default: but = "Middle"; break;
646 case 3: but = "Right"; break;
647 }
648 config->setValue(screenstr + "workspaceMenuButton", but);
649 }
650
651
652 void BScreen::save_rc(void) {
653 saveSloppyFocus(resource.sloppy_focus);
654 saveAutoRaise(resource.auto_raise);
655 saveImageDither(doImageDither());
656 saveShadowFonts(resource.shadow_fonts);
657 saveAAFonts(resource.aa_fonts);
658 saveResizeZones(resource.resize_zones);
659 saveOpaqueMove(resource.opaque_move);
660 saveFullMax(resource.full_max);
661 saveFocusNew(resource.focus_new);
662 saveFocusLast(resource.focus_last);
663 saveHideToolbar(resource.hide_toolbar);
664 saveWindowToWindowSnap(resource.snap_to_windows);
665 saveWindowToEdgeSnap(resource.snap_to_edges);
666 saveWindowCornerSnap(resource.window_corner_snap);
667 saveWorkspaces(resource.workspaces);
668 savePlacementPolicy(resource.placement_policy);
669 saveSnapThreshold(resource.snap_threshold);
670 saveSnapOffset(resource.snap_offset);
671 saveResistanceSize(resource.resistance_size);
672 saveRowPlacementDirection(resource.row_direction);
673 saveColPlacementDirection(resource.col_direction);
674 #ifdef HAVE_STRFTIME
675 saveStrftimeFormat(resource.strftime_format);
676 #else // !HAVE_STRFTIME
677 saveDateFormat(resource.date_format);
678 savwClock24Hour(resource.clock24hour);
679 #endif // HAVE_STRFTIME
680 savePlaceIgnoreShaded(resource.ignore_shaded);
681 savePlaceIgnoreMaximized(resource.ignore_maximized);
682 saveAllowScrollLock(resource.allow_scroll_lock);
683 saveWorkspaceWarping(resource.workspace_warping);
684 saveRootScrollDirection(resource.root_scroll);
685 saveRootMenuButton(resource.root_menu_button);
686 saveWorkspaceMenuButton(resource.workspace_menu_button);
687
688 toolbar->save_rc();
689 slit->save_rc();
690 }
691
692
693 void BScreen::load_rc(void) {
694 std::string s;
695 bool b;
696
697 if (! config->getValue(screenstr + "fullMaximization", resource.full_max))
698 resource.full_max = false;
699
700 if (! config->getValue(screenstr + "focusNewWindows", resource.focus_new))
701 resource.focus_new = false;
702
703 if (! config->getValue(screenstr + "focusLastWindow", resource.focus_last))
704 resource.focus_last = false;
705
706 if (! config->getValue(screenstr + "workspaces", resource.workspaces))
707 resource.workspaces = 1;
708
709 if (! config->getValue(screenstr + "opaqueMove", resource.opaque_move))
710 resource.opaque_move = false;
711
712 if (! config->getValue(screenstr + "antialiasFonts", resource.aa_fonts))
713 resource.aa_fonts = true;
714
715 if (! resource.aa_fonts ||
716 ! config->getValue(screenstr + "dropShadowFonts", resource.shadow_fonts))
717 resource.shadow_fonts = false;
718
719 if (! config->getValue(screenstr + "resizeZones", resource.resize_zones) ||
720 (resource.resize_zones != 1 && resource.resize_zones != 2 &&
721 resource.resize_zones != 4))
722 resource.resize_zones = 4;
723
724 if (! config->getValue(screenstr + "hideToolbar", resource.hide_toolbar))
725 resource.hide_toolbar = false;
726
727 resource.snap_to_windows = WindowResistance;
728 if (config->getValue(screenstr + "windowToWindowSnap", s)) {
729 if (s == "NoSnap")
730 resource.snap_to_windows = WindowNoSnap;
731 else if (s == "Snap")
732 resource.snap_to_windows = WindowSnap;
733 }
734
735 resource.snap_to_edges = WindowResistance;
736 if (config->getValue(screenstr + "windowToEdgeSnap", s)) {
737 if (s == "NoSnap")
738 resource.snap_to_edges = WindowNoSnap;
739 else if (s == "Snap")
740 resource.snap_to_edges = WindowSnap;
741 }
742
743 if (! config->getValue(screenstr + "windowCornerSnap",
744 resource.window_corner_snap))
745 resource.window_corner_snap = true;
746
747 if (! config->getValue(screenstr + "imageDither", b))
748 b = true;
749 image_control->setDither(b);
750
751 if (! config->getValue(screenstr + "edgeSnapOffset",
752 resource.snap_offset))
753 resource.snap_offset = 0;
754 if (resource.snap_offset > 50) // sanity check, setting this huge would
755 resource.snap_offset = 50; // seriously suck.
756
757 if (! config->getValue(screenstr + "edgeSnapThreshold",
758 resource.snap_threshold))
759 resource.snap_threshold = 4;
760
761 if (! config->getValue(screenstr + "resistanceSize",
762 resource.resistance_size))
763 resource.resistance_size = 18;
764
765 if (config->getValue(screenstr + "rowPlacementDirection", s) &&
766 s == "RightToLeft")
767 resource.row_direction = RightLeft;
768 else
769 resource.row_direction = LeftRight;
770
771 if (config->getValue(screenstr + "colPlacementDirection", s) &&
772 s == "BottomToTop")
773 resource.col_direction = BottomTop;
774 else
775 resource.col_direction = TopBottom;
776
777 if (config->getValue(screenstr + "workspaceNames", s)) {
778 XAtom::StringVect workspaceNames;
779
780 string::const_iterator it = s.begin(), end = s.end();
781 while(1) {
782 string::const_iterator tmp = it; // current string.begin()
783 it = std::find(tmp, end, ','); // look for comma between tmp and end
784 workspaceNames.push_back(string(tmp, it)); // s[tmp:it]
785 if (it == end)
786 break;
787 ++it;
788 }
789
790 xatom->setValue(getRootWindow(), XAtom::net_desktop_names, XAtom::utf8,
791 workspaceNames);
792 }
793
794 resource.sloppy_focus = true;
795 resource.auto_raise = false;
796 resource.click_raise = false;
797 if (config->getValue(screenstr + "focusModel", s)) {
798 if (s.find("ClickToFocus") != string::npos) {
799 resource.sloppy_focus = false;
800 } else {
801 // must be sloppy
802 if (s.find("AutoRaise") != string::npos)
803 resource.auto_raise = true;
804 if (s.find("ClickRaise") != string::npos)
805 resource.click_raise = true;
806 }
807 }
808
809 if (config->getValue(screenstr + "windowPlacement", s)) {
810 if (s == "CascadePlacement")
811 resource.placement_policy = CascadePlacement;
812 else if (s == "UnderMousePlacement")
813 resource.placement_policy = UnderMousePlacement;
814 else if (s == "ClickMousePlacement")
815 resource.placement_policy = ClickMousePlacement;
816 else if (s == "ColSmartPlacement")
817 resource.placement_policy = ColSmartPlacement;
818 else //if (s == "RowSmartPlacement")
819 resource.placement_policy = RowSmartPlacement;
820 } else
821 resource.placement_policy = RowSmartPlacement;
822
823 #ifdef HAVE_STRFTIME
824 if (! config->getValue(screenstr + "strftimeFormat",
825 resource.strftime_format))
826 resource.strftime_format = "%I:%M %p";
827 #else // !HAVE_STRFTIME
828 long l;
829
830 if (config->getValue(screenstr + "dateFormat", s) && s == "European")
831 resource.date_format = B_EuropeanDate;
832 else
833 resource.date_format = B_AmericanDate;
834
835 if (! config->getValue(screenstr + "clockFormat", l))
836 l = 12;
837 resource.clock24hour = l == 24;
838 #endif // HAVE_STRFTIME
839
840 if (! config->getValue(screenstr + "placementIgnoreShaded",
841 resource.ignore_shaded))
842 resource.ignore_shaded = true;
843
844 if (! config->getValue(screenstr + "placementIgnoreMaximized",
845 resource.ignore_maximized))
846 resource.ignore_maximized = true;
847
848 if (! config->getValue(screenstr + "disableBindingsWithScrollLock",
849 resource.allow_scroll_lock))
850 resource.allow_scroll_lock = false;
851
852 if (! config->getValue(screenstr + "workspaceWarping",
853 resource.workspace_warping))
854 resource.workspace_warping = false;
855
856 resource.root_scroll = NormalScroll;
857 if (config->getValue(screenstr + "rootScrollDirection", s)) {
858 if (s == "None")
859 resource.root_scroll = NoScroll;
860 else if (s == "Reverse")
861 resource.root_scroll = ReverseScroll;
862 }
863
864 resource.root_menu_button = 3;
865 if (config->getValue(screenstr + "rootMenuButton", s)) {
866 if (s == "None")
867 resource.root_menu_button = 0;
868 else if (s == "Left")
869 resource.root_menu_button = 1;
870 else if (s == "Middle")
871 resource.root_menu_button = 2;
872 }
873
874 resource.workspace_menu_button = 2;
875 if (config->getValue(screenstr + "workspaceMenuButton", s)) {
876 if (s == "None")
877 resource.workspace_menu_button = 0;
878 else if (s == "Left")
879 resource.workspace_menu_button = 1;
880 else if (s == "Right")
881 resource.workspace_menu_button = 3;
882 }
883 // cant both be the same
884 if (resource.workspace_menu_button == resource.root_menu_button)
885 resource.workspace_menu_button = 0;
886 }
887
888
889 void BScreen::changeWorkspaceCount(unsigned int new_count) {
890 assert(new_count > 0);
891
892 if (new_count < workspacesList.size()) {
893 // shrink
894 for (unsigned int i = workspacesList.size(); i > new_count; --i)
895 removeLastWorkspace();
896 // removeLast already sets the current workspace to the
897 // last available one.
898 } else if (new_count > workspacesList.size()) {
899 // grow
900 for(unsigned int i = workspacesList.size(); i < new_count; ++i)
901 addWorkspace();
902 }
903 }
904
905
906 void BScreen::reconfigure(void) {
907 // don't reconfigure while saving the initial rc file, it's a waste and it
908 // breaks somethings (workspace names)
909 if (blackbox->isStartup()) return;
910
911 load_rc();
912 toolbar->load_rc();
913 slit->load_rc();
914 LoadStyle();
915
916 // we need to do this explicitly, because just loading this value from the rc
917 // does nothing
918 changeWorkspaceCount(resource.workspaces);
919
920 XGCValues gcv;
921 gcv.foreground = WhitePixel(blackbox->getXDisplay(),
922 getScreenNumber());
923 gcv.function = GXinvert;
924 gcv.subwindow_mode = IncludeInferiors;
925 XChangeGC(blackbox->getXDisplay(), opGC,
926 GCForeground | GCFunction | GCSubwindowMode, &gcv);
927
928 const char *s = i18n(ScreenSet, ScreenPositionLength,
929 "0: 0000 x 0: 0000");
930
931 geom_w = resource.wstyle.font->measureString(s) + resource.bevel_width * 2;
932 geom_h = resource.wstyle.font->height() + resource.bevel_width * 2;
933
934 BTexture* texture = &(resource.wstyle.l_focus);
935 geom_pixmap = texture->render(geom_w, geom_h, geom_pixmap);
936 if (geom_pixmap == ParentRelative) {
937 texture = &(resource.wstyle.t_focus);
938 geom_pixmap = texture->render(geom_w, geom_h, geom_pixmap);
939 }
940 if (! geom_pixmap)
941 XSetWindowBackground(blackbox->getXDisplay(), geom_window,
942 texture->color().pixel());
943 else
944 XSetWindowBackgroundPixmap(blackbox->getXDisplay(),
945 geom_window, geom_pixmap);
946
947 XSetWindowBorderWidth(blackbox->getXDisplay(), geom_window,
948 resource.border_width);
949 XSetWindowBorder(blackbox->getXDisplay(), geom_window,
950 resource.border_color.pixel());
951
952 workspacemenu->reconfigure();
953 iconmenu->reconfigure();
954
955 typedef std::vector<int> SubList;
956 SubList remember_subs;
957
958 // save the current open menus
959 Basemenu *menu = rootmenu;
960 int submenu;
961 while ((submenu = menu->getCurrentSubmenu()) >= 0) {
962 remember_subs.push_back(submenu);
963 menu = menu->find(submenu)->submenu();
964 assert(menu);
965 }
966
967 InitMenu();
968 raiseWindows(0, 0);
969 rootmenu->reconfigure();
970
971 // reopen the saved menus
972 menu = rootmenu;
973 const SubList::iterator subs_end = remember_subs.end();
974 for (SubList::iterator it = remember_subs.begin(); it != subs_end; ++it) {
975 menu->drawSubmenu(*it);
976 menu = menu->find(*it)->submenu();
977 if (! menu)
978 break;
979 }
980
981 configmenu->reconfigure();
982
983 toolbar->reconfigure();
984
985 slit->reconfigure();
986
987 std::for_each(workspacesList.begin(), workspacesList.end(),
988 std::mem_fun(&Workspace::reconfigure));
989
990 BlackboxWindowList::iterator iit = iconList.begin();
991 for (; iit != iconList.end(); ++iit) {
992 BlackboxWindow *bw = *iit;
993 if (bw->validateClient())
994 bw->reconfigure();
995 }
996
997 image_control->timeout();
998 }
999
1000
1001 void BScreen::rereadMenu(void) {
1002 InitMenu();
1003 raiseWindows(0, 0);
1004
1005 rootmenu->reconfigure();
1006 }
1007
1008
1009 void BScreen::LoadStyle(void) {
1010 Configuration style(False);
1011
1012 const char *sfile = blackbox->getStyleFilename();
1013 if (sfile != NULL) {
1014 style.setFile(sfile);
1015 if (! style.load()) {
1016 style.setFile(DEFAULTSTYLE);
1017 if (! style.load())
1018 style.create(); // hardcoded default values will be used.
1019 }
1020 }
1021
1022 // merge in the rc file
1023 style.merge(config->file(), True);
1024
1025 string s;
1026
1027 // load fonts/fontsets
1028 if (resource.wstyle.font)
1029 delete resource.wstyle.font;
1030 if (resource.tstyle.font)
1031 delete resource.tstyle.font;
1032 if (resource.mstyle.f_font)
1033 delete resource.mstyle.f_font;
1034 if (resource.mstyle.t_font)
1035 delete resource.mstyle.t_font;
1036 resource.wstyle.font = resource.tstyle.font = resource.mstyle.f_font =
1037 resource.mstyle.t_font = (BFont *) 0;
1038
1039 resource.wstyle.font = readDatabaseFont("window.", style);
1040 resource.tstyle.font = readDatabaseFont("toolbar.", style);
1041 resource.mstyle.t_font = readDatabaseFont("menu.title.", style);
1042 resource.mstyle.f_font = readDatabaseFont("menu.frame.", style);
1043
1044 // load window config
1045 resource.wstyle.t_focus =
1046 readDatabaseTexture("window.title.focus", "white", style);
1047 resource.wstyle.t_unfocus =
1048 readDatabaseTexture("window.title.unfocus", "black", style);
1049 resource.wstyle.l_focus =
1050 readDatabaseTexture("window.label.focus", "white", style);
1051 resource.wstyle.l_unfocus =
1052 readDatabaseTexture("window.label.unfocus", "black", style);
1053 resource.wstyle.h_focus =
1054 readDatabaseTexture("window.handle.focus", "white", style);
1055 resource.wstyle.h_unfocus =
1056 readDatabaseTexture("window.handle.unfocus", "black", style);
1057 resource.wstyle.g_focus =
1058 readDatabaseTexture("window.grip.focus", "white", style);
1059 resource.wstyle.g_unfocus =
1060 readDatabaseTexture("window.grip.unfocus", "black", style);
1061 resource.wstyle.b_focus =
1062 readDatabaseTexture("window.button.focus", "white", style);
1063 resource.wstyle.b_unfocus =
1064 readDatabaseTexture("window.button.unfocus", "black", style);
1065 resource.wstyle.b_pressed =
1066 readDatabaseTexture("window.button.pressed", "black", style);
1067
1068 //if neither of these can be found, we will use the previous resource
1069 resource.wstyle.b_pressed_focus =
1070 readDatabaseTexture("window.button.pressed.focus", "black", style, true);
1071 resource.wstyle.b_pressed_unfocus =
1072 readDatabaseTexture("window.button.pressed.unfocus", "black", style, true);
1073
1074 #ifdef BITMAPBUTTONS
1075 if (resource.wstyle.close_button.mask != None)
1076 XFreePixmap(blackbox->getXDisplay(), resource.wstyle.close_button.mask);
1077 if (resource.wstyle.max_button.mask != None)
1078 XFreePixmap(blackbox->getXDisplay(), resource.wstyle.max_button.mask);
1079 if (resource.wstyle.icon_button.mask != None)
1080 XFreePixmap(blackbox->getXDisplay(), resource.wstyle.icon_button.mask);
1081 if (resource.wstyle.stick_button.mask != None)
1082 XFreePixmap(blackbox->getXDisplay(), resource.wstyle.stick_button.mask);
1083
1084 resource.wstyle.close_button.mask = resource.wstyle.max_button.mask =
1085 resource.wstyle.icon_button.mask =
1086 resource.wstyle.icon_button.mask = None;
1087
1088 readDatabaseMask("window.button.close.mask", resource.wstyle.close_button,
1089 style);
1090 readDatabaseMask("window.button.max.mask", resource.wstyle.max_button,
1091 style);
1092 readDatabaseMask("window.button.icon.mask", resource.wstyle.icon_button,
1093 style);
1094 readDatabaseMask("window.button.stick.mask", resource.wstyle.stick_button,
1095 style);
1096 #endif // BITMAPBUTTONS
1097
1098 // we create the window.frame texture by hand because it exists only to
1099 // make the code cleaner and is not actually used for display
1100 BColor color = readDatabaseColor("window.frame.focusColor", "white", style);
1101 resource.wstyle.f_focus = BTexture("solid flat", getBaseDisplay(),
1102 getScreenNumber(), image_control);
1103 resource.wstyle.f_focus.setColor(color);
1104
1105 color = readDatabaseColor("window.frame.unfocusColor", "white", style);
1106 resource.wstyle.f_unfocus = BTexture("solid flat", getBaseDisplay(),
1107 getScreenNumber(), image_control);
1108 resource.wstyle.f_unfocus.setColor(color);
1109
1110 resource.wstyle.l_text_focus =
1111 readDatabaseColor("window.label.focus.textColor", "black", style);
1112 resource.wstyle.l_text_unfocus =
1113 readDatabaseColor("window.label.unfocus.textColor", "white", style);
1114 resource.wstyle.b_pic_focus =
1115 readDatabaseColor("window.button.focus.picColor", "black", style);
1116 resource.wstyle.b_pic_unfocus =
1117 readDatabaseColor("window.button.unfocus.picColor", "white", style);
1118
1119 resource.wstyle.justify = LeftJustify;
1120 if (style.getValue("window.justify", s)) {
1121 if (s == "right" || s == "Right")
1122 resource.wstyle.justify = RightJustify;
1123 else if (s == "center" || s == "Center")
1124 resource.wstyle.justify = CenterJustify;
1125 }
1126
1127 // sanity checks
1128 if (resource.wstyle.t_focus.texture() == BTexture::Parent_Relative)
1129 resource.wstyle.t_focus = resource.wstyle.f_focus;
1130 if (resource.wstyle.t_unfocus.texture() == BTexture::Parent_Relative)
1131 resource.wstyle.t_unfocus = resource.wstyle.f_unfocus;
1132 if (resource.wstyle.h_focus.texture() == BTexture::Parent_Relative)
1133 resource.wstyle.h_focus = resource.wstyle.f_focus;
1134 if (resource.wstyle.h_unfocus.texture() == BTexture::Parent_Relative)
1135 resource.wstyle.h_unfocus = resource.wstyle.f_unfocus;
1136
1137 // load toolbar config
1138 #ifdef BITMAPBUTTONS
1139 if (resource.tstyle.left_button.mask != None)
1140 XFreePixmap(blackbox->getXDisplay(), resource.tstyle.left_button.mask);
1141 if (resource.tstyle.right_button.mask != None)
1142 XFreePixmap(blackbox->getXDisplay(), resource.tstyle.right_button.mask);
1143 #endif // BITMAPBUTTONS
1144
1145 resource.tstyle.toolbar =
1146 readDatabaseTexture("toolbar", "black", style);
1147 resource.tstyle.label =
1148 readDatabaseTexture("toolbar.label", "black", style);
1149 resource.tstyle.window =
1150 readDatabaseTexture("toolbar.windowLabel", "black", style);
1151 resource.tstyle.button =
1152 readDatabaseTexture("toolbar.button", "white", style);
1153 resource.tstyle.pressed =
1154 readDatabaseTexture("toolbar.button.pressed", "black", style);
1155 resource.tstyle.clock =
1156 readDatabaseTexture("toolbar.clock", "black", style);
1157 resource.tstyle.l_text =
1158 readDatabaseColor("toolbar.label.textColor", "white", style);
1159 resource.tstyle.w_text =
1160 readDatabaseColor("toolbar.windowLabel.textColor", "white", style);
1161 resource.tstyle.c_text =
1162 readDatabaseColor("toolbar.clock.textColor", "white", style);
1163 resource.tstyle.b_pic =
1164 readDatabaseColor("toolbar.button.picColor", "black", style);
1165
1166 #ifdef BITMAPBUTTONS
1167 readDatabaseMask("toolbar.button.left.mask", resource.tstyle.left_button,
1168 style);
1169 readDatabaseMask("toolbar.button.right.mask", resource.tstyle.right_button,
1170 style);
1171 #endif // BITMAPBUTTONS
1172
1173 resource.tstyle.justify = LeftJustify;
1174 if (style.getValue("toolbar.justify", s)) {
1175 if (s == "right" || s == "Right")
1176 resource.tstyle.justify = RightJustify;
1177 else if (s == "center" || s == "Center")
1178 resource.tstyle.justify = CenterJustify;
1179 }
1180
1181 // sanity checks
1182 if (resource.tstyle.toolbar.texture() == BTexture::Parent_Relative) {
1183 resource.tstyle.toolbar = BTexture("solid flat", getBaseDisplay(),
1184 getScreenNumber(), image_control);
1185 resource.tstyle.toolbar.setColor(BColor("black", getBaseDisplay(),
1186 getScreenNumber()));
1187 }
1188
1189 // load menu config
1190 #ifdef BITMAPBUTTONS
1191 if (resource.mstyle.bullet_image.mask != None)
1192 XFreePixmap(blackbox->getXDisplay(), resource.mstyle.bullet_image.mask);
1193 if (resource.mstyle.tick_image.mask != None)
1194 XFreePixmap(blackbox->getXDisplay(), resource.mstyle.tick_image.mask);
1195 #endif // BITMAPBUTTONS
1196
1197 resource.mstyle.title =
1198 readDatabaseTexture("menu.title", "white", style);
1199 resource.mstyle.frame =
1200 readDatabaseTexture("menu.frame", "black", style);
1201 resource.mstyle.hilite =
1202 readDatabaseTexture("menu.hilite", "white", style);
1203 resource.mstyle.t_text =
1204 readDatabaseColor("menu.title.textColor", "black", style);
1205 resource.mstyle.f_text =
1206 readDatabaseColor("menu.frame.textColor", "white", style);
1207 resource.mstyle.d_text =
1208 readDatabaseColor("menu.frame.disableColor", "black", style);
1209 resource.mstyle.h_text =
1210 readDatabaseColor("menu.hilite.textColor", "black", style);
1211
1212 #ifdef BITMAPBUTTONS
1213 readDatabaseMask("menu.arrow.mask", resource.mstyle.bullet_image, style);
1214 readDatabaseMask("menu.selected.mask", resource.mstyle.tick_image, style);
1215 #endif // BITMAPBUTTONS
1216
1217 resource.mstyle.t_justify = LeftJustify;
1218 if (style.getValue("menu.title.justify", s)) {
1219 if (s == "right" || s == "Right")
1220 resource.mstyle.t_justify = RightJustify;
1221 else if (s == "center" || s == "Center")
1222 resource.mstyle.t_justify = CenterJustify;
1223 }
1224
1225 resource.mstyle.f_justify = LeftJustify;
1226 if (style.getValue("menu.frame.justify", s)) {
1227 if (s == "right" || s == "Right")
1228 resource.mstyle.f_justify = RightJustify;
1229 else if (s == "center" || s == "Center")
1230 resource.mstyle.f_justify = CenterJustify;
1231 }
1232
1233 resource.mstyle.bullet = Basemenu::Triangle;
1234 if (style.getValue("menu.bullet", s)) {
1235 if (s == "empty" || s == "Empty")
1236 resource.mstyle.bullet = Basemenu::Empty;
1237 else if (s == "square" || s == "Square")
1238 resource.mstyle.bullet = Basemenu::Square;
1239 else if (s == "diamond" || s == "Diamond")
1240 resource.mstyle.bullet = Basemenu::Diamond;
1241 }
1242
1243 resource.mstyle.bullet_pos = Basemenu::Left;
1244 if (style.getValue("menu.bullet.position", s)) {
1245 if (s == "right" || s == "Right")
1246 resource.mstyle.bullet_pos = Basemenu::Right;
1247 }
1248
1249 // sanity checks
1250 if (resource.mstyle.frame.texture() == BTexture::Parent_Relative) {
1251 resource.mstyle.frame = BTexture("solid flat", getBaseDisplay(),
1252 getScreenNumber(), image_control);
1253 resource.mstyle.frame.setColor(BColor("black", getBaseDisplay(),
1254 getScreenNumber()));
1255 }
1256
1257 resource.border_color =
1258 readDatabaseColor("borderColor", "black", style);
1259
1260 // load bevel, border and handle widths
1261 if (! style.getValue("handleWidth", resource.handle_width) ||
1262 resource.handle_width > (getWidth() / 2) || resource.handle_width == 0)
1263 resource.handle_width = 6;
1264
1265 if (! style.getValue("borderWidth", resource.border_width))
1266 resource.border_width = 1;
1267
1268 if (! style.getValue("bevelWidth", resource.bevel_width) ||
1269 resource.bevel_width > (getWidth() / 2) || resource.bevel_width == 0)
1270 resource.bevel_width = 3;
1271
1272 if (! style.getValue("frameWidth", resource.frame_width) ||
1273 resource.frame_width > (getWidth() / 2))
1274 resource.frame_width = resource.bevel_width;
1275
1276 if (style.getValue("rootCommand", s))
1277 bexec(s, displayString());
1278 }
1279
1280
1281 void BScreen::addIcon(BlackboxWindow *w) {
1282 if (! w) return;
1283
1284 w->setWorkspace(BSENTINEL);
1285 w->setWindowNumber(iconList.size());
1286
1287 iconList.push_back(w);
1288
1289 const char* title = w->getIconTitle();
1290 iconmenu->insert(title);
1291 iconmenu->update();
1292 }
1293
1294
1295 void BScreen::removeIcon(BlackboxWindow *w) {
1296 if (! w) return;
1297
1298 iconList.remove(w);
1299
1300 iconmenu->remove(w->getWindowNumber());
1301 iconmenu->update();
1302
1303 BlackboxWindowList::iterator it = iconList.begin(),
1304 end = iconList.end();
1305 for (int i = 0; it != end; ++it)
1306 (*it)->setWindowNumber(i++);
1307 }
1308
1309
1310 BlackboxWindow *BScreen::getIcon(unsigned int index) {
1311 if (index < iconList.size()) {
1312 BlackboxWindowList::iterator it = iconList.begin();
1313 while (index-- > 0) // increment to index
1314 ++it;
1315 return *it;
1316 }
1317
1318 return (BlackboxWindow *) 0;
1319 }
1320
1321
1322 unsigned int BScreen::addWorkspace(void) {
1323 Workspace *wkspc = new Workspace(this, workspacesList.size());
1324 workspacesList.push_back(wkspc);
1325 saveWorkspaces(getWorkspaceCount());
1326 saveWorkspaceNames();
1327
1328 workspacemenu->insertWorkspace(wkspc);
1329 workspacemenu->update();
1330
1331 toolbar->reconfigure();
1332
1333 updateNetizenWorkspaceCount();
1334
1335 return workspacesList.size();
1336 }
1337
1338
1339 unsigned int BScreen::removeLastWorkspace(void) {
1340 if (workspacesList.size() == 1)
1341 return 1;
1342
1343 Workspace *wkspc = workspacesList.back();
1344
1345 if (current_workspace->getID() == wkspc->getID())
1346 changeWorkspaceID(current_workspace->getID() - 1);
1347
1348 wkspc->removeAll();
1349
1350 workspacemenu->removeWorkspace(wkspc);
1351 workspacemenu->update();
1352
1353 workspacesList.pop_back();
1354 delete wkspc;
1355
1356 saveWorkspaces(getWorkspaceCount());
1357 saveWorkspaceNames();
1358
1359 toolbar->reconfigure();
1360
1361 updateNetizenWorkspaceCount();
1362
1363 return workspacesList.size();
1364 }
1365
1366
1367 void BScreen::changeWorkspaceID(unsigned int id) {
1368 if (! current_workspace || id == current_workspace->getID()) return;
1369
1370 BlackboxWindow *focused = blackbox->getFocusedWindow();
1371 if (focused && focused->getScreen() == this) {
1372 assert(focused->isStuck() ||
1373 focused->getWorkspaceNumber() == current_workspace->getID());
1374
1375 current_workspace->setLastFocusedWindow(focused);
1376 } else {
1377 // if no window had focus, no need to store a last focus
1378 current_workspace->setLastFocusedWindow((BlackboxWindow *) 0);
1379 }
1380
1381 // when we switch workspaces, unfocus whatever was focused if it is going
1382 // to be unmapped
1383 if (focused && ! focused->isStuck())
1384 blackbox->setFocusedWindow((BlackboxWindow *) 0);
1385
1386 current_workspace->hideAll();
1387 workspacemenu->setItemSelected(current_workspace->getID() + 2, False);
1388
1389 current_workspace = getWorkspace(id);
1390
1391 xatom->setValue(getRootWindow(), XAtom::net_current_desktop,
1392 XAtom::cardinal, id);
1393
1394 workspacemenu->setItemSelected(current_workspace->getID() + 2, True);
1395 toolbar->redrawWorkspaceLabel(True);
1396
1397 current_workspace->showAll();
1398
1399 int x, y, rx, ry;
1400 Window c, r;
1401 unsigned int m;
1402 BlackboxWindow *win = (BlackboxWindow *) 0;
1403 bool f = False;
1404
1405 XSync(blackbox->getXDisplay(), False);
1406
1407 // If sloppy focus and we can find the client window under the pointer,
1408 // try to focus it.
1409 if (resource.sloppy_focus &&
1410 XQueryPointer(blackbox->getXDisplay(), getRootWindow(), &r, &c,
1411 &rx, &ry, &x, &y, &m) &&
1412 c != None) {
1413 if ( (win = blackbox->searchWindow(c)) )
1414 f = win->setInputFocus();
1415 }
1416
1417 // If that fails, and we're doing focus_last, try to focus the last window.
1418 if (! f && resource.focus_last &&
1419 (win = current_workspace->getLastFocusedWindow()))
1420 f = win->setInputFocus();
1421
1422 /*
1423 if we found a focus target, then we set the focused window explicitly
1424 because it is possible to switch off this workspace before the x server
1425 generates the FocusIn event for the window. if that happens, openbox would
1426 lose track of what window was the 'LastFocused' window on the workspace.
1427
1428 if we did not find a focus target, then set the current focused window to
1429 nothing.
1430 */
1431 if (f)
1432 blackbox->setFocusedWindow(win);
1433 else
1434 blackbox->setFocusedWindow((BlackboxWindow *) 0);
1435
1436 updateNetizenCurrentWorkspace();
1437 }
1438
1439
1440 /*
1441 * Set the _NET_CLIENT_LIST root window property.
1442 */
1443 void BScreen::updateClientList(void) {
1444 if (windowList.size() > 0) {
1445 Window *windows = new Window[windowList.size()];
1446 Window *win_it = windows;
1447 BlackboxWindowList::iterator it = windowList.begin();
1448 const BlackboxWindowList::iterator end = windowList.end();
1449 for (; it != end; ++it, ++win_it)
1450 *win_it = (*it)->getClientWindow();
1451 xatom->setValue(getRootWindow(), XAtom::net_client_list, XAtom::window,
1452 windows, windowList.size());
1453 delete [] windows;
1454 } else
1455 xatom->setValue(getRootWindow(), XAtom::net_client_list, XAtom::window,
1456 0, 0);
1457
1458 updateStackingList();
1459 }
1460
1461
1462 /*
1463 * Set the _NET_CLIENT_LIST_STACKING root window property.
1464 */
1465 void BScreen::updateStackingList(void) {
1466
1467 BlackboxWindowList stack_order;
1468
1469 /*
1470 * Get the stacking order from all of the workspaces.
1471 * We start with the current workspace so that the sticky windows will be
1472 * in the right order on the current workspace.
1473 * XXX: Do we need to have sticky windows in the list once for each workspace?
1474 */
1475 getCurrentWorkspace()->appendStackOrder(stack_order);
1476 for (unsigned int i = 0; i < getWorkspaceCount(); ++i)
1477 if (i != getCurrentWorkspaceID())
1478 getWorkspace(i)->appendStackOrder(stack_order);
1479
1480 if (stack_order.size() > 0) {
1481 // set the client list atoms
1482 Window *windows = new Window[stack_order.size()];
1483 Window *win_it = windows;
1484 BlackboxWindowList::iterator it = stack_order.begin(),
1485 end = stack_order.end();
1486 for (; it != end; ++it, ++win_it)
1487 *win_it = (*it)->getClientWindow();
1488 xatom->setValue(getRootWindow(), XAtom::net_client_list_stacking,
1489 XAtom::window, windows, stack_order.size());
1490 delete [] windows;
1491 } else
1492 xatom->setValue(getRootWindow(), XAtom::net_client_list_stacking,
1493 XAtom::window, 0, 0);
1494 }
1495
1496
1497 void BScreen::addSystrayWindow(Window window) {
1498 XGrabServer(blackbox->getXDisplay());
1499
1500 XSelectInput(blackbox->getXDisplay(), window, StructureNotifyMask);
1501 systrayWindowList.push_back(window);
1502 xatom->setValue(getRootWindow(), XAtom::kde_net_system_tray_windows,
1503 XAtom::window,
1504 &systrayWindowList[0], systrayWindowList.size());
1505 blackbox->saveSystrayWindowSearch(window, this);
1506
1507 XUngrabServer(blackbox->getXDisplay());
1508 }
1509
1510
1511 void BScreen::removeSystrayWindow(Window window) {
1512 XGrabServer(blackbox->getXDisplay());
1513
1514 WindowList::iterator it = systrayWindowList.begin();
1515 const WindowList::iterator end = systrayWindowList.end();
1516 for (; it != end; ++it)
1517 if (*it == window) {
1518 systrayWindowList.erase(it);
1519 xatom->setValue(getRootWindow(), XAtom::kde_net_system_tray_windows,
1520 XAtom::window,
1521 &systrayWindowList[0], systrayWindowList.size());
1522 blackbox->removeSystrayWindowSearch(window);
1523 XSelectInput(blackbox->getXDisplay(), window, NoEventMask);
1524 break;
1525 }
1526
1527 assert(it != end); // not a systray window
1528
1529 XUngrabServer(blackbox->getXDisplay());
1530 }
1531
1532
1533 void BScreen::manageWindow(Window w) {
1534 // is the window a KDE systray window?
1535 Window systray;
1536 if (xatom->getValue(w, XAtom::kde_net_wm_system_tray_window_for,
1537 XAtom::window, systray) && systray != None) {
1538 addSystrayWindow(w);
1539 return;
1540 }
1541
1542 // is the window a docking app
1543 XWMHints *wmhint = XGetWMHints(blackbox->getXDisplay(), w);
1544 if (wmhint && (wmhint->flags & StateHint) &&
1545 wmhint->initial_state == WithdrawnState) {
1546 slit->addClient(w);
1547 return;
1548 }
1549
1550 new BlackboxWindow(blackbox, w, this);
1551
1552 BlackboxWindow *win = blackbox->searchWindow(w);
1553 if (! win)
1554 return;
1555
1556 if (win->isDesktop()) {
1557 desktopWindowList.push_back(win->getFrameWindow());
1558 } else { // if (win->isNormal()) {
1559 // don't list desktop windows as managed windows
1560 windowList.push_back(win);
1561 updateClientList();
1562
1563 if (win->isTopmost())
1564 specialWindowList.push_back(win->getFrameWindow());
1565 }
1566
1567 XMapRequestEvent mre;
1568 mre.window = w;
1569 if (blackbox->isStartup() && win->isNormal()) win->restoreAttributes();
1570 win->mapRequestEvent(&mre);
1571 }
1572
1573
1574 void BScreen::unmanageWindow(BlackboxWindow *w, bool remap) {
1575 // is the window a KDE systray window?
1576 Window systray;
1577 if (xatom->getValue(w->getClientWindow(),
1578 XAtom::kde_net_wm_system_tray_window_for,
1579 XAtom::window, systray) && systray != None) {
1580 removeSystrayWindow(w->getClientWindow());
1581 return;
1582 }
1583
1584 w->restore(remap);
1585
1586 // Remove the modality so that its parent won't try to re-focus the window
1587 if (w->isModal()) w->setModal(False);
1588
1589 if (w->getWorkspaceNumber() != BSENTINEL &&
1590 w->getWindowNumber() != BSENTINEL) {
1591 getWorkspace(w->getWorkspaceNumber())->removeWindow(w);
1592 if (w->isStuck()) {
1593 for (unsigned int i = 0; i < getNumberOfWorkspaces(); ++i)
1594 if (i != w->getWorkspaceNumber())
1595 getWorkspace(i)->removeWindow(w, True);
1596 }
1597 } else if (w->isIconic())
1598 removeIcon(w);
1599
1600 if (w->isDesktop()) {
1601 WindowList::iterator it = desktopWindowList.begin();
1602 const WindowList::iterator end = desktopWindowList.end();
1603 for (; it != end; ++it)
1604 if (*it == w->getFrameWindow()) {
1605 desktopWindowList.erase(it);
1606 break;
1607 }
1608 assert(it != end); // the window wasnt a desktop window?
1609 } else { // if (w->isNormal()) {
1610 // we don't list desktop windows as managed windows
1611 windowList.remove(w);
1612 updateClientList();
1613
1614 if (w->isTopmost()) {
1615 WindowList::iterator it = specialWindowList.begin();
1616 const WindowList::iterator end = specialWindowList.end();
1617 for (; it != end; ++it)
1618 if (*it == w->getFrameWindow()) {
1619 specialWindowList.erase(it);
1620 break;
1621 }
1622 assert(it != end); // the window wasnt a special window?
1623 }
1624 }
1625
1626 if (blackbox->getFocusedWindow() == w)
1627 blackbox->setFocusedWindow((BlackboxWindow *) 0);
1628
1629 removeNetizen(w->getClientWindow());
1630
1631 /*
1632 some managed windows can also be window group controllers. when
1633 unmanaging such windows, we should also delete the window group.
1634 */
1635 BWindowGroup *group = blackbox->searchGroup(w->getClientWindow());
1636 delete group;
1637
1638 delete w;
1639 }
1640
1641
1642 void BScreen::addNetizen(Netizen *n) {
1643 netizenList.push_back(n);
1644
1645 n->sendWorkspaceCount();
1646 n->sendCurrentWorkspace();
1647
1648 WorkspaceList::iterator it = workspacesList.begin();
1649 const WorkspaceList::iterator end = workspacesList.end();
1650 for (; it != end; ++it)
1651 (*it)->sendWindowList(*n);
1652
1653 Window f = ((blackbox->getFocusedWindow()) ?
1654 blackbox->getFocusedWindow()->getClientWindow() : None);
1655 n->sendWindowFocus(f);
1656 }
1657
1658
1659 void BScreen::removeNetizen(Window w) {
1660 NetizenList::iterator it = netizenList.begin();
1661 for (; it != netizenList.end(); ++it) {
1662 if ((*it)->getWindowID() == w) {
1663 delete *it;
1664 netizenList.erase(it);
1665 break;
1666 }
1667 }
1668 }
1669
1670
1671 void BScreen::updateWorkArea(void) {
1672 if (workspacesList.size() > 0) {
1673 unsigned long *dims = new unsigned long[4 * workspacesList.size()];
1674 for (unsigned int i = 0, m = workspacesList.size(); i < m; ++i) {
1675 // XXX: this could be different for each workspace
1676 const Rect &area = availableArea();
1677 dims[(i * 4) + 0] = area.x();
1678 dims[(i * 4) + 1] = area.y();
1679 dims[(i * 4) + 2] = area.width();
1680 dims[(i * 4) + 3] = area.height();
1681 }
1682 xatom->setValue(getRootWindow(), XAtom::net_workarea, XAtom::cardinal,
1683 dims, 4 * workspacesList.size());
1684 delete [] dims;
1685 } else
1686 xatom->setValue(getRootWindow(), XAtom::net_workarea, XAtom::cardinal,
1687 0, 0);
1688 }
1689
1690
1691 void BScreen::updateNetizenCurrentWorkspace(void) {
1692 std::for_each(netizenList.begin(), netizenList.end(),
1693 std::mem_fun(&Netizen::sendCurrentWorkspace));
1694 }
1695
1696
1697 void BScreen::updateNetizenWorkspaceCount(void) {
1698 xatom->setValue(getRootWindow(), XAtom::net_number_of_desktops,
1699 XAtom::cardinal, workspacesList.size());
1700
1701 updateWorkArea();
1702
1703 std::for_each(netizenList.begin(), netizenList.end(),
1704 std::mem_fun(&Netizen::sendWorkspaceCount));
1705 }
1706
1707
1708 void BScreen::updateNetizenWindowFocus(void) {
1709 Window f = ((blackbox->getFocusedWindow()) ?
1710 blackbox->getFocusedWindow()->getClientWindow() : None);
1711
1712 xatom->setValue(getRootWindow(), XAtom::net_active_window,
1713 XAtom::window, f);
1714
1715 NetizenList::iterator it = netizenList.begin();
1716 for (; it != netizenList.end(); ++it)
1717 (*it)->sendWindowFocus(f);
1718 }
1719
1720
1721 void BScreen::updateNetizenWindowAdd(Window w, unsigned long p) {
1722 NetizenList::iterator it = netizenList.begin();
1723 for (; it != netizenList.end(); ++it) {
1724 (*it)->sendWindowAdd(w, p);
1725 }
1726 }
1727
1728
1729 void BScreen::updateNetizenWindowDel(Window w) {
1730 NetizenList::iterator it = netizenList.begin();
1731 for (; it != netizenList.end(); ++it)
1732 (*it)->sendWindowDel(w);
1733 }
1734
1735
1736 void BScreen::updateNetizenWindowRaise(Window w) {
1737 NetizenList::iterator it = netizenList.begin();
1738 for (; it != netizenList.end(); ++it)
1739 (*it)->sendWindowRaise(w);
1740 }
1741
1742
1743 void BScreen::updateNetizenWindowLower(Window w) {
1744 NetizenList::iterator it = netizenList.begin();
1745 for (; it != netizenList.end(); ++it)
1746 (*it)->sendWindowLower(w);
1747 }
1748
1749
1750 void BScreen::updateNetizenConfigNotify(XEvent *e) {
1751 NetizenList::iterator it = netizenList.begin();
1752 for (; it != netizenList.end(); ++it)
1753 (*it)->sendConfigNotify(e);
1754 }
1755
1756
1757 void BScreen::raiseWindows(Window *workspace_stack, unsigned int num) {
1758 // the 13 represents the number of blackbox windows such as menus
1759 int bbwins = 15;
1760 #ifdef XINERAMA
1761 ++bbwins;
1762 #endif // XINERAMA
1763 #ifdef XFT
1764 ++bbwins;
1765 #endif // XFT
1766
1767 Window *session_stack = new
1768 Window[(num + workspacesList.size() + rootmenuList.size() +
1769 specialWindowList.size() + bbwins)];
1770 unsigned int i = 0, k = num;
1771
1772 XRaiseWindow(blackbox->getXDisplay(), iconmenu->getWindowID());
1773 *(session_stack + i++) = iconmenu->getWindowID();
1774
1775 WorkspaceList::iterator wit = workspacesList.begin();
1776 const WorkspaceList::iterator w_end = workspacesList.end();
1777 for (; wit != w_end; ++wit)
1778 *(session_stack + i++) = (*wit)->getMenu()->getWindowID();
1779
1780 *(session_stack + i++) = workspacemenu->getWindowID();
1781
1782 *(session_stack + i++) = configmenu->getFocusmenu()->getWindowID();
1783 *(session_stack + i++) = configmenu->getPlacementmenu()->getWindowID();
1784 *(session_stack + i++) = configmenu->getWindowSnapmenu()->getWindowID();
1785 *(session_stack + i++) = configmenu->getEdgeSnapmenu()->getWindowID();
1786 #ifdef XINERAMA
1787 *(session_stack + i++) = configmenu->getXineramamenu()->getWindowID();
1788 #endif // XINERAMA
1789 #ifdef XFT
1790 *(session_stack + i++) = configmenu->getXftmenu()->getWindowID();
1791 #endif // XFT
1792 *(session_stack + i++) = configmenu->getWindowID();
1793
1794 *(session_stack + i++) = slit->getMenu()->getDirectionmenu()->getWindowID();
1795 *(session_stack + i++) = slit->getMenu()->getPlacementmenu()->getWindowID();
1796 *(session_stack + i++) = slit->getMenu()->getWindowID();
1797
1798 *(session_stack + i++) =
1799 toolbar->getMenu()->getPlacementmenu()->getWindowID();
1800 *(session_stack + i++) = toolbar->getMenu()->getWindowID();
1801
1802 RootmenuList::iterator rit = rootmenuList.begin();
1803 for (; rit != rootmenuList.end(); ++rit)
1804 *(session_stack + i++) = (*rit)->getWindowID();
1805 *(session_stack + i++) = rootmenu->getWindowID();
1806
1807 if (toolbar->isOnTop())
1808 *(session_stack + i++) = toolbar->getWindowID();
1809
1810 if (slit->isOnTop())
1811 *(session_stack + i++) = slit->getWindowID();
1812
1813 WindowList::iterator sit, send = specialWindowList.end();
1814 for (sit = specialWindowList.begin(); sit != send; ++sit)
1815 *(session_stack + i++) = *sit;
1816
1817 while (k--)
1818 *(session_stack + i++) = *(workspace_stack + k);
1819
1820 XRestackWindows(blackbox->getXDisplay(), session_stack, i);
1821
1822 delete [] session_stack;
1823
1824 updateStackingList();
1825 }
1826
1827
1828 void BScreen::lowerWindows(Window *workspace_stack, unsigned int num) {
1829 assert(num > 0); // this would cause trouble in the XRaiseWindow call
1830
1831 Window *session_stack = new Window[(num + desktopWindowList.size())];
1832 unsigned int i = 0, k = num;
1833
1834 XLowerWindow(blackbox->getXDisplay(), workspace_stack[0]);
1835
1836 while (k--)
1837 *(session_stack + i++) = *(workspace_stack + k);
1838
1839 WindowList::iterator dit = desktopWindowList.begin();
1840 const WindowList::iterator d_end = desktopWindowList.end();
1841 for (; dit != d_end; ++dit)
1842 *(session_stack + i++) = *dit;
1843
1844 XRestackWindows(blackbox->getXDisplay(), session_stack, i);
1845
1846 delete [] session_stack;
1847
1848 updateStackingList();
1849 }
1850
1851
1852 void BScreen::reassociateWindow(BlackboxWindow *w, unsigned int wkspc_id,
1853 bool ignore_sticky) {
1854 if (! w) return;
1855
1856 if (wkspc_id == BSENTINEL)
1857 wkspc_id = current_workspace->getID();
1858
1859 if (w->getWorkspaceNumber() == wkspc_id)
1860 return;
1861
1862 if (w->isIconic()) {
1863 removeIcon(w);
1864 getWorkspace(wkspc_id)->addWindow(w);
1865 if (w->isStuck())
1866 for (unsigned int i = 0; i < getNumberOfWorkspaces(); ++i)
1867 if (i != w->getWorkspaceNumber())
1868 getWorkspace(i)->addWindow(w, True);
1869 } else if (ignore_sticky || ! w->isStuck()) {
1870 if (w->isStuck())
1871 w->stick();
1872 getWorkspace(w->getWorkspaceNumber())->removeWindow(w);
1873 getWorkspace(wkspc_id)->addWindow(w);
1874 }
1875 updateStackingList();
1876 }
1877
1878
1879 void BScreen::propagateWindowName(const BlackboxWindow *bw) {
1880 if (bw->isIconic()) {
1881 iconmenu->changeItemLabel(bw->getWindowNumber(), bw->getIconTitle());
1882 iconmenu->update();
1883 } else {
1884 Clientmenu *clientmenu = getWorkspace(bw->getWorkspaceNumber())->getMenu();
1885 clientmenu->changeItemLabel(bw->getWindowNumber(), bw->getTitle());
1886 clientmenu->update();
1887
1888 if (blackbox->getFocusedWindow() == bw)
1889 toolbar->redrawWindowLabel(True);
1890 }
1891 }
1892
1893
1894 void BScreen::nextFocus(void) const {
1895 BlackboxWindow *focused = blackbox->getFocusedWindow(),
1896 *next = focused;
1897
1898 if (focused &&
1899 focused->getScreen()->getScreenNumber() == getScreenNumber() &&
1900 current_workspace->getCount() > 1) {
1901 do {
1902 next = current_workspace->getNextWindowInList(next);
1903 } while (next != focused && ! next->setInputFocus());
1904
1905 if (next != focused)
1906 current_workspace->raiseWindow(next);
1907 } else if (current_workspace->getCount() > 0) {
1908 next = current_workspace->getTopWindowOnStack();
1909 next->setInputFocus();
1910 current_workspace->raiseWindow(next);
1911 }
1912 }
1913
1914
1915 void BScreen::prevFocus(void) const {
1916 BlackboxWindow *focused = blackbox->getFocusedWindow(),
1917 *next = focused;
1918
1919 if (focused) {
1920 // if window is not on this screen, ignore it
1921 if (focused->getScreen()->getScreenNumber() != getScreenNumber())
1922 focused = (BlackboxWindow*) 0;
1923 }
1924
1925 if (focused &&
1926 focused->getScreen()->getScreenNumber() == getScreenNumber() &&
1927 current_workspace->getCount() > 1) {
1928 // next is the next window to receive focus, current is a place holder
1929 do {
1930 next = current_workspace->getPrevWindowInList(next);
1931 } while (next != focused && ! next->setInputFocus());
1932
1933 if (next != focused)
1934 current_workspace->raiseWindow(next);
1935 } else if (current_workspace->getCount() > 0) {
1936 next = current_workspace->getTopWindowOnStack();
1937 next->setInputFocus();
1938 current_workspace->raiseWindow(next);
1939 }
1940 }
1941
1942
1943 void BScreen::raiseFocus(void) const {
1944 BlackboxWindow *focused = blackbox->getFocusedWindow();
1945 if (! focused)
1946 return;
1947
1948 // if on this Screen, raise it
1949 if (focused->getScreen()->getScreenNumber() == getScreenNumber()) {
1950 Workspace *workspace = getWorkspace(focused->getWorkspaceNumber());
1951 workspace->raiseWindow(focused);
1952 }
1953 }
1954
1955
1956 void BScreen::InitMenu(void) {
1957 if (rootmenu) {
1958 rootmenuList.clear();
1959
1960 while (rootmenu->getCount())
1961 rootmenu->remove(0);
1962 } else {
1963 rootmenu = new Rootmenu(this);
1964 }
1965 bool defaultMenu = True;
1966
1967 FILE *menu_file = (FILE *) 0;
1968 const char *menu_filename = blackbox->getMenuFilename();
1969
1970 if (menu_filename)
1971 if (! (menu_file = fopen(menu_filename, "r")))
1972 perror(menu_filename);
1973 if (! menu_file) { // opening the menu file failed, try the default menu
1974 menu_filename = DEFAULTMENU;
1975 if (! (menu_file = fopen(menu_filename, "r")))
1976 perror(menu_filename);
1977 }
1978
1979 if (menu_file) {
1980 if (feof(menu_file)) {
1981 fprintf(stderr, i18n(ScreenSet, ScreenEmptyMenuFile,
1982 "%s: Empty menu file"),
1983 menu_filename);
1984 } else {
1985 char line[1024], label[1024];
1986 memset(line, 0, 1024);
1987 memset(label, 0, 1024);
1988
1989 while (fgets(line, 1024, menu_file) && ! feof(menu_file)) {
1990 if (line[0] == '#')
1991 continue;
1992
1993 int i, key = 0, index = -1, len = strlen(line);
1994
1995 for (i = 0; i < len; i++) {
1996 if (line[i] == '[') index = 0;
1997 else if (line[i] == ']') break;
1998 else if (line[i] != ' ')
1999 if (index++ >= 0)
2000 key += tolower(line[i]);
2001 }
2002
2003 if (key == 517) { // [begin]
2004 index = -1;
2005 for (i = index; i < len; i++) {
2006 if (line[i] == '(') index = 0;
2007 else if (line[i] == ')') break;
2008 else if (index++ >= 0) {
2009 if (line[i] == '\\' && i < len - 1) i++;
2010 label[index - 1] = line[i];
2011 }
2012 }
2013
2014 if (index == -1) index = 0;
2015 label[index] = '\0';
2016
2017 rootmenu->setLabel(label);
2018 defaultMenu = parseMenuFile(menu_file, rootmenu);
2019 if (! defaultMenu)
2020 blackbox->addMenuTimestamp(menu_filename);
2021 break;
2022 }
2023 }
2024 }
2025 fclose(menu_file);
2026 }
2027
2028 if (defaultMenu) {
2029 rootmenu->setInternalMenu();
2030 rootmenu->insert(i18n(ScreenSet, Screenxterm, "xterm"),
2031 BScreen::Execute,
2032 i18n(ScreenSet, Screenxterm, "xterm"));
2033 rootmenu->insert(i18n(ScreenSet, ScreenRestart, "Restart"),
2034 BScreen::Restart);
2035 rootmenu->insert(i18n(ScreenSet, ScreenExit, "Exit"),
2036 BScreen::Exit);
2037 rootmenu->setLabel(i18n(BasemenuSet, BasemenuBlackboxMenu,
2038 "Openbox Menu"));
2039 }
2040 }
2041
2042
2043 static
2044 size_t string_within(char begin, char end,
2045 const char *input, size_t start_at, size_t length,
2046 char *output) {
2047 bool parse = False;
2048 size_t index = 0;
2049 size_t i = start_at;
2050 for (; i < length; ++i) {
2051 if (input[i] == begin) {
2052 parse = True;
2053 } else if (input[i] == end) {
2054 break;
2055 } else if (parse) {
2056 if (input[i] == '\\' && i < length - 1) i++;
2057 output[index++] = input[i];
2058 }
2059 }
2060
2061 if (parse)
2062 output[index] = '\0';
2063 else
2064 output[0] = '\0';
2065
2066 return i;
2067 }
2068
2069
2070 bool BScreen::parseMenuFile(FILE *file, Rootmenu *menu) {
2071 char line[1024], keyword[1024], label[1024], command[1024];
2072 bool done = False;
2073
2074 while (! (done || feof(file))) {
2075 memset(line, 0, 1024);
2076 memset(label, 0, 1024);
2077 memset(command, 0, 1024);
2078
2079 if (! fgets(line, 1024, file))
2080 continue;
2081
2082 if (line[0] == '#') // comment, skip it
2083 continue;
2084
2085 size_t line_length = strlen(line);
2086 unsigned int key = 0;
2087
2088 // get the keyword enclosed in []'s
2089 size_t pos = string_within('[', ']', line, 0, line_length, keyword);
2090
2091 if (keyword[0] == '\0') { // no keyword, no menu entry
2092 continue;
2093 } else {
2094 size_t len = strlen(keyword);
2095 for (size_t i = 0; i < len; ++i) {
2096 if (keyword[i] != ' ')
2097 key += tolower(keyword[i]);
2098 }
2099 }
2100
2101 // get the label enclosed in ()'s
2102 pos = string_within('(', ')', line, pos, line_length, label);
2103
2104 // get the command enclosed in {}'s
2105 pos = string_within('{', '}', line, pos, line_length, command);
2106
2107 switch (key) {
2108 case 311: // end
2109 done = True;
2110
2111 break;
2112
2113 case 333: // nop
2114 if (! *label)
2115 label[0] = '\0';
2116 menu->insert(label);
2117
2118 break;
2119
2120 case 421: // exec
2121 if (! (*label && *command)) {
2122 fprintf(stderr, i18n(ScreenSet, ScreenEXECError,
2123 "BScreen::parseMenuFile: [exec] error, "
2124 "no menu label and/or command defined\n"));
2125 continue;
2126 }
2127
2128 menu->insert(label, BScreen::Execute, command);
2129
2130 break;
2131
2132 case 442: // exit
2133 if (! *label) {
2134 fprintf(stderr, i18n(ScreenSet, ScreenEXITError,
2135 "BScreen::parseMenuFile: [exit] error, "
2136 "no menu label defined\n"));
2137 continue;
2138 }
2139
2140 menu->insert(label, BScreen::Exit);
2141
2142 break;
2143
2144 case 561: { // style
2145 if (! (*label && *command)) {
2146 fprintf(stderr,
2147 i18n(ScreenSet, ScreenSTYLEError,
2148 "BScreen::parseMenuFile: [style] error, "
2149 "no menu label and/or filename defined\n"));
2150 continue;
2151 }
2152
2153 string style = expandTilde(command);
2154
2155 menu->insert(label, BScreen::SetStyle, style.c_str());
2156 }
2157 break;
2158
2159 case 630: // config
2160 if (! *label) {
2161 fprintf(stderr, i18n(ScreenSet, ScreenCONFIGError,
2162 "BScreen::parseMenufile: [config] error, "
2163 "no label defined"));
2164 continue;
2165 }
2166
2167 menu->insert(label, configmenu);
2168
2169 break;
2170
2171 case 740: { // include
2172 if (! *label) {
2173 fprintf(stderr, i18n(ScreenSet, ScreenINCLUDEError,
2174 "BScreen::parseMenuFile: [include] error, "
2175 "no filename defined\n"));
2176 continue;
2177 }
2178
2179 string newfile = expandTilde(label);
2180 FILE *submenufile = fopen(newfile.c_str(), "r");
2181
2182 if (! submenufile) {
2183 perror(newfile.c_str());
2184 continue;
2185 }
2186
2187 struct stat buf;
2188 if (fstat(fileno(submenufile), &buf) ||
2189 ! S_ISREG(buf.st_mode)) {
2190 fprintf(stderr,
2191 i18n(ScreenSet, ScreenINCLUDEErrorReg,
2192 "BScreen::parseMenuFile: [include] error: "
2193 "'%s' is not a regular file\n"), newfile.c_str());
2194 break;
2195 }
2196
2197 if (! feof(submenufile)) {
2198 if (! parseMenuFile(submenufile, menu))
2199 blackbox->addMenuTimestamp(newfile);
2200
2201 fclose(submenufile);
2202 }
2203 }
2204
2205 break;
2206
2207 case 767: { // submenu
2208 if (! *label) {
2209 fprintf(stderr, i18n(ScreenSet, ScreenSUBMENUError,
2210 "BScreen::parseMenuFile: [submenu] error, "
2211 "no menu label defined\n"));
2212 continue;
2213 }
2214
2215 Rootmenu *submenu = new Rootmenu(this);
2216
2217 if (*command)
2218 submenu->setLabel(command);
2219 else
2220 submenu->setLabel(label);
2221
2222 parseMenuFile(file, submenu);
2223 submenu->update();
2224 menu->insert(label, submenu);
2225 rootmenuList.push_back(submenu);
2226 }
2227
2228 break;
2229
2230 case 773: { // restart
2231 if (! *label) {
2232 fprintf(stderr, i18n(ScreenSet, ScreenRESTARTError,
2233 "BScreen::parseMenuFile: [restart] error, "
2234 "no menu label defined\n"));
2235 continue;
2236 }
2237
2238 if (*command)
2239 menu->insert(label, BScreen::RestartOther, command);
2240 else
2241 menu->insert(label, BScreen::Restart);
2242 }
2243
2244 break;
2245
2246 case 845: { // reconfig
2247 if (! *label) {
2248 fprintf(stderr,
2249 i18n(ScreenSet, ScreenRECONFIGError,
2250 "BScreen::parseMenuFile: [reconfig] error, "
2251 "no menu label defined\n"));
2252 continue;
2253 }
2254
2255 menu->insert(label, BScreen::Reconfigure);
2256 }
2257
2258 break;
2259
2260 case 995: // stylesdir
2261 case 1113: { // stylesmenu
2262 bool newmenu = ((key == 1113) ? True : False);
2263
2264 if (! *label || (! *command && newmenu)) {
2265 fprintf(stderr,
2266 i18n(ScreenSet, ScreenSTYLESDIRError,
2267 "BScreen::parseMenuFile: [stylesdir/stylesmenu]"
2268 " error, no directory defined\n"));
2269 continue;
2270 }
2271
2272 char *directory = ((newmenu) ? command : label);
2273
2274 string stylesdir = expandTilde(directory);
2275
2276 struct stat statbuf;
2277
2278 if (stat(stylesdir.c_str(), &statbuf) == -1) {
2279 fprintf(stderr,
2280 i18n(ScreenSet, ScreenSTYLESDIRErrorNoExist,
2281 "BScreen::parseMenuFile: [stylesdir/stylesmenu]"
2282 " error, %s does not exist\n"), stylesdir.c_str());
2283 continue;
2284 }
2285 if (! S_ISDIR(statbuf.st_mode)) {
2286 fprintf(stderr,
2287 i18n(ScreenSet, ScreenSTYLESDIRErrorNotDir,
2288 "BScreen::parseMenuFile:"
2289 " [stylesdir/stylesmenu] error, %s is not a"
2290 " directory\n"), stylesdir.c_str());
2291 continue;
2292 }
2293
2294 Rootmenu *stylesmenu;
2295
2296 if (newmenu)
2297 stylesmenu = new Rootmenu(this);
2298 else
2299 stylesmenu = menu;
2300
2301 DIR *d = opendir(stylesdir.c_str());
2302 struct dirent *p;
2303 std::vector<string> ls;
2304
2305 while((p = readdir(d)))
2306 ls.push_back(p->d_name);
2307
2308 closedir(d);
2309
2310 std::sort(ls.begin(), ls.end());
2311
2312 std::vector<string>::iterator it = ls.begin(),
2313 end = ls.end();
2314 for (; it != end; ++it) {
2315 const string& fname = *it;
2316
2317 if (fname[fname.size()-1] == '~')
2318 continue;
2319
2320 string style = stylesdir;
2321 style += '/';
2322 style += fname;
2323
2324 if (! stat(style.c_str(), &statbuf) && S_ISREG(statbuf.st_mode))
2325 stylesmenu->insert(fname, BScreen::SetStyle, style);
2326 }
2327
2328 stylesmenu->update();
2329
2330 if (newmenu) {
2331 stylesmenu->setLabel(label);
2332 menu->insert(label, stylesmenu);
2333 rootmenuList.push_back(stylesmenu);
2334 }
2335
2336 blackbox->addMenuTimestamp(stylesdir);
2337 }
2338 break;
2339
2340 case 1090: { // workspaces
2341 if (! *label) {
2342 fprintf(stderr,
2343 i18n(ScreenSet, ScreenWORKSPACESError,
2344 "BScreen:parseMenuFile: [workspaces] error, "
2345 "no menu label defined\n"));
2346 continue;
2347 }
2348
2349 menu->insert(label, workspacemenu);
2350 }
2351 break;
2352 }
2353 }
2354
2355 return ((menu->getCount() == 0) ? True : False);
2356 }
2357
2358
2359 void BScreen::shutdown(void) {
2360 XSelectInput(blackbox->getXDisplay(), getRootWindow(), NoEventMask);
2361 XSync(blackbox->getXDisplay(), False);
2362
2363 while(! windowList.empty())
2364 unmanageWindow(windowList.front(), True);
2365
2366 while(! desktopWindowList.empty()) {
2367 BlackboxWindow *win = blackbox->searchWindow(desktopWindowList.front());
2368 assert(win);
2369 unmanageWindow(win, True);
2370 }
2371
2372 slit->shutdown();
2373 }
2374
2375
2376 void BScreen::showPosition(int x, int y) {
2377 if (! geom_visible) {
2378 XMoveResizeWindow(blackbox->getXDisplay(), geom_window,
2379 (getWidth() - geom_w) / 2,
2380 (getHeight() - geom_h) / 2, geom_w, geom_h);
2381 XMapWindow(blackbox->getXDisplay(), geom_window);
2382 XRaiseWindow(blackbox->getXDisplay(), geom_window);
2383
2384 geom_visible = True;
2385 }
2386
2387 char label[1024];
2388
2389 sprintf(label, i18n(ScreenSet, ScreenPositionFormat,
2390 "X: %4d x Y: %4d"), x, y);
2391
2392 XClearWindow(blackbox->getXDisplay(), geom_window);
2393
2394 resource.wstyle.font->drawString(geom_window,
2395 resource.bevel_width, resource.bevel_width,
2396 resource.wstyle.l_text_focus,
2397 label);
2398 }
2399
2400
2401 void BScreen::showGeometry(unsigned int gx, unsigned int gy) {
2402 if (! geom_visible) {
2403 XMoveResizeWindow(blackbox->getXDisplay(), geom_window,
2404 (getWidth() - geom_w) / 2,
2405 (getHeight() - geom_h) / 2, geom_w, geom_h);
2406 XMapWindow(blackbox->getXDisplay(), geom_window);
2407 XRaiseWindow(blackbox->getXDisplay(), geom_window);
2408
2409 geom_visible = True;
2410 }
2411
2412 char label[1024];
2413
2414 sprintf(label, i18n(ScreenSet, ScreenGeometryFormat,
2415 "W: %4d x H: %4d"), gx, gy);
2416
2417 XClearWindow(blackbox->getXDisplay(), geom_window);
2418
2419 resource.wstyle.font->drawString(geom_window,
2420 resource.bevel_width, resource.bevel_width,
2421 resource.wstyle.l_text_focus,
2422 label);
2423 }
2424
2425
2426 void BScreen::hideGeometry(void) {
2427 if (geom_visible) {
2428 XUnmapWindow(blackbox->getXDisplay(), geom_window);
2429 geom_visible = False;
2430 }
2431 }
2432
2433
2434 void BScreen::addStrut(Strut *strut) {
2435 strutList.push_back(strut);
2436 }
2437
2438
2439 void BScreen::removeStrut(Strut *strut) {
2440 strutList.remove(strut);
2441 }
2442
2443
2444 const Rect& BScreen::availableArea(void) const {
2445 if (doFullMax())
2446 return getRect(); // return the full screen
2447 return usableArea;
2448 }
2449
2450
2451 #ifdef XINERAMA
2452 const RectList& BScreen::allAvailableAreas(void) const {
2453 assert(isXineramaActive());
2454 assert(xineramaUsableArea.size() > 0);
2455 fprintf(stderr, "1found x %d y %d w %d h %d\n",
2456 xineramaUsableArea[0].x(), xineramaUsableArea[0].y(),
2457 xineramaUsableArea[0].width(), xineramaUsableArea[0].height());
2458 return xineramaUsableArea;
2459 }
2460 #endif // XINERAMA
2461
2462
2463 void BScreen::updateAvailableArea(void) {
2464 Rect old_area = usableArea;
2465 usableArea = getRect(); // reset to full screen
2466
2467 #ifdef XINERAMA
2468 // reset to the full areas
2469 if (isXineramaActive())
2470 xineramaUsableArea = getXineramaAreas();
2471 #endif // XINERAMA
2472
2473 /* these values represent offsets from the screen edge
2474 * we look for the biggest offset on each edge and then apply them
2475 * all at once
2476 * do not be confused by the similarity to the names of Rect's members
2477 */
2478 unsigned int current_left = 0, current_right = 0, current_top = 0,
2479 current_bottom = 0;
2480
2481 StrutList::const_iterator it = strutList.begin(), end = strutList.end();
2482
2483 for(; it != end; ++it) {
2484 Strut *strut = *it;
2485 if (strut->left > current_left)
2486 current_left = strut->left;
2487 if (strut->top > current_top)
2488 current_top = strut->top;
2489 if (strut->right > current_right)
2490 current_right = strut->right;
2491 if (strut->bottom > current_bottom)
2492 current_bottom = strut->bottom;
2493 }
2494
2495 usableArea.setPos(current_left, current_top);
2496 usableArea.setSize(usableArea.width() - (current_left + current_right),
2497 usableArea.height() - (current_top + current_bottom));
2498
2499 #ifdef XINERAMA
2500 if (isXineramaActive()) {
2501 // keep each of the ximerama-defined areas inside the strut
2502 RectList::iterator xit, xend = xineramaUsableArea.end();
2503 for (xit = xineramaUsableArea.begin(); xit != xend; ++xit) {
2504 if (xit->x() < usableArea.x()) {
2505 xit->setX(usableArea.x());
2506 xit->setWidth(xit->width() - usableArea.x());
2507 }
2508 if (xit->y() < usableArea.y()) {
2509 xit->setY(usableArea.y());
2510 xit->setHeight(xit->height() - usableArea.y());
2511 }
2512 if (xit->x() + xit->width() > usableArea.width())
2513 xit->setWidth(usableArea.width() - xit->x());
2514 if (xit->y() + xit->height() > usableArea.height())
2515 xit->setHeight(usableArea.height() - xit->y());
2516 }
2517 }
2518 #endif // XINERAMA
2519
2520 if (old_area != usableArea) {
2521 BlackboxWindowList::iterator it = windowList.begin(),
2522 end = windowList.end();
2523 for (; it != end; ++it)
2524 if ((*it)->isMaximized()) (*it)->remaximize();
2525 }
2526
2527 updateWorkArea();
2528 }
2529
2530
2531 Workspace* BScreen::getWorkspace(unsigned int index) const {
2532 assert(index < workspacesList.size());
2533 return workspacesList[index];
2534 }
2535
2536
2537 void BScreen::buttonPressEvent(const XButtonEvent *xbutton) {
2538 if (xbutton->button == 1) {
2539 if (! isRootColormapInstalled())
2540 image_control->installRootColormap();
2541
2542 if (workspacemenu->isVisible())
2543 workspacemenu->hide();
2544
2545 if (rootmenu->isVisible())
2546 rootmenu->hide();
2547 // mouse wheel up
2548 } else if ((xbutton->button == 4 && resource.root_scroll == NormalScroll) ||
2549 (xbutton->button == 5 && resource.root_scroll == ReverseScroll)) {
2550 if (getCurrentWorkspaceID() >= getWorkspaceCount() - 1)
2551 changeWorkspaceID(0);
2552 else
2553 changeWorkspaceID(getCurrentWorkspaceID() + 1);
2554 // mouse wheel down
2555 } else if ((xbutton->button == 5 && resource.root_scroll == NormalScroll) ||
2556 (xbutton->button == 4 && resource.root_scroll == ReverseScroll)) {
2557 if (getCurrentWorkspaceID() == 0)
2558 changeWorkspaceID(getWorkspaceCount() - 1);
2559 else
2560 changeWorkspaceID(getCurrentWorkspaceID() - 1);
2561 }
2562
2563 if (resource.root_menu_button > 0 &&
2564 xbutton->button == resource.root_menu_button)
2565 showRootMenu(xbutton->x_root, xbutton->y_root);
2566 else if (resource.workspace_menu_button > 0 &&
2567 xbutton->button == resource.workspace_menu_button)
2568 showWorkspaceMenu(xbutton->x_root, xbutton->y_root);
2569 }
2570
2571
2572 void BScreen::showWorkspaceMenu(int x, int y) {
2573 int mx = x - (workspacemenu->getWidth() / 2);
2574 int my = y - (workspacemenu->getTitleHeight() / 2);
2575
2576 if (mx < 0) mx = 0;
2577 if (my < 0) my = 0;
2578
2579 if (mx + workspacemenu->getWidth() > getWidth())
2580 mx = getWidth() - workspacemenu->getWidth() - getBorderWidth();
2581
2582 if (my + workspacemenu->getHeight() > getHeight())
2583 my = getHeight() - workspacemenu->getHeight() - getBorderWidth();
2584
2585 workspacemenu->move(mx, my);
2586
2587 if (! workspacemenu->isVisible()) {
2588 workspacemenu->removeParent();
2589 workspacemenu->show();
2590 }
2591 }
2592
2593
2594 void BScreen::showRootMenu(int x, int y) {
2595 int mx = x - (rootmenu->getWidth() / 2);
2596 int my = y - (rootmenu->getTitleHeight() / 2);
2597
2598 if (mx < 0) mx = 0;
2599 if (my < 0) my = 0;
2600
2601 if (mx + rootmenu->getWidth() > getWidth())
2602 mx = getWidth() - rootmenu->getWidth() - getBorderWidth();
2603
2604 if (my + rootmenu->getHeight() > getHeight())
2605 my = getHeight() - rootmenu->getHeight() - getBorderWidth();
2606
2607 rootmenu->move(mx, my);
2608
2609 if (! rootmenu->isVisible()) {
2610 blackbox->checkMenu();
2611 rootmenu->show();
2612 }
2613 }
2614
2615
2616 void BScreen::propertyNotifyEvent(const XPropertyEvent *pe) {
2617 if (pe->atom == xatom->getAtom(XAtom::net_desktop_names)) {
2618 // _NET_WM_DESKTOP_NAMES
2619 WorkspaceList::iterator it = workspacesList.begin();
2620 const WorkspaceList::iterator end = workspacesList.end();
2621 for (; it != end; ++it) {
2622 (*it)->readName(); // re-read its name from the window property
2623 workspacemenu->changeWorkspaceLabel((*it)->getID(), (*it)->getName());
2624 }
2625 workspacemenu->update();
2626 toolbar->reconfigure();
2627 saveWorkspaceNames();
2628 }
2629 }
2630
2631
2632 void BScreen::toggleFocusModel(FocusModel model) {
2633 std::for_each(windowList.begin(), windowList.end(),
2634 std::mem_fun(&BlackboxWindow::ungrabButtons));
2635
2636 if (model == SloppyFocus) {
2637 saveSloppyFocus(True);
2638 } else {
2639 // we're cheating here to save writing the config file 3 times
2640 resource.auto_raise = False;
2641 resource.click_raise = False;
2642 saveSloppyFocus(False);
2643 }
2644
2645 std::for_each(windowList.begin(), windowList.end(),
2646 std::mem_fun(&BlackboxWindow::grabButtons));
2647 }
2648
2649 #ifdef BITMAPBUTTONS
2650 void BScreen::readDatabaseMask(const string &rname, PixmapMask &pixmapMask,
2651 const Configuration &style) {
2652 string s;
2653 int hx, hy; //ignored
2654 int ret = BitmapOpenFailed; //default to failure.
2655
2656 if (style.getValue(rname, s))
2657 {
2658 if (s[0] != '/' && s[0] != '~')
2659 {
2660 std::string xbmFile = std::string("~/.openbox/buttons/") + s;
2661 ret = XReadBitmapFile(blackbox->getXDisplay(), getRootWindow(),
2662 expandTilde(xbmFile).c_str(), &pixmapMask.w,
2663 &pixmapMask.h, &pixmapMask.mask, &hx, &hy);
2664 } else
2665 ret = XReadBitmapFile(blackbox->getXDisplay(), getRootWindow(),
2666 expandTilde(s).c_str(), &pixmapMask.w,
2667 &pixmapMask.h, &pixmapMask.mask, &hx, &hy);
2668
2669 if (ret == BitmapSuccess)
2670 return;
2671 }
2672
2673 pixmapMask.mask = None;
2674 pixmapMask.w = pixmapMask.h = 0;
2675 }
2676 #endif // BITMAPSUCCESS
2677
2678 BTexture BScreen::readDatabaseTexture(const string &rname,
2679 const string &default_color,
2680 const Configuration &style,
2681 bool allowNoTexture) {
2682 BTexture texture;
2683 string s;
2684
2685 if (style.getValue(rname, s))
2686 texture = BTexture(s);
2687 else if (allowNoTexture) //no default
2688 texture.setTexture(BTexture::NoTexture);
2689 else
2690 texture.setTexture(BTexture::Solid | BTexture::Flat);
2691
2692 // associate this texture with this screen
2693 texture.setDisplay(getBaseDisplay(), getScreenNumber());
2694 texture.setImageControl(image_control);
2695
2696 if (texture.texture() != BTexture::NoTexture) {
2697 texture.setColor(readDatabaseColor(rname + ".color", default_color,
2698 style));
2699 texture.setColorTo(readDatabaseColor(rname + ".colorTo", default_color,
2700 style));
2701 texture.setBorderColor(readDatabaseColor(rname + ".borderColor",
2702 default_color, style));
2703 }
2704
2705 return texture;
2706 }
2707
2708
2709 BColor BScreen::readDatabaseColor(const string &rname,
2710 const string &default_color,
2711 const Configuration &style) {
2712 BColor color;
2713 string s;
2714 if (style.getValue(rname, s))
2715 color = BColor(s, getBaseDisplay(), getScreenNumber());
2716 else
2717 color = BColor(default_color, getBaseDisplay(), getScreenNumber());
2718 return color;
2719 }
2720
2721
2722 BFont *BScreen::readDatabaseFont(const string &rbasename,
2723 const Configuration &style) {
2724 string fontname;
2725
2726 string s;
2727
2728 #ifdef XFT
2729 int i;
2730 if (style.getValue(rbasename + "xft.font", s) &&
2731 style.getValue(rbasename + "xft.size", i)) {
2732 string family = s;
2733 bool bold = False;
2734 bool italic = False;
2735 if (style.getValue(rbasename + "xft.flags", s)) {
2736 if (s.find("bold") != string::npos)
2737 bold = True;
2738 if (s.find("italic") != string::npos)
2739 italic = True;
2740 }
2741
2742 BFont *b = new BFont(blackbox->getXDisplay(), this, family, i, bold,
2743 italic, resource.shadow_fonts, resource.aa_fonts);
2744 if (b->valid())
2745 return b;
2746 else
2747 delete b; // fall back to the normal X font stuff
2748 }
2749 #endif // XFT
2750
2751 style.getValue(rbasename + "font", s);
2752 // if this fails, a blank string will be used, which will cause the fallback
2753 // font to load.
2754
2755 BFont *b = new BFont(blackbox->getXDisplay(), this, s);
2756 if (! b->valid())
2757 exit(2); // can't continue without a font
2758 return b;
2759 }
This page took 0.164412 seconds and 4 git commands to generate.