1 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
5 #endif // HAVE_CONFIG_H
9 #include <X11/keysym.h>
12 # include <X11/Xlib.h>
13 # include <X11/extensions/Xinerama.h>
18 #endif // HAVE_STDLIB_H
22 #endif // HAVE_STRING_H
26 #endif // HAVE_CTYPE_H
29 # include <sys/types.h>
31 #endif // HAVE_UNISTD_H
35 #endif // HAVE_DIRENT_H
39 #endif // HAVE_LOCALE_H
41 #ifdef HAVE_SYS_STAT_H
42 # include <sys/stat.h>
43 #endif // HAVE_SYS_STAT_H
47 #endif // HAVE_STDARG_H
58 #include "otk/font.hh"
59 #include "otk/gccache.hh"
60 #include "otk/image.hh"
61 #include "otk/assassin.hh"
62 #include "otk/util.hh"
64 #include "bbwindow.hh"
65 #include "workspace.hh"
67 #ifndef FONT_ELEMENT_SIZE
68 #define FONT_ELEMENT_SIZE 50
69 #endif // FONT_ELEMENT_SIZE
73 static bool running
= True
;
75 static int anotherWMRunning(Display
*display
, XErrorEvent
*) {
77 "BScreen::BScreen: an error occured while querying the X server.\n"
78 " another window manager already running on display %s.\n",
79 DisplayString(display
));
87 BScreen::BScreen(Blackbox
*bb
, unsigned int scrn
) : ScreenInfo(scrn
) {
89 screenstr
= "session.screen" + otk::itostring(scrn
) + '.';
90 config
= blackbox
->getConfig();
91 xatom
= blackbox
->getXAtom();
93 event_mask
= ColormapChangeMask
| EnterWindowMask
| PropertyChangeMask
|
94 SubstructureRedirectMask
| ButtonPressMask
| ButtonReleaseMask
;
96 XErrorHandler old
= XSetErrorHandler((XErrorHandler
) anotherWMRunning
);
97 XSelectInput(otk::OBDisplay::display
, getRootWindow(), event_mask
);
98 XSync(otk::OBDisplay::display
, False
);
99 XSetErrorHandler((XErrorHandler
) old
);
102 if (! managed
) return;
104 fprintf(stderr
, "BScreen::BScreen: managing screen %d "
105 "using visual 0x%lx, depth %d\n",
106 getScreenNumber(), XVisualIDFromVisual(getVisual()),
109 resource
.wstyle
.font
= (otk::BFont
*) 0;
113 // xatom->setSupported(this); // set-up netwm support
115 xatom
->setValue(getRootWindow(), otk::OBProperty::blackbox_pid
,
116 otk::OBProperty::Atom_Cardinal
,
117 (unsigned long) getpid());
118 #endif // HAVE_GETPID
119 unsigned long geometry
[] = { getWidth(),
121 xatom
->set(getRootWindow(), otk::OBProperty::net_desktop_geometry
,
122 otk::OBProperty::Atom_Cardinal
, geometry
, 2);
123 unsigned long viewport
[] = {0,0};
124 xatom
->set(getRootWindow(), otk::OBProperty::net_desktop_viewport
,
125 otk::OBProperty::Atom_Cardinal
, viewport
, 2);
128 XDefineCursor(otk::OBDisplay::display
, getRootWindow(),
129 blackbox
->getSessionCursor());
131 updateAvailableArea();
134 new otk::BImageControl(Openbox::instance
->timerManager(),
135 this, True
, blackbox
->getColorsPerChannel(),
136 blackbox
->getCacheLife(), blackbox
->getCacheMax());
137 image_control
->installRootColormap();
138 root_colormap_installed
= True
;
143 resource
.wstyle
.setImageControl(image_control
);
144 resource
.wstyle
.setScreenNumber(scrn
);
148 gcv
.foreground
= WhitePixel(otk::OBDisplay::display
, getScreenNumber())
149 ^ BlackPixel(otk::OBDisplay::display
, getScreenNumber());
150 gcv
.function
= GXxor
;
151 gcv
.subwindow_mode
= IncludeInferiors
;
152 opGC
= XCreateGC(otk::OBDisplay::display
, getRootWindow(),
153 GCForeground
| GCFunction
| GCSubwindowMode
, &gcv
);
155 const char *s
= "0: 0000 x 0: 0000";
156 geom_w
= resource
.wstyle
.font
->measureString(s
) + resource
.wstyle
.bevel_width
* 2;
157 geom_h
= resource
.wstyle
.font
->height() + resource
.wstyle
.bevel_width
* 2;
159 XSetWindowAttributes attrib
;
160 unsigned long mask
= CWBorderPixel
| CWColormap
| CWSaveUnder
;
161 attrib
.border_pixel
= getBorderColor()->pixel();
162 attrib
.colormap
= getColormap();
163 attrib
.save_under
= True
;
165 // XXX -- move this geom_* crap out of here
167 geom_window
= XCreateWindow(otk::OBDisplay::display
, getRootWindow(),
168 0, 0, geom_w
, geom_h
, resource
.wstyle
.border_width
,
169 getDepth(), InputOutput
, getVisual(),
171 geom_visible
= False
;
173 otk::BTexture
* texture
= &(resource
.wstyle
.l_focus
);
174 geom_pixmap
= texture
->render(geom_w
, geom_h
, geom_pixmap
);
175 if (geom_pixmap
== ParentRelative
) {
176 texture
= &(resource
.wstyle
.t_focus
);
177 geom_pixmap
= texture
->render(geom_w
, geom_h
, geom_pixmap
);
180 XSetWindowBackground(otk::OBDisplay::display
, geom_window
,
181 texture
->color().pixel());
183 XSetWindowBackgroundPixmap(otk::OBDisplay::display
,
184 geom_window
, geom_pixmap
);
186 if (resource
.workspaces
> 0) {
187 for (unsigned int i
= 0; i
< resource
.workspaces
; ++i
) {
188 Workspace
*wkspc
= new Workspace(this, workspacesList
.size());
189 workspacesList
.push_back(wkspc
);
193 Workspace
*wkspc
= new Workspace(this, workspacesList
.size());
194 workspacesList
.push_back(wkspc
);
199 saveWorkspaceNames();
201 updateNetizenWorkspaceCount();
203 current_workspace
= workspacesList
.front();
205 xatom
->set(getRootWindow(), otk::OBProperty::net_current_desktop
,
206 otk::OBProperty::Atom_Cardinal
, 0); //first workspace
208 raiseWindows(0, 0); // this also initializes the empty stacking list
210 updateClientList(); // initialize the client lists, which will be empty
211 updateAvailableArea();
213 changeWorkspaceID(0);
215 unsigned int i
, j
, nchild
;
216 Window r
, p
, *children
;
217 XQueryTree(otk::OBDisplay::display
, getRootWindow(), &r
, &p
,
220 // preen the window list of all icon windows... for better dockapp support
221 for (i
= 0; i
< nchild
; i
++) {
222 if (children
[i
] == None
) continue;
224 XWMHints
*wmhints
= XGetWMHints(otk::OBDisplay::display
,
228 if ((wmhints
->flags
& IconWindowHint
) &&
229 (wmhints
->icon_window
!= children
[i
])) {
230 for (j
= 0; j
< nchild
; j
++) {
231 if (children
[j
] == wmhints
->icon_window
) {
242 // manage shown windows
243 for (i
= 0; i
< nchild
; ++i
) {
244 if (children
[i
] == None
|| ! blackbox
->validateWindow(children
[i
]))
247 XWindowAttributes attrib
;
248 if (XGetWindowAttributes(otk::OBDisplay::display
, children
[i
], &attrib
)) {
249 if (attrib
.override_redirect
) continue;
251 if (attrib
.map_state
!= IsUnmapped
) {
252 manageWindow(children
[i
]);
259 // call this again just in case a window we found updates the Strut list
260 updateAvailableArea();
264 BScreen::~BScreen(void) {
265 if (! managed
) return;
267 if (geom_pixmap
!= None
)
268 image_control
->removeImage(geom_pixmap
);
270 if (geom_window
!= None
)
271 XDestroyWindow(otk::OBDisplay::display
, geom_window
);
273 std::for_each(workspacesList
.begin(), workspacesList
.end(),
274 otk::PointerAssassin());
276 std::for_each(iconList
.begin(), iconList
.end(), otk::PointerAssassin());
278 while (! systrayWindowList
.empty())
279 removeSystrayWindow(systrayWindowList
[0]);
281 delete image_control
;
285 XFreeGC(otk::OBDisplay::display
, opGC
);
289 void BScreen::LoadStyle(void) {
290 otk::Configuration
style_conf(False
);
292 const char *sfile
= blackbox
->getStyleFilename();
294 style_conf
.setFile(sfile
);
295 if (! style_conf
.load()) {
296 style_conf
.setFile(DEFAULTSTYLE
);
297 if (! style_conf
.load())
298 style_conf
.create(); // hardcoded default values will be used.
302 // merge in the rc file
303 style_conf
.merge(config
->file(), True
);
305 resource
.wstyle
.load(style_conf
);
308 void BScreen::saveSloppyFocus(bool s
) {
309 resource
.sloppy_focus
= s
;
312 if (resource
.sloppy_focus
) {
313 fmodel
= "SloppyFocus";
314 if (resource
.auto_raise
) fmodel
+= " AutoRaise";
315 if (resource
.click_raise
) fmodel
+= " ClickRaise";
317 fmodel
= "ClickToFocus";
319 config
->setValue(screenstr
+ "focusModel", fmodel
);
323 void BScreen::saveAutoRaise(bool a
) {
324 resource
.auto_raise
= a
;
325 saveSloppyFocus(resource
.sloppy_focus
);
329 void BScreen::saveClickRaise(bool c
) {
330 resource
.click_raise
= c
;
331 saveSloppyFocus(resource
.sloppy_focus
);
335 void BScreen::saveImageDither(bool d
) {
336 image_control
->setDither(d
);
337 config
->setValue(screenstr
+ "imageDither", doImageDither());
341 void BScreen::saveOpaqueMove(bool o
) {
342 resource
.opaque_move
= o
;
343 config
->setValue(screenstr
+ "opaqueMove", resource
.opaque_move
);
347 void BScreen::saveFullMax(bool f
) {
348 resource
.full_max
= f
;
349 config
->setValue(screenstr
+ "fullMaximization", resource
.full_max
);
353 void BScreen::saveFocusNew(bool f
) {
354 resource
.focus_new
= f
;
355 config
->setValue(screenstr
+ "focusNewWindows", resource
.focus_new
);
359 void BScreen::saveFocusLast(bool f
) {
360 resource
.focus_last
= f
;
361 config
->setValue(screenstr
+ "focusLastWindow", resource
.focus_last
);
365 void BScreen::saveAAFonts(bool f
) {
366 resource
.aa_fonts
= f
;
367 config
->setValue(screenstr
+ "antialiasFonts", resource
.aa_fonts
);
372 void BScreen::saveShadowFonts(bool f
) {
373 resource
.shadow_fonts
= f
;
374 config
->setValue(screenstr
+ "dropShadowFonts", resource
.shadow_fonts
);
379 void BScreen::saveWindowToEdgeSnap(int s
) {
380 resource
.snap_to_edges
= s
;
383 switch (resource
.snap_to_edges
) {
384 case WindowNoSnap
: snap
= "NoSnap"; break;
385 case WindowResistance
: snap
= "Resistance"; break;
386 case WindowSnap
: default: snap
= "Snap"; break;
388 config
->setValue(screenstr
+ "windowToEdgeSnap", snap
);
392 void BScreen::saveWindowToWindowSnap(int s
) {
393 resource
.snap_to_windows
= s
;
396 switch (resource
.snap_to_windows
) {
397 case WindowNoSnap
: snap
= "NoSnap"; break;
398 case WindowResistance
: snap
= "Resistance"; break;
399 case WindowSnap
: default: snap
= "Snap"; break;
401 config
->setValue(screenstr
+ "windowToWindowSnap", snap
);
405 void BScreen::saveResizeZones(unsigned int z
) {
406 resource
.resize_zones
= z
;
407 config
->setValue(screenstr
+ "resizeZones", resource
.resize_zones
);
411 void BScreen::saveWindowCornerSnap(bool s
) {
412 resource
.window_corner_snap
= s
;
413 config
->setValue(screenstr
+ "windowCornerSnap",
414 resource
.window_corner_snap
);
418 void BScreen::saveWorkspaces(unsigned int w
) {
419 resource
.workspaces
= w
;
420 config
->setValue(screenstr
+ "workspaces", resource
.workspaces
);
424 void BScreen::savePlacementPolicy(int p
) {
425 resource
.placement_policy
= p
;
426 const char *placement
;
427 switch (resource
.placement_policy
) {
428 case CascadePlacement
: placement
= "CascadePlacement"; break;
429 case UnderMousePlacement
: placement
= "UnderMousePlacement"; break;
430 case ClickMousePlacement
: placement
= "ClickMousePlacement"; break;
431 case ColSmartPlacement
: placement
= "ColSmartPlacement"; break;
432 case RowSmartPlacement
: default: placement
= "RowSmartPlacement"; break;
434 config
->setValue(screenstr
+ "windowPlacement", placement
);
438 void BScreen::saveResistanceSize(int s
) {
439 resource
.resistance_size
= s
;
440 config
->setValue(screenstr
+ "resistanceSize",
441 resource
.resistance_size
);
445 void BScreen::saveSnapThreshold(int t
) {
446 resource
.snap_threshold
= t
;
447 config
->setValue(screenstr
+ "edgeSnapThreshold",
448 resource
.snap_threshold
);
452 void BScreen::saveSnapOffset(int t
) {
453 resource
.snap_offset
= t
;
454 config
->setValue(screenstr
+ "edgeSnapOffset",
455 resource
.snap_offset
);
459 void BScreen::saveRowPlacementDirection(int d
) {
460 resource
.row_direction
= d
;
461 config
->setValue(screenstr
+ "rowPlacementDirection",
462 resource
.row_direction
== LeftRight
?
463 "LeftToRight" : "RightToLeft");
467 void BScreen::saveColPlacementDirection(int d
) {
468 resource
.col_direction
= d
;
469 config
->setValue(screenstr
+ "colPlacementDirection",
470 resource
.col_direction
== TopBottom
?
471 "TopToBottom" : "BottomToTop");
475 void BScreen::saveStrftimeFormat(const std::string
& format
) {
476 resource
.strftime_format
= format
;
477 config
->setValue(screenstr
+ "strftimeFormat", resource
.strftime_format
);
481 void BScreen::saveWorkspaceNames() {
484 for (unsigned int i
= 0; i
< workspacesList
.size(); ++i
) {
485 names
+= workspacesList
[i
]->getName();
486 if (i
< workspacesList
.size() - 1)
490 config
->setValue(screenstr
+ "workspaceNames", names
);
494 void BScreen::savePlaceIgnoreShaded(bool i
) {
495 resource
.ignore_shaded
= i
;
496 config
->setValue(screenstr
+ "placementIgnoreShaded",
497 resource
.ignore_shaded
);
501 void BScreen::savePlaceIgnoreMaximized(bool i
) {
502 resource
.ignore_maximized
= i
;
503 config
->setValue(screenstr
+ "placementIgnoreMaximized",
504 resource
.ignore_maximized
);
508 void BScreen::saveAllowScrollLock(bool a
) {
509 resource
.allow_scroll_lock
= a
;
510 config
->setValue(screenstr
+ "disableBindingsWithScrollLock",
511 resource
.allow_scroll_lock
);
515 void BScreen::saveWorkspaceWarping(bool w
) {
516 resource
.workspace_warping
= w
;
517 config
->setValue(screenstr
+ "workspaceWarping",
518 resource
.workspace_warping
);
522 void BScreen::saveRootScrollDirection(int d
) {
523 resource
.root_scroll
= d
;
525 switch (resource
.root_scroll
) {
526 case NoScroll
: dir
= "None"; break;
527 case ReverseScroll
: dir
= "Reverse"; break;
528 case NormalScroll
: default: dir
= "Normal"; break;
530 config
->setValue(screenstr
+ "rootScrollDirection", dir
);
534 void BScreen::save_rc(void) {
535 saveSloppyFocus(resource
.sloppy_focus
);
536 saveAutoRaise(resource
.auto_raise
);
537 saveImageDither(doImageDither());
538 saveShadowFonts(resource
.shadow_fonts
);
539 saveAAFonts(resource
.aa_fonts
);
540 saveResizeZones(resource
.resize_zones
);
541 saveOpaqueMove(resource
.opaque_move
);
542 saveFullMax(resource
.full_max
);
543 saveFocusNew(resource
.focus_new
);
544 saveFocusLast(resource
.focus_last
);
545 saveWindowToWindowSnap(resource
.snap_to_windows
);
546 saveWindowToEdgeSnap(resource
.snap_to_edges
);
547 saveWindowCornerSnap(resource
.window_corner_snap
);
548 saveWorkspaces(resource
.workspaces
);
549 savePlacementPolicy(resource
.placement_policy
);
550 saveSnapThreshold(resource
.snap_threshold
);
551 saveSnapOffset(resource
.snap_offset
);
552 saveResistanceSize(resource
.resistance_size
);
553 saveRowPlacementDirection(resource
.row_direction
);
554 saveColPlacementDirection(resource
.col_direction
);
555 saveStrftimeFormat(resource
.strftime_format
);
556 savePlaceIgnoreShaded(resource
.ignore_shaded
);
557 savePlaceIgnoreMaximized(resource
.ignore_maximized
);
558 saveAllowScrollLock(resource
.allow_scroll_lock
);
559 saveWorkspaceWarping(resource
.workspace_warping
);
560 saveRootScrollDirection(resource
.root_scroll
);
564 void BScreen::load_rc(void) {
568 if (! config
->getValue(screenstr
+ "fullMaximization", resource
.full_max
))
569 resource
.full_max
= false;
571 if (! config
->getValue(screenstr
+ "focusNewWindows", resource
.focus_new
))
572 resource
.focus_new
= false;
574 if (! config
->getValue(screenstr
+ "focusLastWindow", resource
.focus_last
))
575 resource
.focus_last
= false;
577 if (! config
->getValue(screenstr
+ "workspaces", resource
.workspaces
))
578 resource
.workspaces
= 1;
580 if (! config
->getValue(screenstr
+ "opaqueMove", resource
.opaque_move
))
581 resource
.opaque_move
= false;
583 if (! config
->getValue(screenstr
+ "antialiasFonts", resource
.aa_fonts
))
584 resource
.aa_fonts
= true;
586 if (! resource
.aa_fonts
||
587 ! config
->getValue(screenstr
+ "dropShadowFonts", resource
.shadow_fonts
))
588 resource
.shadow_fonts
= false;
590 if (! config
->getValue(screenstr
+ "resizeZones", resource
.resize_zones
) ||
591 (resource
.resize_zones
!= 1 && resource
.resize_zones
!= 2 &&
592 resource
.resize_zones
!= 4))
593 resource
.resize_zones
= 4;
595 resource
.snap_to_windows
= WindowResistance
;
596 if (config
->getValue(screenstr
+ "windowToWindowSnap", s
)) {
598 resource
.snap_to_windows
= WindowNoSnap
;
599 else if (s
== "Snap")
600 resource
.snap_to_windows
= WindowSnap
;
603 resource
.snap_to_edges
= WindowResistance
;
604 if (config
->getValue(screenstr
+ "windowToEdgeSnap", s
)) {
606 resource
.snap_to_edges
= WindowNoSnap
;
607 else if (s
== "Snap")
608 resource
.snap_to_edges
= WindowSnap
;
611 if (! config
->getValue(screenstr
+ "windowCornerSnap",
612 resource
.window_corner_snap
))
613 resource
.window_corner_snap
= true;
615 if (! config
->getValue(screenstr
+ "imageDither", b
))
617 image_control
->setDither(b
);
619 if (! config
->getValue(screenstr
+ "edgeSnapOffset",
620 resource
.snap_offset
))
621 resource
.snap_offset
= 0;
622 if (resource
.snap_offset
> 50) // sanity check, setting this huge would
623 resource
.snap_offset
= 50; // seriously suck.
625 if (! config
->getValue(screenstr
+ "edgeSnapThreshold",
626 resource
.snap_threshold
))
627 resource
.snap_threshold
= 4;
629 if (! config
->getValue(screenstr
+ "resistanceSize",
630 resource
.resistance_size
))
631 resource
.resistance_size
= 18;
633 if (config
->getValue(screenstr
+ "rowPlacementDirection", s
) &&
635 resource
.row_direction
= RightLeft
;
637 resource
.row_direction
= LeftRight
;
639 if (config
->getValue(screenstr
+ "colPlacementDirection", s
) &&
641 resource
.col_direction
= BottomTop
;
643 resource
.col_direction
= TopBottom
;
645 if (config
->getValue(screenstr
+ "workspaceNames", s
)) {
646 otk::OBProperty::StringVect workspaceNames
;
648 string::const_iterator it
= s
.begin(), end
= s
.end();
650 string::const_iterator tmp
= it
; // current string.begin()
651 it
= std::find(tmp
, end
, ','); // look for comma between tmp and end
652 workspaceNames
.push_back(string(tmp
, it
)); // s[tmp:it]
658 xatom
->set(getRootWindow(), otk::OBProperty::net_desktop_names
,
659 otk::OBProperty::utf8
, workspaceNames
);
662 resource
.sloppy_focus
= true;
663 resource
.auto_raise
= false;
664 resource
.click_raise
= false;
665 if (config
->getValue(screenstr
+ "focusModel", s
)) {
666 if (s
.find("ClickToFocus") != string::npos
) {
667 resource
.sloppy_focus
= false;
670 if (s
.find("AutoRaise") != string::npos
)
671 resource
.auto_raise
= true;
672 if (s
.find("ClickRaise") != string::npos
)
673 resource
.click_raise
= true;
677 if (config
->getValue(screenstr
+ "windowPlacement", s
)) {
678 if (s
== "CascadePlacement")
679 resource
.placement_policy
= CascadePlacement
;
680 else if (s
== "UnderMousePlacement")
681 resource
.placement_policy
= UnderMousePlacement
;
682 else if (s
== "ClickMousePlacement")
683 resource
.placement_policy
= ClickMousePlacement
;
684 else if (s
== "ColSmartPlacement")
685 resource
.placement_policy
= ColSmartPlacement
;
686 else //if (s == "RowSmartPlacement")
687 resource
.placement_policy
= RowSmartPlacement
;
689 resource
.placement_policy
= RowSmartPlacement
;
691 if (! config
->getValue(screenstr
+ "strftimeFormat",
692 resource
.strftime_format
))
693 resource
.strftime_format
= "%I:%M %p";
695 if (! config
->getValue(screenstr
+ "placementIgnoreShaded",
696 resource
.ignore_shaded
))
697 resource
.ignore_shaded
= true;
699 if (! config
->getValue(screenstr
+ "placementIgnoreMaximized",
700 resource
.ignore_maximized
))
701 resource
.ignore_maximized
= true;
703 if (! config
->getValue(screenstr
+ "disableBindingsWithScrollLock",
704 resource
.allow_scroll_lock
))
705 resource
.allow_scroll_lock
= false;
707 if (! config
->getValue(screenstr
+ "workspaceWarping",
708 resource
.workspace_warping
))
709 resource
.workspace_warping
= false;
711 resource
.root_scroll
= NormalScroll
;
712 if (config
->getValue(screenstr
+ "rootScrollDirection", s
)) {
714 resource
.root_scroll
= NoScroll
;
715 else if (s
== "Reverse")
716 resource
.root_scroll
= ReverseScroll
;
721 void BScreen::changeWorkspaceCount(unsigned int new_count
) {
722 assert(new_count
> 0);
724 if (new_count
< workspacesList
.size()) {
726 for (unsigned int i
= workspacesList
.size(); i
> new_count
; --i
)
727 removeLastWorkspace();
728 // removeLast already sets the current workspace to the
729 // last available one.
730 } else if (new_count
> workspacesList
.size()) {
732 for(unsigned int i
= workspacesList
.size(); i
< new_count
; ++i
)
738 void BScreen::reconfigure(void) {
739 // don't reconfigure while saving the initial rc file, it's a waste and it
740 // breaks somethings (workspace names)
741 if (blackbox
->state() == Openbox::State_Starting
) return;
746 // we need to do this explicitly, because just loading this value from the rc
748 changeWorkspaceCount(resource
.workspaces
);
751 gcv
.foreground
= WhitePixel(otk::OBDisplay::display
,
753 gcv
.function
= GXinvert
;
754 gcv
.subwindow_mode
= IncludeInferiors
;
755 XChangeGC(otk::OBDisplay::display
, opGC
,
756 GCForeground
| GCFunction
| GCSubwindowMode
, &gcv
);
758 const char *s
= "0: 0000 x 0: 0000";
760 geom_w
= resource
.wstyle
.font
->measureString(s
) + resource
.wstyle
.bevel_width
* 2;
761 geom_h
= resource
.wstyle
.font
->height() + resource
.wstyle
.bevel_width
* 2;
763 otk::BTexture
* texture
= &(resource
.wstyle
.l_focus
);
764 geom_pixmap
= texture
->render(geom_w
, geom_h
, geom_pixmap
);
765 if (geom_pixmap
== ParentRelative
) {
766 texture
= &(resource
.wstyle
.t_focus
);
767 geom_pixmap
= texture
->render(geom_w
, geom_h
, geom_pixmap
);
770 XSetWindowBackground(otk::OBDisplay::display
, geom_window
,
771 texture
->color().pixel());
773 XSetWindowBackgroundPixmap(otk::OBDisplay::display
,
774 geom_window
, geom_pixmap
);
776 XSetWindowBorderWidth(otk::OBDisplay::display
, geom_window
,
777 resource
.wstyle
.border_width
);
778 XSetWindowBorder(otk::OBDisplay::display
, geom_window
,
779 resource
.wstyle
.border_color
.pixel());
781 typedef std::vector
<int> SubList
;
782 SubList remember_subs
;
786 std::for_each(workspacesList
.begin(), workspacesList
.end(),
787 std::mem_fun(&Workspace::reconfigure
));
789 BlackboxWindowList::iterator iit
= iconList
.begin();
790 for (; iit
!= iconList
.end(); ++iit
) {
791 BlackboxWindow
*bw
= *iit
;
792 if (bw
->validateClient())
796 otk::BImageControl::timeout(image_control
);
801 void BScreen::addIcon(BlackboxWindow
*w
) {
804 w
->setWorkspace(otk::BSENTINEL
);
805 w
->setWindowNumber(iconList
.size());
807 iconList
.push_back(w
);
811 void BScreen::removeIcon(BlackboxWindow
*w
) {
816 BlackboxWindowList::iterator it
= iconList
.begin(),
817 end
= iconList
.end();
818 for (int i
= 0; it
!= end
; ++it
)
819 (*it
)->setWindowNumber(i
++);
823 BlackboxWindow
*BScreen::getIcon(unsigned int index
) {
824 if (index
< iconList
.size()) {
825 BlackboxWindowList::iterator it
= iconList
.begin();
826 while (index
-- > 0) // increment to index
831 return (BlackboxWindow
*) 0;
835 unsigned int BScreen::addWorkspace(void) {
836 Workspace
*wkspc
= new Workspace(this, workspacesList
.size());
837 workspacesList
.push_back(wkspc
);
838 saveWorkspaces(getWorkspaceCount());
839 saveWorkspaceNames();
841 return workspacesList
.size();
845 unsigned int BScreen::removeLastWorkspace(void) {
846 if (workspacesList
.size() == 1)
849 Workspace
*wkspc
= workspacesList
.back();
851 if (current_workspace
->getID() == wkspc
->getID())
852 changeWorkspaceID(current_workspace
->getID() - 1);
856 workspacesList
.pop_back();
859 saveWorkspaces(getWorkspaceCount());
860 saveWorkspaceNames();
862 updateNetizenWorkspaceCount();
864 return workspacesList
.size();
868 void BScreen::changeWorkspaceID(unsigned int id
) {
869 if (! current_workspace
|| id
== current_workspace
->getID()) return;
871 BlackboxWindow
*focused
= blackbox
->getFocusedWindow();
872 if (focused
&& focused
->getScreen() == this) {
873 assert(focused
->isStuck() ||
874 focused
->getWorkspaceNumber() == current_workspace
->getID());
876 current_workspace
->setLastFocusedWindow(focused
);
878 // if no window had focus, no need to store a last focus
879 current_workspace
->setLastFocusedWindow((BlackboxWindow
*) 0);
882 // when we switch workspaces, unfocus whatever was focused if it is going
884 if (focused
&& ! focused
->isStuck())
885 blackbox
->setFocusedWindow((BlackboxWindow
*) 0);
887 current_workspace
->hideAll();
889 current_workspace
= getWorkspace(id
);
891 xatom
->set(getRootWindow(), otk::OBProperty::net_current_desktop
,
892 otk::OBProperty::Atom_Cardinal
, id
);
894 current_workspace
->showAll();
899 BlackboxWindow
*win
= (BlackboxWindow
*) 0;
902 XSync(otk::OBDisplay::display
, False
);
904 // If sloppy focus and we can find the client window under the pointer,
906 if (resource
.sloppy_focus
&&
907 XQueryPointer(otk::OBDisplay::display
, getRootWindow(), &r
, &c
,
908 &rx
, &ry
, &x
, &y
, &m
) &&
910 if ( (win
= blackbox
->searchWindow(c
)) )
911 f
= win
->setInputFocus();
914 // If that fails, and we're doing focus_last, try to focus the last window.
915 if (! f
&& resource
.focus_last
&&
916 (win
= current_workspace
->getLastFocusedWindow()))
917 f
= win
->setInputFocus();
920 if we found a focus target, then we set the focused window explicitly
921 because it is possible to switch off this workspace before the x server
922 generates the FocusIn event for the window. if that happens, openbox would
923 lose track of what window was the 'LastFocused' window on the workspace.
925 if we did not find a focus target, then set the current focused window to
929 blackbox
->setFocusedWindow(win
);
931 blackbox
->setFocusedWindow((BlackboxWindow
*) 0);
936 * Set the _NET_CLIENT_LIST root window property.
938 void BScreen::updateClientList(void) {
939 if (windowList
.size() > 0) {
940 Window
*windows
= new Window
[windowList
.size()];
941 Window
*win_it
= windows
;
942 BlackboxWindowList::iterator it
= windowList
.begin();
943 const BlackboxWindowList::iterator end
= windowList
.end();
944 for (; it
!= end
; ++it
, ++win_it
)
945 *win_it
= (*it
)->getClientWindow();
946 xatom
->set(getRootWindow(), otk::OBProperty::net_client_list
,
947 otk::OBProperty::Atom_Window
, windows
, windowList
.size());
950 xatom
->set(getRootWindow(), otk::OBProperty::net_client_list
,
951 otk::OBProperty::Atom_Window
, 0, 0);
953 updateStackingList();
958 * Set the _NET_CLIENT_LIST_STACKING root window property.
960 void BScreen::updateStackingList(void) {
962 BlackboxWindowList stack_order
;
965 * Get the stacking order from all of the workspaces.
966 * We start with the current workspace so that the sticky windows will be
967 * in the right order on the current workspace.
968 * XXX: Do we need to have sticky windows in the list once for each workspace?
970 getCurrentWorkspace()->appendStackOrder(stack_order
);
971 for (unsigned int i
= 0; i
< getWorkspaceCount(); ++i
)
972 if (i
!= getCurrentWorkspaceID())
973 getWorkspace(i
)->appendStackOrder(stack_order
);
975 if (stack_order
.size() > 0) {
976 // set the client list atoms
977 Window
*windows
= new Window
[stack_order
.size()];
978 Window
*win_it
= windows
;
979 BlackboxWindowList::iterator it
= stack_order
.begin(),
980 end
= stack_order
.end();
981 for (; it
!= end
; ++it
, ++win_it
)
982 *win_it
= (*it
)->getClientWindow();
983 xatom
->set(getRootWindow(), otk::OBProperty::net_client_list_stacking
,
984 otk::OBProperty::Atom_Window
, windows
, stack_order
.size());
987 xatom
->set(getRootWindow(), otk::OBProperty::net_client_list_stacking
,
988 otk::OBProperty::Atom_Window
, 0, 0);
992 void BScreen::addSystrayWindow(Window window
) {
993 XGrabServer(otk::OBDisplay::display
);
995 XSelectInput(otk::OBDisplay::display
, window
, StructureNotifyMask
);
996 systrayWindowList
.push_back(window
);
997 xatom
->set(getRootWindow(), otk::OBProperty::kde_net_system_tray_windows
,
998 otk::OBProperty::Atom_Window
,
999 &systrayWindowList
[0], systrayWindowList
.size());
1000 blackbox
->saveSystrayWindowSearch(window
, this);
1002 XUngrabServer(otk::OBDisplay::display
);
1006 void BScreen::removeSystrayWindow(Window window
) {
1007 XGrabServer(otk::OBDisplay::display
);
1009 WindowList::iterator it
= systrayWindowList
.begin();
1010 const WindowList::iterator end
= systrayWindowList
.end();
1011 for (; it
!= end
; ++it
)
1012 if (*it
== window
) {
1013 systrayWindowList
.erase(it
);
1014 xatom
->set(getRootWindow(),
1015 otk::OBProperty::kde_net_system_tray_windows
,
1016 otk::OBProperty::Atom_Window
,
1017 &systrayWindowList
[0], systrayWindowList
.size());
1018 blackbox
->removeSystrayWindowSearch(window
);
1019 XSelectInput(otk::OBDisplay::display
, window
, NoEventMask
);
1023 assert(it
!= end
); // not a systray window
1025 XUngrabServer(otk::OBDisplay::display
);
1029 void BScreen::manageWindow(Window w
) {
1030 // is the window a KDE systray window?
1032 if (xatom
->get(w
, otk::OBProperty::kde_net_wm_system_tray_window_for
,
1033 otk::OBProperty::Atom_Window
, &systray
) &&
1036 addSystrayWindow(w
);
1040 // is the window a docking app
1041 XWMHints
*wmhint
= XGetWMHints(otk::OBDisplay::display
, w
);
1042 if (wmhint
&& (wmhint
->flags
& StateHint
) &&
1043 wmhint
->initial_state
== WithdrawnState
) {
1044 //slit->addClient(w);
1048 new BlackboxWindow(blackbox
, w
, this);
1050 BlackboxWindow
*win
= blackbox
->searchWindow(w
);
1054 if (win
->isDesktop()) {
1055 desktopWindowList
.push_back(win
->getFrameWindow());
1056 } else { // if (win->isNormal()) {
1057 // don't list desktop windows as managed windows
1058 windowList
.push_back(win
);
1061 if (win
->isTopmost())
1062 specialWindowList
.push_back(win
->getFrameWindow());
1065 XMapRequestEvent mre
;
1067 if (blackbox
->state() == Openbox::State_Starting
&&
1069 win
->restoreAttributes();
1070 win
->mapRequestEvent(&mre
);
1074 void BScreen::unmanageWindow(BlackboxWindow
*w
, bool remap
) {
1075 // is the window a KDE systray window?
1077 if (xatom
->get(w
->getClientWindow(),
1078 otk::OBProperty::kde_net_wm_system_tray_window_for
,
1079 otk::OBProperty::Atom_Window
, &systray
) &&
1082 removeSystrayWindow(w
->getClientWindow());
1088 // Remove the modality so that its parent won't try to re-focus the window
1089 if (w
->isModal()) w
->setModal(False
);
1091 if (w
->getWorkspaceNumber() != otk::BSENTINEL
&&
1092 w
->getWindowNumber() != otk::BSENTINEL
) {
1093 getWorkspace(w
->getWorkspaceNumber())->removeWindow(w
);
1095 for (unsigned int i
= 0; i
< getNumberOfWorkspaces(); ++i
)
1096 if (i
!= w
->getWorkspaceNumber())
1097 getWorkspace(i
)->removeWindow(w
, True
);
1099 } else if (w
->isIconic())
1102 if (w
->isDesktop()) {
1103 WindowList::iterator it
= desktopWindowList
.begin();
1104 const WindowList::iterator end
= desktopWindowList
.end();
1105 for (; it
!= end
; ++it
)
1106 if (*it
== w
->getFrameWindow()) {
1107 desktopWindowList
.erase(it
);
1110 assert(it
!= end
); // the window wasnt a desktop window?
1111 } else { // if (w->isNormal()) {
1112 // we don't list desktop windows as managed windows
1113 windowList
.remove(w
);
1116 if (w
->isTopmost()) {
1117 WindowList::iterator it
= specialWindowList
.begin();
1118 const WindowList::iterator end
= specialWindowList
.end();
1119 for (; it
!= end
; ++it
)
1120 if (*it
== w
->getFrameWindow()) {
1121 specialWindowList
.erase(it
);
1124 assert(it
!= end
); // the window wasnt a special window?
1128 if (blackbox
->getFocusedWindow() == w
)
1129 blackbox
->setFocusedWindow((BlackboxWindow
*) 0);
1132 some managed windows can also be window group controllers. when
1133 unmanaging such windows, we should also delete the window group.
1135 BWindowGroup
*group
= blackbox
->searchGroup(w
->getClientWindow());
1142 void BScreen::updateWorkArea(void) {
1143 if (workspacesList
.size() > 0) {
1144 unsigned long *dims
= new unsigned long[4 * workspacesList
.size()];
1145 for (unsigned int i
= 0, m
= workspacesList
.size(); i
< m
; ++i
) {
1146 // XXX: this could be different for each workspace
1147 const otk::Rect
&area
= availableArea();
1148 dims
[(i
* 4) + 0] = area
.x();
1149 dims
[(i
* 4) + 1] = area
.y();
1150 dims
[(i
* 4) + 2] = area
.width();
1151 dims
[(i
* 4) + 3] = area
.height();
1153 xatom
->set(getRootWindow(), otk::OBProperty::net_workarea
,
1154 otk::OBProperty::Atom_Cardinal
,
1155 dims
, 4 * workspacesList
.size());
1158 xatom
->set(getRootWindow(), otk::OBProperty::net_workarea
,
1159 otk::OBProperty::Atom_Cardinal
, 0, 0);
1163 void BScreen::updateNetizenWorkspaceCount(void) {
1164 xatom
->set(getRootWindow(), otk::OBProperty::net_number_of_desktops
,
1165 otk::OBProperty::Atom_Cardinal
, workspacesList
.size());
1171 void BScreen::updateNetizenWindowFocus(void) {
1172 Window f
= ((blackbox
->getFocusedWindow()) ?
1173 blackbox
->getFocusedWindow()->getClientWindow() : None
);
1175 xatom
->set(getRootWindow(), otk::OBProperty::net_active_window
,
1176 otk::OBProperty::Atom_Window
, f
);
1180 void BScreen::raiseWindows(Window
*workspace_stack
, unsigned int num
) {
1181 // the 13 represents the number of blackbox windows such as menus
1187 Window
*session_stack
= new
1188 Window
[(num
+ specialWindowList
.size() + bbwins
)];
1189 unsigned int i
= 0, k
= num
;
1191 WindowList::iterator sit
, send
= specialWindowList
.end();
1192 for (sit
= specialWindowList
.begin(); sit
!= send
; ++sit
)
1193 *(session_stack
+ i
++) = *sit
;
1196 *(session_stack
+ i
++) = *(workspace_stack
+ k
);
1198 XRestackWindows(otk::OBDisplay::display
, session_stack
, i
);
1200 delete [] session_stack
;
1202 updateStackingList();
1206 void BScreen::lowerWindows(Window
*workspace_stack
, unsigned int num
) {
1207 assert(num
> 0); // this would cause trouble in the XRaiseWindow call
1209 Window
*session_stack
= new Window
[(num
+ desktopWindowList
.size())];
1210 unsigned int i
= 0, k
= num
;
1212 XLowerWindow(otk::OBDisplay::display
, workspace_stack
[0]);
1215 *(session_stack
+ i
++) = *(workspace_stack
+ k
);
1217 WindowList::iterator dit
= desktopWindowList
.begin();
1218 const WindowList::iterator d_end
= desktopWindowList
.end();
1219 for (; dit
!= d_end
; ++dit
)
1220 *(session_stack
+ i
++) = *dit
;
1222 XRestackWindows(otk::OBDisplay::display
, session_stack
, i
);
1224 delete [] session_stack
;
1226 updateStackingList();
1230 void BScreen::reassociateWindow(BlackboxWindow
*w
, unsigned int wkspc_id
,
1231 bool ignore_sticky
) {
1234 if (wkspc_id
== otk::BSENTINEL
)
1235 wkspc_id
= current_workspace
->getID();
1237 if (w
->getWorkspaceNumber() == wkspc_id
)
1240 if (w
->isIconic()) {
1242 getWorkspace(wkspc_id
)->addWindow(w
);
1244 for (unsigned int i
= 0; i
< getNumberOfWorkspaces(); ++i
)
1245 if (i
!= w
->getWorkspaceNumber())
1246 getWorkspace(i
)->addWindow(w
, True
);
1247 } else if (ignore_sticky
|| ! w
->isStuck()) {
1250 getWorkspace(w
->getWorkspaceNumber())->removeWindow(w
);
1251 getWorkspace(wkspc_id
)->addWindow(w
);
1253 updateStackingList();
1257 void BScreen::propagateWindowName(const BlackboxWindow
*bw
) {
1258 if (bw
->isIconic()) {
1264 void BScreen::nextFocus(void) const {
1265 BlackboxWindow
*focused
= blackbox
->getFocusedWindow(),
1269 focused
->getScreen()->getScreenNumber() == getScreenNumber() &&
1270 current_workspace
->getCount() > 1) {
1272 next
= current_workspace
->getNextWindowInList(next
);
1273 } while (next
!= focused
&& ! next
->setInputFocus());
1275 if (next
!= focused
)
1276 current_workspace
->raiseWindow(next
);
1277 } else if (current_workspace
->getCount() > 0) {
1278 next
= current_workspace
->getTopWindowOnStack();
1279 next
->setInputFocus();
1280 current_workspace
->raiseWindow(next
);
1285 void BScreen::prevFocus(void) const {
1286 BlackboxWindow
*focused
= blackbox
->getFocusedWindow(),
1290 // if window is not on this screen, ignore it
1291 if (focused
->getScreen()->getScreenNumber() != getScreenNumber())
1292 focused
= (BlackboxWindow
*) 0;
1296 focused
->getScreen()->getScreenNumber() == getScreenNumber() &&
1297 current_workspace
->getCount() > 1) {
1298 // next is the next window to receive focus, current is a place holder
1300 next
= current_workspace
->getPrevWindowInList(next
);
1301 } while (next
!= focused
&& ! next
->setInputFocus());
1303 if (next
!= focused
)
1304 current_workspace
->raiseWindow(next
);
1305 } else if (current_workspace
->getCount() > 0) {
1306 next
= current_workspace
->getTopWindowOnStack();
1307 next
->setInputFocus();
1308 current_workspace
->raiseWindow(next
);
1313 void BScreen::raiseFocus(void) const {
1314 BlackboxWindow
*focused
= blackbox
->getFocusedWindow();
1318 // if on this Screen, raise it
1319 if (focused
->getScreen()->getScreenNumber() == getScreenNumber()) {
1320 Workspace
*workspace
= getWorkspace(focused
->getWorkspaceNumber());
1321 workspace
->raiseWindow(focused
);
1326 void BScreen::shutdown(void) {
1327 XSelectInput(otk::OBDisplay::display
, getRootWindow(), NoEventMask
);
1328 XSync(otk::OBDisplay::display
, False
);
1330 while(! windowList
.empty())
1331 unmanageWindow(windowList
.front(), True
);
1333 while(! desktopWindowList
.empty()) {
1334 BlackboxWindow
*win
= blackbox
->searchWindow(desktopWindowList
.front());
1336 unmanageWindow(win
, True
);
1341 void BScreen::showPosition(int x
, int y
) {
1342 if (! geom_visible
) {
1343 XMoveResizeWindow(otk::OBDisplay::display
, geom_window
,
1344 (getWidth() - geom_w
) / 2,
1345 (getHeight() - geom_h
) / 2, geom_w
, geom_h
);
1346 XMapWindow(otk::OBDisplay::display
, geom_window
);
1347 XRaiseWindow(otk::OBDisplay::display
, geom_window
);
1349 geom_visible
= True
;
1354 sprintf(label
, "X: %4d x Y: %4d", x
, y
);
1356 XClearWindow(otk::OBDisplay::display
, geom_window
);
1358 resource
.wstyle
.font
->drawString(geom_window
,
1359 resource
.wstyle
.bevel_width
, resource
.wstyle
.bevel_width
,
1360 resource
.wstyle
.l_text_focus
,
1365 void BScreen::showGeometry(unsigned int gx
, unsigned int gy
) {
1366 if (! geom_visible
) {
1367 XMoveResizeWindow(otk::OBDisplay::display
, geom_window
,
1368 (getWidth() - geom_w
) / 2,
1369 (getHeight() - geom_h
) / 2, geom_w
, geom_h
);
1370 XMapWindow(otk::OBDisplay::display
, geom_window
);
1371 XRaiseWindow(otk::OBDisplay::display
, geom_window
);
1373 geom_visible
= True
;
1378 sprintf(label
, "W: %4d x H: %4d", gx
, gy
);
1380 XClearWindow(otk::OBDisplay::display
, geom_window
);
1382 resource
.wstyle
.font
->drawString(geom_window
,
1383 resource
.wstyle
.bevel_width
, resource
.wstyle
.bevel_width
,
1384 resource
.wstyle
.l_text_focus
,
1389 void BScreen::hideGeometry(void) {
1391 XUnmapWindow(otk::OBDisplay::display
, geom_window
);
1392 geom_visible
= False
;
1397 void BScreen::addStrut(otk::Strut
*strut
) {
1398 strutList
.push_back(strut
);
1402 void BScreen::removeStrut(otk::Strut
*strut
) {
1403 strutList
.remove(strut
);
1407 const otk::Rect
& BScreen::availableArea(void) const {
1409 return getRect(); // return the full screen
1415 const RectList
& BScreen::allAvailableAreas(void) const {
1416 assert(isXineramaActive());
1417 assert(xineramaUsableArea
.size() > 0);
1418 fprintf(stderr
, "1found x %d y %d w %d h %d\n",
1419 xineramaUsableArea
[0].x(), xineramaUsableArea
[0].y(),
1420 xineramaUsableArea
[0].width(), xineramaUsableArea
[0].height());
1421 return xineramaUsableArea
;
1426 void BScreen::updateAvailableArea(void) {
1427 otk::Rect old_area
= usableArea
;
1428 usableArea
= getRect(); // reset to full screen
1431 // reset to the full areas
1432 if (isXineramaActive())
1433 xineramaUsableArea
= getXineramaAreas();
1436 /* these values represent offsets from the screen edge
1437 * we look for the biggest offset on each edge and then apply them
1439 * do not be confused by the similarity to the names of Rect's members
1441 unsigned int current_left
= 0, current_right
= 0, current_top
= 0,
1444 StrutList::const_iterator it
= strutList
.begin(), end
= strutList
.end();
1446 for(; it
!= end
; ++it
) {
1447 otk::Strut
*strut
= *it
;
1448 if (strut
->left
> current_left
)
1449 current_left
= strut
->left
;
1450 if (strut
->top
> current_top
)
1451 current_top
= strut
->top
;
1452 if (strut
->right
> current_right
)
1453 current_right
= strut
->right
;
1454 if (strut
->bottom
> current_bottom
)
1455 current_bottom
= strut
->bottom
;
1458 usableArea
.setPos(current_left
, current_top
);
1459 usableArea
.setSize(usableArea
.width() - (current_left
+ current_right
),
1460 usableArea
.height() - (current_top
+ current_bottom
));
1463 if (isXineramaActive()) {
1464 // keep each of the ximerama-defined areas inside the strut
1465 RectList::iterator xit
, xend
= xineramaUsableArea
.end();
1466 for (xit
= xineramaUsableArea
.begin(); xit
!= xend
; ++xit
) {
1467 if (xit
->x() < usableArea
.x()) {
1468 xit
->setX(usableArea
.x());
1469 xit
->setWidth(xit
->width() - usableArea
.x());
1471 if (xit
->y() < usableArea
.y()) {
1472 xit
->setY(usableArea
.y());
1473 xit
->setHeight(xit
->height() - usableArea
.y());
1475 if (xit
->x() + xit
->width() > usableArea
.width())
1476 xit
->setWidth(usableArea
.width() - xit
->x());
1477 if (xit
->y() + xit
->height() > usableArea
.height())
1478 xit
->setHeight(usableArea
.height() - xit
->y());
1483 if (old_area
!= usableArea
) {
1484 BlackboxWindowList::iterator it
= windowList
.begin(),
1485 end
= windowList
.end();
1486 for (; it
!= end
; ++it
)
1487 if ((*it
)->isMaximized()) (*it
)->remaximize();
1494 Workspace
* BScreen::getWorkspace(unsigned int index
) const {
1495 assert(index
< workspacesList
.size());
1496 return workspacesList
[index
];
1500 void BScreen::buttonPressEvent(const XButtonEvent
*xbutton
) {
1501 if (xbutton
->button
== 1) {
1502 if (! isRootColormapInstalled())
1503 image_control
->installRootColormap();
1506 } else if ((xbutton
->button
== 4 && resource
.root_scroll
== NormalScroll
) ||
1507 (xbutton
->button
== 5 && resource
.root_scroll
== ReverseScroll
)) {
1508 if (getCurrentWorkspaceID() >= getWorkspaceCount() - 1)
1509 changeWorkspaceID(0);
1511 changeWorkspaceID(getCurrentWorkspaceID() + 1);
1513 } else if ((xbutton
->button
== 5 && resource
.root_scroll
== NormalScroll
) ||
1514 (xbutton
->button
== 4 && resource
.root_scroll
== ReverseScroll
)) {
1515 if (getCurrentWorkspaceID() == 0)
1516 changeWorkspaceID(getWorkspaceCount() - 1);
1518 changeWorkspaceID(getCurrentWorkspaceID() - 1);
1523 void BScreen::propertyNotifyEvent(const XPropertyEvent
*pe
) {
1524 if (pe
->atom
== xatom
->atom(otk::OBProperty::net_desktop_names
)) {
1525 // _NET_WM_DESKTOP_NAMES
1526 WorkspaceList::iterator it
= workspacesList
.begin();
1527 const WorkspaceList::iterator end
= workspacesList
.end();
1528 for (; it
!= end
; ++it
) {
1529 (*it
)->readName(); // re-read its name from the window property
1530 //workspacemenu->changeWorkspaceLabel((*it)->getID(), (*it)->getName());
1532 //workspacemenu->update();
1533 saveWorkspaceNames();
1538 void BScreen::toggleFocusModel(FocusModel model
) {
1539 std::for_each(windowList
.begin(), windowList
.end(),
1540 std::mem_fun(&BlackboxWindow::ungrabButtons
));
1542 if (model
== SloppyFocus
) {
1543 saveSloppyFocus(True
);
1545 // we're cheating here to save writing the config file 3 times
1546 resource
.auto_raise
= False
;
1547 resource
.click_raise
= False
;
1548 saveSloppyFocus(False
);
1551 std::for_each(windowList
.begin(), windowList
.end(),
1552 std::mem_fun(&BlackboxWindow::grabButtons
));