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
57 #include "bbscreen.hh"
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
);
147 gcv
.foreground
= WhitePixel(otk::OBDisplay::display
, getScreenNumber())
148 ^ BlackPixel(otk::OBDisplay::display
, getScreenNumber());
149 gcv
.function
= GXxor
;
150 gcv
.subwindow_mode
= IncludeInferiors
;
151 opGC
= XCreateGC(otk::OBDisplay::display
, getRootWindow(),
152 GCForeground
| GCFunction
| GCSubwindowMode
, &gcv
);
154 const char *s
= "0: 0000 x 0: 0000";
155 geom_w
= resource
.wstyle
.font
->measureString(s
) + resource
.wstyle
.bevel_width
* 2;
156 geom_h
= resource
.wstyle
.font
->height() + resource
.wstyle
.bevel_width
* 2;
158 XSetWindowAttributes attrib
;
159 unsigned long mask
= CWBorderPixel
| CWColormap
| CWSaveUnder
;
160 attrib
.border_pixel
= getBorderColor()->pixel();
161 attrib
.colormap
= getColormap();
162 attrib
.save_under
= True
;
164 // XXX -- move this geom_* crap out of here
166 geom_window
= XCreateWindow(otk::OBDisplay::display
, getRootWindow(),
167 0, 0, geom_w
, geom_h
, resource
.wstyle
.border_width
,
168 getDepth(), InputOutput
, getVisual(),
170 geom_visible
= False
;
172 otk::BTexture
* texture
= &(resource
.wstyle
.l_focus
);
173 geom_pixmap
= texture
->render(geom_w
, geom_h
, geom_pixmap
);
174 if (geom_pixmap
== ParentRelative
) {
175 texture
= &(resource
.wstyle
.t_focus
);
176 geom_pixmap
= texture
->render(geom_w
, geom_h
, geom_pixmap
);
179 XSetWindowBackground(otk::OBDisplay::display
, geom_window
,
180 texture
->color().pixel());
182 XSetWindowBackgroundPixmap(otk::OBDisplay::display
,
183 geom_window
, geom_pixmap
);
185 if (resource
.workspaces
> 0) {
186 for (unsigned int i
= 0; i
< resource
.workspaces
; ++i
) {
187 Workspace
*wkspc
= new Workspace(this, workspacesList
.size());
188 workspacesList
.push_back(wkspc
);
192 Workspace
*wkspc
= new Workspace(this, workspacesList
.size());
193 workspacesList
.push_back(wkspc
);
198 saveWorkspaceNames();
200 updateNetizenWorkspaceCount();
202 current_workspace
= workspacesList
.front();
204 xatom
->set(getRootWindow(), otk::OBProperty::net_current_desktop
,
205 otk::OBProperty::Atom_Cardinal
, 0); //first workspace
207 raiseWindows(0, 0); // this also initializes the empty stacking list
209 updateClientList(); // initialize the client lists, which will be empty
210 updateAvailableArea();
212 changeWorkspaceID(0);
214 unsigned int i
, j
, nchild
;
215 Window r
, p
, *children
;
216 XQueryTree(otk::OBDisplay::display
, getRootWindow(), &r
, &p
,
219 // preen the window list of all icon windows... for better dockapp support
220 for (i
= 0; i
< nchild
; i
++) {
221 if (children
[i
] == None
) continue;
223 XWMHints
*wmhints
= XGetWMHints(otk::OBDisplay::display
,
227 if ((wmhints
->flags
& IconWindowHint
) &&
228 (wmhints
->icon_window
!= children
[i
])) {
229 for (j
= 0; j
< nchild
; j
++) {
230 if (children
[j
] == wmhints
->icon_window
) {
241 // manage shown windows
242 for (i
= 0; i
< nchild
; ++i
) {
243 if (children
[i
] == None
|| ! blackbox
->validateWindow(children
[i
]))
246 XWindowAttributes attrib
;
247 if (XGetWindowAttributes(otk::OBDisplay::display
, children
[i
], &attrib
)) {
248 if (attrib
.override_redirect
) continue;
250 if (attrib
.map_state
!= IsUnmapped
) {
251 manageWindow(children
[i
]);
258 // call this again just in case a window we found updates the Strut list
259 updateAvailableArea();
263 BScreen::~BScreen(void) {
264 if (! managed
) return;
266 if (geom_pixmap
!= None
)
267 image_control
->removeImage(geom_pixmap
);
269 if (geom_window
!= None
)
270 XDestroyWindow(otk::OBDisplay::display
, geom_window
);
272 std::for_each(workspacesList
.begin(), workspacesList
.end(),
273 otk::PointerAssassin());
275 std::for_each(iconList
.begin(), iconList
.end(), otk::PointerAssassin());
277 while (! systrayWindowList
.empty())
278 removeSystrayWindow(systrayWindowList
[0]);
280 delete image_control
;
284 XFreeGC(otk::OBDisplay::display
, opGC
);
288 void BScreen::LoadStyle(void) {
289 otk::Configuration
style_conf(False
);
291 const char *sfile
= blackbox
->getStyleFilename();
293 style_conf
.setFile(sfile
);
294 if (! style_conf
.load()) {
295 style_conf
.setFile(DEFAULTSTYLE
);
296 if (! style_conf
.load())
297 style_conf
.create(); // hardcoded default values will be used.
301 // merge in the rc file
302 style_conf
.merge(config
->file(), True
);
304 resource
.wstyle
.load(style_conf
);
307 void BScreen::saveSloppyFocus(bool s
) {
308 resource
.sloppy_focus
= s
;
311 if (resource
.sloppy_focus
) {
312 fmodel
= "SloppyFocus";
313 if (resource
.auto_raise
) fmodel
+= " AutoRaise";
314 if (resource
.click_raise
) fmodel
+= " ClickRaise";
316 fmodel
= "ClickToFocus";
318 config
->setValue(screenstr
+ "focusModel", fmodel
);
322 void BScreen::saveAutoRaise(bool a
) {
323 resource
.auto_raise
= a
;
324 saveSloppyFocus(resource
.sloppy_focus
);
328 void BScreen::saveClickRaise(bool c
) {
329 resource
.click_raise
= c
;
330 saveSloppyFocus(resource
.sloppy_focus
);
334 void BScreen::saveImageDither(bool d
) {
335 image_control
->setDither(d
);
336 config
->setValue(screenstr
+ "imageDither", doImageDither());
340 void BScreen::saveOpaqueMove(bool o
) {
341 resource
.opaque_move
= o
;
342 config
->setValue(screenstr
+ "opaqueMove", resource
.opaque_move
);
346 void BScreen::saveFullMax(bool f
) {
347 resource
.full_max
= f
;
348 config
->setValue(screenstr
+ "fullMaximization", resource
.full_max
);
352 void BScreen::saveFocusNew(bool f
) {
353 resource
.focus_new
= f
;
354 config
->setValue(screenstr
+ "focusNewWindows", resource
.focus_new
);
358 void BScreen::saveFocusLast(bool f
) {
359 resource
.focus_last
= f
;
360 config
->setValue(screenstr
+ "focusLastWindow", resource
.focus_last
);
364 void BScreen::saveAAFonts(bool f
) {
365 resource
.aa_fonts
= f
;
366 config
->setValue(screenstr
+ "antialiasFonts", resource
.aa_fonts
);
371 void BScreen::saveShadowFonts(bool f
) {
372 resource
.shadow_fonts
= f
;
373 config
->setValue(screenstr
+ "dropShadowFonts", resource
.shadow_fonts
);
378 void BScreen::saveWindowToEdgeSnap(int s
) {
379 resource
.snap_to_edges
= s
;
382 switch (resource
.snap_to_edges
) {
383 case WindowNoSnap
: snap
= "NoSnap"; break;
384 case WindowResistance
: snap
= "Resistance"; break;
385 case WindowSnap
: default: snap
= "Snap"; break;
387 config
->setValue(screenstr
+ "windowToEdgeSnap", snap
);
391 void BScreen::saveWindowToWindowSnap(int s
) {
392 resource
.snap_to_windows
= s
;
395 switch (resource
.snap_to_windows
) {
396 case WindowNoSnap
: snap
= "NoSnap"; break;
397 case WindowResistance
: snap
= "Resistance"; break;
398 case WindowSnap
: default: snap
= "Snap"; break;
400 config
->setValue(screenstr
+ "windowToWindowSnap", snap
);
404 void BScreen::saveResizeZones(unsigned int z
) {
405 resource
.resize_zones
= z
;
406 config
->setValue(screenstr
+ "resizeZones", resource
.resize_zones
);
410 void BScreen::saveWindowCornerSnap(bool s
) {
411 resource
.window_corner_snap
= s
;
412 config
->setValue(screenstr
+ "windowCornerSnap",
413 resource
.window_corner_snap
);
417 void BScreen::saveWorkspaces(unsigned int w
) {
418 resource
.workspaces
= w
;
419 config
->setValue(screenstr
+ "workspaces", resource
.workspaces
);
423 void BScreen::savePlacementPolicy(int p
) {
424 resource
.placement_policy
= p
;
425 const char *placement
;
426 switch (resource
.placement_policy
) {
427 case CascadePlacement
: placement
= "CascadePlacement"; break;
428 case UnderMousePlacement
: placement
= "UnderMousePlacement"; break;
429 case ClickMousePlacement
: placement
= "ClickMousePlacement"; break;
430 case ColSmartPlacement
: placement
= "ColSmartPlacement"; break;
431 case RowSmartPlacement
: default: placement
= "RowSmartPlacement"; break;
433 config
->setValue(screenstr
+ "windowPlacement", placement
);
437 void BScreen::saveResistanceSize(int s
) {
438 resource
.resistance_size
= s
;
439 config
->setValue(screenstr
+ "resistanceSize",
440 resource
.resistance_size
);
444 void BScreen::saveSnapThreshold(int t
) {
445 resource
.snap_threshold
= t
;
446 config
->setValue(screenstr
+ "edgeSnapThreshold",
447 resource
.snap_threshold
);
451 void BScreen::saveSnapOffset(int t
) {
452 resource
.snap_offset
= t
;
453 config
->setValue(screenstr
+ "edgeSnapOffset",
454 resource
.snap_offset
);
458 void BScreen::saveRowPlacementDirection(int d
) {
459 resource
.row_direction
= d
;
460 config
->setValue(screenstr
+ "rowPlacementDirection",
461 resource
.row_direction
== LeftRight
?
462 "LeftToRight" : "RightToLeft");
466 void BScreen::saveColPlacementDirection(int d
) {
467 resource
.col_direction
= d
;
468 config
->setValue(screenstr
+ "colPlacementDirection",
469 resource
.col_direction
== TopBottom
?
470 "TopToBottom" : "BottomToTop");
474 void BScreen::saveStrftimeFormat(const std::string
& format
) {
475 resource
.strftime_format
= format
;
476 config
->setValue(screenstr
+ "strftimeFormat", resource
.strftime_format
);
480 void BScreen::saveWorkspaceNames() {
483 for (unsigned int i
= 0; i
< workspacesList
.size(); ++i
) {
484 names
+= workspacesList
[i
]->getName();
485 if (i
< workspacesList
.size() - 1)
489 config
->setValue(screenstr
+ "workspaceNames", names
);
493 void BScreen::savePlaceIgnoreShaded(bool i
) {
494 resource
.ignore_shaded
= i
;
495 config
->setValue(screenstr
+ "placementIgnoreShaded",
496 resource
.ignore_shaded
);
500 void BScreen::savePlaceIgnoreMaximized(bool i
) {
501 resource
.ignore_maximized
= i
;
502 config
->setValue(screenstr
+ "placementIgnoreMaximized",
503 resource
.ignore_maximized
);
507 void BScreen::saveAllowScrollLock(bool a
) {
508 resource
.allow_scroll_lock
= a
;
509 config
->setValue(screenstr
+ "disableBindingsWithScrollLock",
510 resource
.allow_scroll_lock
);
514 void BScreen::saveWorkspaceWarping(bool w
) {
515 resource
.workspace_warping
= w
;
516 config
->setValue(screenstr
+ "workspaceWarping",
517 resource
.workspace_warping
);
521 void BScreen::saveRootScrollDirection(int d
) {
522 resource
.root_scroll
= d
;
524 switch (resource
.root_scroll
) {
525 case NoScroll
: dir
= "None"; break;
526 case ReverseScroll
: dir
= "Reverse"; break;
527 case NormalScroll
: default: dir
= "Normal"; break;
529 config
->setValue(screenstr
+ "rootScrollDirection", dir
);
533 void BScreen::save_rc(void) {
534 saveSloppyFocus(resource
.sloppy_focus
);
535 saveAutoRaise(resource
.auto_raise
);
536 saveImageDither(doImageDither());
537 saveShadowFonts(resource
.shadow_fonts
);
538 saveAAFonts(resource
.aa_fonts
);
539 saveResizeZones(resource
.resize_zones
);
540 saveOpaqueMove(resource
.opaque_move
);
541 saveFullMax(resource
.full_max
);
542 saveFocusNew(resource
.focus_new
);
543 saveFocusLast(resource
.focus_last
);
544 saveWindowToWindowSnap(resource
.snap_to_windows
);
545 saveWindowToEdgeSnap(resource
.snap_to_edges
);
546 saveWindowCornerSnap(resource
.window_corner_snap
);
547 saveWorkspaces(resource
.workspaces
);
548 savePlacementPolicy(resource
.placement_policy
);
549 saveSnapThreshold(resource
.snap_threshold
);
550 saveSnapOffset(resource
.snap_offset
);
551 saveResistanceSize(resource
.resistance_size
);
552 saveRowPlacementDirection(resource
.row_direction
);
553 saveColPlacementDirection(resource
.col_direction
);
554 saveStrftimeFormat(resource
.strftime_format
);
555 savePlaceIgnoreShaded(resource
.ignore_shaded
);
556 savePlaceIgnoreMaximized(resource
.ignore_maximized
);
557 saveAllowScrollLock(resource
.allow_scroll_lock
);
558 saveWorkspaceWarping(resource
.workspace_warping
);
559 saveRootScrollDirection(resource
.root_scroll
);
563 void BScreen::load_rc(void) {
567 if (! config
->getValue(screenstr
+ "fullMaximization", resource
.full_max
))
568 resource
.full_max
= false;
570 if (! config
->getValue(screenstr
+ "focusNewWindows", resource
.focus_new
))
571 resource
.focus_new
= false;
573 if (! config
->getValue(screenstr
+ "focusLastWindow", resource
.focus_last
))
574 resource
.focus_last
= false;
576 if (! config
->getValue(screenstr
+ "workspaces", resource
.workspaces
))
577 resource
.workspaces
= 1;
579 if (! config
->getValue(screenstr
+ "opaqueMove", resource
.opaque_move
))
580 resource
.opaque_move
= false;
582 if (! config
->getValue(screenstr
+ "antialiasFonts", resource
.aa_fonts
))
583 resource
.aa_fonts
= true;
585 if (! resource
.aa_fonts
||
586 ! config
->getValue(screenstr
+ "dropShadowFonts", resource
.shadow_fonts
))
587 resource
.shadow_fonts
= false;
589 if (! config
->getValue(screenstr
+ "resizeZones", resource
.resize_zones
) ||
590 (resource
.resize_zones
!= 1 && resource
.resize_zones
!= 2 &&
591 resource
.resize_zones
!= 4))
592 resource
.resize_zones
= 4;
594 resource
.snap_to_windows
= WindowResistance
;
595 if (config
->getValue(screenstr
+ "windowToWindowSnap", s
)) {
597 resource
.snap_to_windows
= WindowNoSnap
;
598 else if (s
== "Snap")
599 resource
.snap_to_windows
= WindowSnap
;
602 resource
.snap_to_edges
= WindowResistance
;
603 if (config
->getValue(screenstr
+ "windowToEdgeSnap", s
)) {
605 resource
.snap_to_edges
= WindowNoSnap
;
606 else if (s
== "Snap")
607 resource
.snap_to_edges
= WindowSnap
;
610 if (! config
->getValue(screenstr
+ "windowCornerSnap",
611 resource
.window_corner_snap
))
612 resource
.window_corner_snap
= true;
614 if (! config
->getValue(screenstr
+ "imageDither", b
))
616 image_control
->setDither(b
);
618 if (! config
->getValue(screenstr
+ "edgeSnapOffset",
619 resource
.snap_offset
))
620 resource
.snap_offset
= 0;
621 if (resource
.snap_offset
> 50) // sanity check, setting this huge would
622 resource
.snap_offset
= 50; // seriously suck.
624 if (! config
->getValue(screenstr
+ "edgeSnapThreshold",
625 resource
.snap_threshold
))
626 resource
.snap_threshold
= 4;
628 if (! config
->getValue(screenstr
+ "resistanceSize",
629 resource
.resistance_size
))
630 resource
.resistance_size
= 18;
632 if (config
->getValue(screenstr
+ "rowPlacementDirection", s
) &&
634 resource
.row_direction
= RightLeft
;
636 resource
.row_direction
= LeftRight
;
638 if (config
->getValue(screenstr
+ "colPlacementDirection", s
) &&
640 resource
.col_direction
= BottomTop
;
642 resource
.col_direction
= TopBottom
;
644 if (config
->getValue(screenstr
+ "workspaceNames", s
)) {
645 otk::OBProperty::StringVect workspaceNames
;
647 string::const_iterator it
= s
.begin(), end
= s
.end();
649 string::const_iterator tmp
= it
; // current string.begin()
650 it
= std::find(tmp
, end
, ','); // look for comma between tmp and end
651 workspaceNames
.push_back(string(tmp
, it
)); // s[tmp:it]
657 xatom
->set(getRootWindow(), otk::OBProperty::net_desktop_names
,
658 otk::OBProperty::utf8
, workspaceNames
);
661 resource
.sloppy_focus
= true;
662 resource
.auto_raise
= false;
663 resource
.click_raise
= false;
664 if (config
->getValue(screenstr
+ "focusModel", s
)) {
665 if (s
.find("ClickToFocus") != string::npos
) {
666 resource
.sloppy_focus
= false;
669 if (s
.find("AutoRaise") != string::npos
)
670 resource
.auto_raise
= true;
671 if (s
.find("ClickRaise") != string::npos
)
672 resource
.click_raise
= true;
676 if (config
->getValue(screenstr
+ "windowPlacement", s
)) {
677 if (s
== "CascadePlacement")
678 resource
.placement_policy
= CascadePlacement
;
679 else if (s
== "UnderMousePlacement")
680 resource
.placement_policy
= UnderMousePlacement
;
681 else if (s
== "ClickMousePlacement")
682 resource
.placement_policy
= ClickMousePlacement
;
683 else if (s
== "ColSmartPlacement")
684 resource
.placement_policy
= ColSmartPlacement
;
685 else //if (s == "RowSmartPlacement")
686 resource
.placement_policy
= RowSmartPlacement
;
688 resource
.placement_policy
= RowSmartPlacement
;
690 if (! config
->getValue(screenstr
+ "strftimeFormat",
691 resource
.strftime_format
))
692 resource
.strftime_format
= "%I:%M %p";
694 if (! config
->getValue(screenstr
+ "placementIgnoreShaded",
695 resource
.ignore_shaded
))
696 resource
.ignore_shaded
= true;
698 if (! config
->getValue(screenstr
+ "placementIgnoreMaximized",
699 resource
.ignore_maximized
))
700 resource
.ignore_maximized
= true;
702 if (! config
->getValue(screenstr
+ "disableBindingsWithScrollLock",
703 resource
.allow_scroll_lock
))
704 resource
.allow_scroll_lock
= false;
706 if (! config
->getValue(screenstr
+ "workspaceWarping",
707 resource
.workspace_warping
))
708 resource
.workspace_warping
= false;
710 resource
.root_scroll
= NormalScroll
;
711 if (config
->getValue(screenstr
+ "rootScrollDirection", s
)) {
713 resource
.root_scroll
= NoScroll
;
714 else if (s
== "Reverse")
715 resource
.root_scroll
= ReverseScroll
;
720 void BScreen::changeWorkspaceCount(unsigned int new_count
) {
721 assert(new_count
> 0);
723 if (new_count
< workspacesList
.size()) {
725 for (unsigned int i
= workspacesList
.size(); i
> new_count
; --i
)
726 removeLastWorkspace();
727 // removeLast already sets the current workspace to the
728 // last available one.
729 } else if (new_count
> workspacesList
.size()) {
731 for(unsigned int i
= workspacesList
.size(); i
< new_count
; ++i
)
737 void BScreen::reconfigure(void) {
738 // don't reconfigure while saving the initial rc file, it's a waste and it
739 // breaks somethings (workspace names)
740 if (blackbox
->state() == Openbox::State_Starting
) return;
745 // we need to do this explicitly, because just loading this value from the rc
747 changeWorkspaceCount(resource
.workspaces
);
750 gcv
.foreground
= WhitePixel(otk::OBDisplay::display
,
752 gcv
.function
= GXinvert
;
753 gcv
.subwindow_mode
= IncludeInferiors
;
754 XChangeGC(otk::OBDisplay::display
, opGC
,
755 GCForeground
| GCFunction
| GCSubwindowMode
, &gcv
);
757 const char *s
= "0: 0000 x 0: 0000";
759 geom_w
= resource
.wstyle
.font
->measureString(s
) + resource
.wstyle
.bevel_width
* 2;
760 geom_h
= resource
.wstyle
.font
->height() + resource
.wstyle
.bevel_width
* 2;
762 otk::BTexture
* texture
= &(resource
.wstyle
.l_focus
);
763 geom_pixmap
= texture
->render(geom_w
, geom_h
, geom_pixmap
);
764 if (geom_pixmap
== ParentRelative
) {
765 texture
= &(resource
.wstyle
.t_focus
);
766 geom_pixmap
= texture
->render(geom_w
, geom_h
, geom_pixmap
);
769 XSetWindowBackground(otk::OBDisplay::display
, geom_window
,
770 texture
->color().pixel());
772 XSetWindowBackgroundPixmap(otk::OBDisplay::display
,
773 geom_window
, geom_pixmap
);
775 XSetWindowBorderWidth(otk::OBDisplay::display
, geom_window
,
776 resource
.wstyle
.border_width
);
777 XSetWindowBorder(otk::OBDisplay::display
, geom_window
,
778 resource
.wstyle
.border_color
.pixel());
780 typedef std::vector
<int> SubList
;
781 SubList remember_subs
;
785 std::for_each(workspacesList
.begin(), workspacesList
.end(),
786 std::mem_fun(&Workspace::reconfigure
));
788 BlackboxWindowList::iterator iit
= iconList
.begin();
789 for (; iit
!= iconList
.end(); ++iit
) {
790 BlackboxWindow
*bw
= *iit
;
791 if (bw
->validateClient())
795 otk::BImageControl::timeout(image_control
);
800 void BScreen::addIcon(BlackboxWindow
*w
) {
803 w
->setWorkspace(otk::BSENTINEL
);
804 w
->setWindowNumber(iconList
.size());
806 iconList
.push_back(w
);
810 void BScreen::removeIcon(BlackboxWindow
*w
) {
815 BlackboxWindowList::iterator it
= iconList
.begin(),
816 end
= iconList
.end();
817 for (int i
= 0; it
!= end
; ++it
)
818 (*it
)->setWindowNumber(i
++);
822 BlackboxWindow
*BScreen::getIcon(unsigned int index
) {
823 if (index
< iconList
.size()) {
824 BlackboxWindowList::iterator it
= iconList
.begin();
825 while (index
-- > 0) // increment to index
830 return (BlackboxWindow
*) 0;
834 unsigned int BScreen::addWorkspace(void) {
835 Workspace
*wkspc
= new Workspace(this, workspacesList
.size());
836 workspacesList
.push_back(wkspc
);
837 saveWorkspaces(getWorkspaceCount());
838 saveWorkspaceNames();
840 return workspacesList
.size();
844 unsigned int BScreen::removeLastWorkspace(void) {
845 if (workspacesList
.size() == 1)
848 Workspace
*wkspc
= workspacesList
.back();
850 if (current_workspace
->getID() == wkspc
->getID())
851 changeWorkspaceID(current_workspace
->getID() - 1);
855 workspacesList
.pop_back();
858 saveWorkspaces(getWorkspaceCount());
859 saveWorkspaceNames();
861 updateNetizenWorkspaceCount();
863 return workspacesList
.size();
867 void BScreen::changeWorkspaceID(unsigned int id
) {
868 if (! current_workspace
|| id
== current_workspace
->getID()) return;
870 BlackboxWindow
*focused
= blackbox
->getFocusedWindow();
871 if (focused
&& focused
->getScreen() == this) {
872 assert(focused
->isStuck() ||
873 focused
->getWorkspaceNumber() == current_workspace
->getID());
875 current_workspace
->setLastFocusedWindow(focused
);
877 // if no window had focus, no need to store a last focus
878 current_workspace
->setLastFocusedWindow((BlackboxWindow
*) 0);
881 // when we switch workspaces, unfocus whatever was focused if it is going
883 if (focused
&& ! focused
->isStuck())
884 blackbox
->setFocusedWindow((BlackboxWindow
*) 0);
886 current_workspace
->hideAll();
888 current_workspace
= getWorkspace(id
);
890 xatom
->set(getRootWindow(), otk::OBProperty::net_current_desktop
,
891 otk::OBProperty::Atom_Cardinal
, id
);
893 current_workspace
->showAll();
898 BlackboxWindow
*win
= (BlackboxWindow
*) 0;
901 XSync(otk::OBDisplay::display
, False
);
903 // If sloppy focus and we can find the client window under the pointer,
905 if (resource
.sloppy_focus
&&
906 XQueryPointer(otk::OBDisplay::display
, getRootWindow(), &r
, &c
,
907 &rx
, &ry
, &x
, &y
, &m
) &&
909 if ( (win
= blackbox
->searchWindow(c
)) )
910 f
= win
->setInputFocus();
913 // If that fails, and we're doing focus_last, try to focus the last window.
914 if (! f
&& resource
.focus_last
&&
915 (win
= current_workspace
->getLastFocusedWindow()))
916 f
= win
->setInputFocus();
919 if we found a focus target, then we set the focused window explicitly
920 because it is possible to switch off this workspace before the x server
921 generates the FocusIn event for the window. if that happens, openbox would
922 lose track of what window was the 'LastFocused' window on the workspace.
924 if we did not find a focus target, then set the current focused window to
928 blackbox
->setFocusedWindow(win
);
930 blackbox
->setFocusedWindow((BlackboxWindow
*) 0);
935 * Set the _NET_CLIENT_LIST root window property.
937 void BScreen::updateClientList(void) {
938 if (windowList
.size() > 0) {
939 Window
*windows
= new Window
[windowList
.size()];
940 Window
*win_it
= windows
;
941 BlackboxWindowList::iterator it
= windowList
.begin();
942 const BlackboxWindowList::iterator end
= windowList
.end();
943 for (; it
!= end
; ++it
, ++win_it
)
944 *win_it
= (*it
)->getClientWindow();
945 xatom
->set(getRootWindow(), otk::OBProperty::net_client_list
,
946 otk::OBProperty::Atom_Window
, windows
, windowList
.size());
949 xatom
->set(getRootWindow(), otk::OBProperty::net_client_list
,
950 otk::OBProperty::Atom_Window
, 0, 0);
952 updateStackingList();
957 * Set the _NET_CLIENT_LIST_STACKING root window property.
959 void BScreen::updateStackingList(void) {
961 BlackboxWindowList stack_order
;
964 * Get the stacking order from all of the workspaces.
965 * We start with the current workspace so that the sticky windows will be
966 * in the right order on the current workspace.
967 * XXX: Do we need to have sticky windows in the list once for each workspace?
969 getCurrentWorkspace()->appendStackOrder(stack_order
);
970 for (unsigned int i
= 0; i
< getWorkspaceCount(); ++i
)
971 if (i
!= getCurrentWorkspaceID())
972 getWorkspace(i
)->appendStackOrder(stack_order
);
974 if (stack_order
.size() > 0) {
975 // set the client list atoms
976 Window
*windows
= new Window
[stack_order
.size()];
977 Window
*win_it
= windows
;
978 BlackboxWindowList::iterator it
= stack_order
.begin(),
979 end
= stack_order
.end();
980 for (; it
!= end
; ++it
, ++win_it
)
981 *win_it
= (*it
)->getClientWindow();
982 xatom
->set(getRootWindow(), otk::OBProperty::net_client_list_stacking
,
983 otk::OBProperty::Atom_Window
, windows
, stack_order
.size());
986 xatom
->set(getRootWindow(), otk::OBProperty::net_client_list_stacking
,
987 otk::OBProperty::Atom_Window
, 0, 0);
991 void BScreen::addSystrayWindow(Window window
) {
992 XGrabServer(otk::OBDisplay::display
);
994 XSelectInput(otk::OBDisplay::display
, window
, StructureNotifyMask
);
995 systrayWindowList
.push_back(window
);
996 xatom
->set(getRootWindow(), otk::OBProperty::kde_net_system_tray_windows
,
997 otk::OBProperty::Atom_Window
,
998 &systrayWindowList
[0], systrayWindowList
.size());
999 blackbox
->saveSystrayWindowSearch(window
, this);
1001 XUngrabServer(otk::OBDisplay::display
);
1005 void BScreen::removeSystrayWindow(Window window
) {
1006 XGrabServer(otk::OBDisplay::display
);
1008 WindowList::iterator it
= systrayWindowList
.begin();
1009 const WindowList::iterator end
= systrayWindowList
.end();
1010 for (; it
!= end
; ++it
)
1011 if (*it
== window
) {
1012 systrayWindowList
.erase(it
);
1013 xatom
->set(getRootWindow(),
1014 otk::OBProperty::kde_net_system_tray_windows
,
1015 otk::OBProperty::Atom_Window
,
1016 &systrayWindowList
[0], systrayWindowList
.size());
1017 blackbox
->removeSystrayWindowSearch(window
);
1018 XSelectInput(otk::OBDisplay::display
, window
, NoEventMask
);
1022 assert(it
!= end
); // not a systray window
1024 XUngrabServer(otk::OBDisplay::display
);
1028 void BScreen::manageWindow(Window w
) {
1029 // is the window a KDE systray window?
1031 if (xatom
->get(w
, otk::OBProperty::kde_net_wm_system_tray_window_for
,
1032 otk::OBProperty::Atom_Window
, &systray
) &&
1035 addSystrayWindow(w
);
1039 // is the window a docking app
1040 XWMHints
*wmhint
= XGetWMHints(otk::OBDisplay::display
, w
);
1041 if (wmhint
&& (wmhint
->flags
& StateHint
) &&
1042 wmhint
->initial_state
== WithdrawnState
) {
1043 //slit->addClient(w);
1047 new BlackboxWindow(blackbox
, w
, this);
1049 BlackboxWindow
*win
= blackbox
->searchWindow(w
);
1053 if (win
->isDesktop()) {
1054 desktopWindowList
.push_back(win
->getFrameWindow());
1055 } else { // if (win->isNormal()) {
1056 // don't list desktop windows as managed windows
1057 windowList
.push_back(win
);
1060 if (win
->isTopmost())
1061 specialWindowList
.push_back(win
->getFrameWindow());
1064 XMapRequestEvent mre
;
1066 if (blackbox
->state() == Openbox::State_Starting
&&
1068 win
->restoreAttributes();
1069 win
->mapRequestEvent(&mre
);
1073 void BScreen::unmanageWindow(BlackboxWindow
*w
, bool remap
) {
1074 // is the window a KDE systray window?
1076 if (xatom
->get(w
->getClientWindow(),
1077 otk::OBProperty::kde_net_wm_system_tray_window_for
,
1078 otk::OBProperty::Atom_Window
, &systray
) &&
1081 removeSystrayWindow(w
->getClientWindow());
1087 // Remove the modality so that its parent won't try to re-focus the window
1088 if (w
->isModal()) w
->setModal(False
);
1090 if (w
->getWorkspaceNumber() != otk::BSENTINEL
&&
1091 w
->getWindowNumber() != otk::BSENTINEL
) {
1092 getWorkspace(w
->getWorkspaceNumber())->removeWindow(w
);
1094 for (unsigned int i
= 0; i
< getNumberOfWorkspaces(); ++i
)
1095 if (i
!= w
->getWorkspaceNumber())
1096 getWorkspace(i
)->removeWindow(w
, True
);
1098 } else if (w
->isIconic())
1101 if (w
->isDesktop()) {
1102 WindowList::iterator it
= desktopWindowList
.begin();
1103 const WindowList::iterator end
= desktopWindowList
.end();
1104 for (; it
!= end
; ++it
)
1105 if (*it
== w
->getFrameWindow()) {
1106 desktopWindowList
.erase(it
);
1109 assert(it
!= end
); // the window wasnt a desktop window?
1110 } else { // if (w->isNormal()) {
1111 // we don't list desktop windows as managed windows
1112 windowList
.remove(w
);
1115 if (w
->isTopmost()) {
1116 WindowList::iterator it
= specialWindowList
.begin();
1117 const WindowList::iterator end
= specialWindowList
.end();
1118 for (; it
!= end
; ++it
)
1119 if (*it
== w
->getFrameWindow()) {
1120 specialWindowList
.erase(it
);
1123 assert(it
!= end
); // the window wasnt a special window?
1127 if (blackbox
->getFocusedWindow() == w
)
1128 blackbox
->setFocusedWindow((BlackboxWindow
*) 0);
1131 some managed windows can also be window group controllers. when
1132 unmanaging such windows, we should also delete the window group.
1134 BWindowGroup
*group
= blackbox
->searchGroup(w
->getClientWindow());
1141 void BScreen::updateWorkArea(void) {
1142 if (workspacesList
.size() > 0) {
1143 unsigned long *dims
= new unsigned long[4 * workspacesList
.size()];
1144 for (unsigned int i
= 0, m
= workspacesList
.size(); i
< m
; ++i
) {
1145 // XXX: this could be different for each workspace
1146 const otk::Rect
&area
= availableArea();
1147 dims
[(i
* 4) + 0] = area
.x();
1148 dims
[(i
* 4) + 1] = area
.y();
1149 dims
[(i
* 4) + 2] = area
.width();
1150 dims
[(i
* 4) + 3] = area
.height();
1152 xatom
->set(getRootWindow(), otk::OBProperty::net_workarea
,
1153 otk::OBProperty::Atom_Cardinal
,
1154 dims
, 4 * workspacesList
.size());
1157 xatom
->set(getRootWindow(), otk::OBProperty::net_workarea
,
1158 otk::OBProperty::Atom_Cardinal
, 0, 0);
1162 void BScreen::updateNetizenWorkspaceCount(void) {
1163 xatom
->set(getRootWindow(), otk::OBProperty::net_number_of_desktops
,
1164 otk::OBProperty::Atom_Cardinal
, workspacesList
.size());
1170 void BScreen::updateNetizenWindowFocus(void) {
1171 Window f
= ((blackbox
->getFocusedWindow()) ?
1172 blackbox
->getFocusedWindow()->getClientWindow() : None
);
1174 xatom
->set(getRootWindow(), otk::OBProperty::net_active_window
,
1175 otk::OBProperty::Atom_Window
, f
);
1179 void BScreen::raiseWindows(Window
*workspace_stack
, unsigned int num
) {
1180 // the 13 represents the number of blackbox windows such as menus
1186 Window
*session_stack
= new
1187 Window
[(num
+ specialWindowList
.size() + bbwins
)];
1188 unsigned int i
= 0, k
= num
;
1190 WindowList::iterator sit
, send
= specialWindowList
.end();
1191 for (sit
= specialWindowList
.begin(); sit
!= send
; ++sit
)
1192 *(session_stack
+ i
++) = *sit
;
1195 *(session_stack
+ i
++) = *(workspace_stack
+ k
);
1197 XRestackWindows(otk::OBDisplay::display
, session_stack
, i
);
1199 delete [] session_stack
;
1201 updateStackingList();
1205 void BScreen::lowerWindows(Window
*workspace_stack
, unsigned int num
) {
1206 assert(num
> 0); // this would cause trouble in the XRaiseWindow call
1208 Window
*session_stack
= new Window
[(num
+ desktopWindowList
.size())];
1209 unsigned int i
= 0, k
= num
;
1211 XLowerWindow(otk::OBDisplay::display
, workspace_stack
[0]);
1214 *(session_stack
+ i
++) = *(workspace_stack
+ k
);
1216 WindowList::iterator dit
= desktopWindowList
.begin();
1217 const WindowList::iterator d_end
= desktopWindowList
.end();
1218 for (; dit
!= d_end
; ++dit
)
1219 *(session_stack
+ i
++) = *dit
;
1221 XRestackWindows(otk::OBDisplay::display
, session_stack
, i
);
1223 delete [] session_stack
;
1225 updateStackingList();
1229 void BScreen::reassociateWindow(BlackboxWindow
*w
, unsigned int wkspc_id
,
1230 bool ignore_sticky
) {
1233 if (wkspc_id
== otk::BSENTINEL
)
1234 wkspc_id
= current_workspace
->getID();
1236 if (w
->getWorkspaceNumber() == wkspc_id
)
1239 if (w
->isIconic()) {
1241 getWorkspace(wkspc_id
)->addWindow(w
);
1243 for (unsigned int i
= 0; i
< getNumberOfWorkspaces(); ++i
)
1244 if (i
!= w
->getWorkspaceNumber())
1245 getWorkspace(i
)->addWindow(w
, True
);
1246 } else if (ignore_sticky
|| ! w
->isStuck()) {
1249 getWorkspace(w
->getWorkspaceNumber())->removeWindow(w
);
1250 getWorkspace(wkspc_id
)->addWindow(w
);
1252 updateStackingList();
1256 void BScreen::propagateWindowName(const BlackboxWindow
*bw
) {
1257 if (bw
->isIconic()) {
1263 void BScreen::nextFocus(void) const {
1264 BlackboxWindow
*focused
= blackbox
->getFocusedWindow(),
1268 focused
->getScreen()->getScreenNumber() == getScreenNumber() &&
1269 current_workspace
->getCount() > 1) {
1271 next
= current_workspace
->getNextWindowInList(next
);
1272 } while (next
!= focused
&& ! next
->setInputFocus());
1274 if (next
!= focused
)
1275 current_workspace
->raiseWindow(next
);
1276 } else if (current_workspace
->getCount() > 0) {
1277 next
= current_workspace
->getTopWindowOnStack();
1278 next
->setInputFocus();
1279 current_workspace
->raiseWindow(next
);
1284 void BScreen::prevFocus(void) const {
1285 BlackboxWindow
*focused
= blackbox
->getFocusedWindow(),
1289 // if window is not on this screen, ignore it
1290 if (focused
->getScreen()->getScreenNumber() != getScreenNumber())
1291 focused
= (BlackboxWindow
*) 0;
1295 focused
->getScreen()->getScreenNumber() == getScreenNumber() &&
1296 current_workspace
->getCount() > 1) {
1297 // next is the next window to receive focus, current is a place holder
1299 next
= current_workspace
->getPrevWindowInList(next
);
1300 } while (next
!= focused
&& ! next
->setInputFocus());
1302 if (next
!= focused
)
1303 current_workspace
->raiseWindow(next
);
1304 } else if (current_workspace
->getCount() > 0) {
1305 next
= current_workspace
->getTopWindowOnStack();
1306 next
->setInputFocus();
1307 current_workspace
->raiseWindow(next
);
1312 void BScreen::raiseFocus(void) const {
1313 BlackboxWindow
*focused
= blackbox
->getFocusedWindow();
1317 // if on this Screen, raise it
1318 if (focused
->getScreen()->getScreenNumber() == getScreenNumber()) {
1319 Workspace
*workspace
= getWorkspace(focused
->getWorkspaceNumber());
1320 workspace
->raiseWindow(focused
);
1325 void BScreen::shutdown(void) {
1326 XSelectInput(otk::OBDisplay::display
, getRootWindow(), NoEventMask
);
1327 XSync(otk::OBDisplay::display
, False
);
1329 while(! windowList
.empty())
1330 unmanageWindow(windowList
.front(), True
);
1332 while(! desktopWindowList
.empty()) {
1333 BlackboxWindow
*win
= blackbox
->searchWindow(desktopWindowList
.front());
1335 unmanageWindow(win
, True
);
1340 void BScreen::showPosition(int x
, int y
) {
1341 if (! geom_visible
) {
1342 XMoveResizeWindow(otk::OBDisplay::display
, geom_window
,
1343 (getWidth() - geom_w
) / 2,
1344 (getHeight() - geom_h
) / 2, geom_w
, geom_h
);
1345 XMapWindow(otk::OBDisplay::display
, geom_window
);
1346 XRaiseWindow(otk::OBDisplay::display
, geom_window
);
1348 geom_visible
= True
;
1353 sprintf(label
, "X: %4d x Y: %4d", x
, y
);
1355 XClearWindow(otk::OBDisplay::display
, geom_window
);
1357 resource
.wstyle
.font
->drawString(geom_window
,
1358 resource
.wstyle
.bevel_width
, resource
.wstyle
.bevel_width
,
1359 resource
.wstyle
.l_text_focus
,
1364 void BScreen::showGeometry(unsigned int gx
, unsigned int gy
) {
1365 if (! geom_visible
) {
1366 XMoveResizeWindow(otk::OBDisplay::display
, geom_window
,
1367 (getWidth() - geom_w
) / 2,
1368 (getHeight() - geom_h
) / 2, geom_w
, geom_h
);
1369 XMapWindow(otk::OBDisplay::display
, geom_window
);
1370 XRaiseWindow(otk::OBDisplay::display
, geom_window
);
1372 geom_visible
= True
;
1377 sprintf(label
, "W: %4d x H: %4d", gx
, gy
);
1379 XClearWindow(otk::OBDisplay::display
, geom_window
);
1381 resource
.wstyle
.font
->drawString(geom_window
,
1382 resource
.wstyle
.bevel_width
, resource
.wstyle
.bevel_width
,
1383 resource
.wstyle
.l_text_focus
,
1388 void BScreen::hideGeometry(void) {
1390 XUnmapWindow(otk::OBDisplay::display
, geom_window
);
1391 geom_visible
= False
;
1396 void BScreen::addStrut(otk::Strut
*strut
) {
1397 strutList
.push_back(strut
);
1401 void BScreen::removeStrut(otk::Strut
*strut
) {
1402 strutList
.remove(strut
);
1406 const otk::Rect
& BScreen::availableArea(void) const {
1408 return getRect(); // return the full screen
1414 const RectList
& BScreen::allAvailableAreas(void) const {
1415 assert(isXineramaActive());
1416 assert(xineramaUsableArea
.size() > 0);
1417 fprintf(stderr
, "1found x %d y %d w %d h %d\n",
1418 xineramaUsableArea
[0].x(), xineramaUsableArea
[0].y(),
1419 xineramaUsableArea
[0].width(), xineramaUsableArea
[0].height());
1420 return xineramaUsableArea
;
1425 void BScreen::updateAvailableArea(void) {
1426 otk::Rect old_area
= usableArea
;
1427 usableArea
= getRect(); // reset to full screen
1430 // reset to the full areas
1431 if (isXineramaActive())
1432 xineramaUsableArea
= getXineramaAreas();
1435 /* these values represent offsets from the screen edge
1436 * we look for the biggest offset on each edge and then apply them
1438 * do not be confused by the similarity to the names of Rect's members
1440 unsigned int current_left
= 0, current_right
= 0, current_top
= 0,
1443 StrutList::const_iterator it
= strutList
.begin(), end
= strutList
.end();
1445 for(; it
!= end
; ++it
) {
1446 otk::Strut
*strut
= *it
;
1447 if (strut
->left
> current_left
)
1448 current_left
= strut
->left
;
1449 if (strut
->top
> current_top
)
1450 current_top
= strut
->top
;
1451 if (strut
->right
> current_right
)
1452 current_right
= strut
->right
;
1453 if (strut
->bottom
> current_bottom
)
1454 current_bottom
= strut
->bottom
;
1457 usableArea
.setPos(current_left
, current_top
);
1458 usableArea
.setSize(usableArea
.width() - (current_left
+ current_right
),
1459 usableArea
.height() - (current_top
+ current_bottom
));
1462 if (isXineramaActive()) {
1463 // keep each of the ximerama-defined areas inside the strut
1464 RectList::iterator xit
, xend
= xineramaUsableArea
.end();
1465 for (xit
= xineramaUsableArea
.begin(); xit
!= xend
; ++xit
) {
1466 if (xit
->x() < usableArea
.x()) {
1467 xit
->setX(usableArea
.x());
1468 xit
->setWidth(xit
->width() - usableArea
.x());
1470 if (xit
->y() < usableArea
.y()) {
1471 xit
->setY(usableArea
.y());
1472 xit
->setHeight(xit
->height() - usableArea
.y());
1474 if (xit
->x() + xit
->width() > usableArea
.width())
1475 xit
->setWidth(usableArea
.width() - xit
->x());
1476 if (xit
->y() + xit
->height() > usableArea
.height())
1477 xit
->setHeight(usableArea
.height() - xit
->y());
1482 if (old_area
!= usableArea
) {
1483 BlackboxWindowList::iterator it
= windowList
.begin(),
1484 end
= windowList
.end();
1485 for (; it
!= end
; ++it
)
1486 if ((*it
)->isMaximized()) (*it
)->remaximize();
1493 Workspace
* BScreen::getWorkspace(unsigned int index
) const {
1494 assert(index
< workspacesList
.size());
1495 return workspacesList
[index
];
1499 void BScreen::buttonPressEvent(const XButtonEvent
*xbutton
) {
1500 if (xbutton
->button
== 1) {
1501 if (! isRootColormapInstalled())
1502 image_control
->installRootColormap();
1505 } else if ((xbutton
->button
== 4 && resource
.root_scroll
== NormalScroll
) ||
1506 (xbutton
->button
== 5 && resource
.root_scroll
== ReverseScroll
)) {
1507 if (getCurrentWorkspaceID() >= getWorkspaceCount() - 1)
1508 changeWorkspaceID(0);
1510 changeWorkspaceID(getCurrentWorkspaceID() + 1);
1512 } else if ((xbutton
->button
== 5 && resource
.root_scroll
== NormalScroll
) ||
1513 (xbutton
->button
== 4 && resource
.root_scroll
== ReverseScroll
)) {
1514 if (getCurrentWorkspaceID() == 0)
1515 changeWorkspaceID(getWorkspaceCount() - 1);
1517 changeWorkspaceID(getCurrentWorkspaceID() - 1);
1522 void BScreen::propertyNotifyEvent(const XPropertyEvent
*pe
) {
1523 if (pe
->atom
== xatom
->atom(otk::OBProperty::net_desktop_names
)) {
1524 // _NET_WM_DESKTOP_NAMES
1525 WorkspaceList::iterator it
= workspacesList
.begin();
1526 const WorkspaceList::iterator end
= workspacesList
.end();
1527 for (; it
!= end
; ++it
) {
1528 (*it
)->readName(); // re-read its name from the window property
1529 //workspacemenu->changeWorkspaceLabel((*it)->getID(), (*it)->getName());
1531 //workspacemenu->update();
1532 saveWorkspaceNames();
1537 void BScreen::toggleFocusModel(FocusModel model
) {
1538 std::for_each(windowList
.begin(), windowList
.end(),
1539 std::mem_fun(&BlackboxWindow::ungrabButtons
));
1541 if (model
== SloppyFocus
) {
1542 saveSloppyFocus(True
);
1544 // we're cheating here to save writing the config file 3 times
1545 resource
.auto_raise
= False
;
1546 resource
.click_raise
= False
;
1547 saveSloppyFocus(False
);
1550 std::for_each(windowList
.begin(), windowList
.end(),
1551 std::mem_fun(&BlackboxWindow::grabButtons
));