1 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
2 // Toolbar.cc for Blackbox - an X11 Window manager
3 // Copyright (c) 2001 - 2005 Sean 'Shaleh' Perry <shaleh@debian.org>
4 // Copyright (c) 1997 - 2000, 2002 - 2005
5 // Bradley T Hughes <bhughes at trolltech.com>
7 // Permission is hereby granted, free of charge, to any person obtaining a
8 // copy of this software and associated documentation files (the "Software"),
9 // to deal in the Software without restriction, including without limitation
10 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 // and/or sell copies of the Software, and to permit persons to whom the
12 // Software is furnished to do so, subject to the following conditions:
14 // The above copyright notice and this permission notice shall be included in
15 // all copies or substantial portions of the Software.
17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 // DEALINGS IN THE SOFTWARE.
26 #include "Iconmenu.hh"
29 #include "Toolbarmenu.hh"
31 #include "Windowmenu.hh"
32 #include "Workspacemenu.hh"
35 #include <PixmapCache.hh>
38 #include <X11/Xutil.h>
43 long nextTimeout(int resolution
)
46 gettimeofday(&now
, 0);
47 return (std::max(1000l, ((((resolution
- (now
.tv_sec
% resolution
)) * 1000l))
48 - (now
.tv_usec
/ 1000l))));
52 Toolbar::Toolbar(BScreen
*scrn
) {
54 blackbox
= _screen
->blackbox();
56 // get the clock updating every minute
57 clock_timer
= new bt::Timer(blackbox
, this);
58 clock_timer
->recurring(True
);
60 const ToolbarOptions
&options
= _screen
->resource().toolbarOptions();
62 const std::string
&time_format
= options
.strftime_format
;
63 if (time_format
.find("%S") != std::string::npos
64 || time_format
.find("%s") != std::string::npos
65 || time_format
.find("%r") != std::string::npos
66 || time_format
.find("%T") != std::string::npos
) {
67 clock_timer_resolution
= 1;
68 } else if (time_format
.find("%M") != std::string::npos
69 || time_format
.find("%R") != std::string::npos
) {
70 clock_timer_resolution
= 60;
72 clock_timer_resolution
= 3600;
75 hide_timer
= new bt::Timer(blackbox
, this);
76 hide_timer
->setTimeout(blackbox
->resource().autoRaiseDelay());
78 setLayer(options
.always_on_top
79 ? StackingList::LayerAbove
80 : StackingList::LayerNormal
);
81 hidden
= options
.auto_hide
;
85 display
= blackbox
->XDisplay();
86 XSetWindowAttributes attrib
;
87 unsigned long create_mask
= CWColormap
| CWOverrideRedirect
| CWEventMask
;
88 attrib
.colormap
= _screen
->screenInfo().colormap();
89 attrib
.override_redirect
= True
;
90 attrib
.event_mask
= ButtonPressMask
| ButtonReleaseMask
|
91 EnterWindowMask
| LeaveWindowMask
| ExposureMask
;
94 XCreateWindow(display
, _screen
->screenInfo().rootWindow(), 0, 0, 1, 1, 0,
95 _screen
->screenInfo().depth(), InputOutput
,
96 _screen
->screenInfo().visual(),
97 create_mask
, &attrib
);
98 blackbox
->insertEventHandler(frame
.window
, this);
101 ButtonPressMask
| ButtonReleaseMask
| ExposureMask
| EnterWindowMask
;
103 frame
.workspace_label
=
104 XCreateWindow(display
, frame
.window
, 0, 0, 1, 1, 0,
105 _screen
->screenInfo().depth(), InputOutput
,
106 _screen
->screenInfo().visual(),
107 create_mask
, &attrib
);
108 blackbox
->insertEventHandler(frame
.workspace_label
, this);
111 XCreateWindow(display
, frame
.window
, 0, 0, 1, 1, 0,
112 _screen
->screenInfo().depth(), InputOutput
,
113 _screen
->screenInfo().visual(),
114 create_mask
, &attrib
);
115 blackbox
->insertEventHandler(frame
.window_label
, this);
118 XCreateWindow(display
, frame
.window
, 0, 0, 1, 1, 0,
119 _screen
->screenInfo().depth(), InputOutput
,
120 _screen
->screenInfo().visual(),
121 create_mask
, &attrib
);
122 blackbox
->insertEventHandler(frame
.clock
, this);
125 XCreateWindow(display
,frame
.window
, 0, 0, 1, 1, 0,
126 _screen
->screenInfo().depth(), InputOutput
,
127 _screen
->screenInfo().visual(),
128 create_mask
, &attrib
);
129 blackbox
->insertEventHandler(frame
.psbutton
, this);
132 XCreateWindow(display
,frame
.window
, 0, 0, 1, 1, 0,
133 _screen
->screenInfo().depth(), InputOutput
,
134 _screen
->screenInfo().visual(),
135 create_mask
, &attrib
);
136 blackbox
->insertEventHandler(frame
.nsbutton
, this);
139 XCreateWindow(display
,frame
.window
, 0, 0, 1, 1, 0,
140 _screen
->screenInfo().depth(), InputOutput
,
141 _screen
->screenInfo().visual(),
142 create_mask
, &attrib
);
143 blackbox
->insertEventHandler(frame
.pwbutton
, this);
146 XCreateWindow(display
,frame
.window
, 0, 0, 1, 1, 0,
147 _screen
->screenInfo().depth(), InputOutput
,
148 _screen
->screenInfo().visual(),
149 create_mask
, &attrib
);
150 blackbox
->insertEventHandler(frame
.nwbutton
, this);
152 frame
.base
= frame
.slabel
= frame
.wlabel
= frame
.clk
= frame
.button
=
153 frame
.pbutton
= None
;
155 _screen
->addStrut(&strut
);
159 clock_timer
->setTimeout(nextTimeout(clock_timer_resolution
));
160 clock_timer
->start();
162 XMapSubwindows(display
, frame
.window
);
163 XMapWindow(display
, frame
.window
);
167 Toolbar::~Toolbar(void) {
168 _screen
->removeStrut(&strut
);
170 XUnmapWindow(display
, frame
.window
);
172 bt::PixmapCache::release(frame
.base
);
173 bt::PixmapCache::release(frame
.slabel
);
174 bt::PixmapCache::release(frame
.wlabel
);
175 bt::PixmapCache::release(frame
.clk
);
176 bt::PixmapCache::release(frame
.button
);
177 bt::PixmapCache::release(frame
.pbutton
);
179 blackbox
->removeEventHandler(frame
.window
);
180 blackbox
->removeEventHandler(frame
.workspace_label
);
181 blackbox
->removeEventHandler(frame
.window_label
);
182 blackbox
->removeEventHandler(frame
.clock
);
183 blackbox
->removeEventHandler(frame
.psbutton
);
184 blackbox
->removeEventHandler(frame
.nsbutton
);
185 blackbox
->removeEventHandler(frame
.pwbutton
);
186 blackbox
->removeEventHandler(frame
.nwbutton
);
188 // all children windows are destroyed by this call as well
189 XDestroyWindow(display
, frame
.window
);
196 unsigned int Toolbar::exposedHeight(void) const {
197 const ToolbarOptions
&options
= _screen
->resource().toolbarOptions();
198 const ToolbarStyle
&style
= _screen
->resource().toolbarStyle();
199 return (options
.auto_hide
? style
.hidden_height
: style
.toolbar_height
);
203 void Toolbar::reconfigure(void) {
204 ScreenResource
&resource
= _screen
->resource();
205 const ToolbarOptions
&options
= resource
.toolbarOptions();
206 const ToolbarStyle
&style
= resource
.toolbarStyle();
208 unsigned int width
= (_screen
->screenInfo().width() *
209 options
.width_percent
) / 100;
211 const unsigned int border_width
= style
.toolbar
.borderWidth();
212 const unsigned int extra
=
213 style
.frame_margin
== 0 ? style
.button
.borderWidth() : 0;
214 frame
.rect
.setSize(width
, style
.toolbar_height
);
217 switch (options
.placement
) {
221 switch (options
.placement
) {
226 x
= _screen
->screenInfo().width() - frame
.rect
.width();
229 x
= (_screen
->screenInfo().width() - frame
.rect
.width()) / 2;
233 frame
.y_hidden
= style
.hidden_height
- frame
.rect
.height();
240 switch (options
.placement
) {
245 x
= _screen
->screenInfo().width() - frame
.rect
.width();
248 x
= (_screen
->screenInfo().width() - frame
.rect
.width()) / 2;
251 y
= _screen
->screenInfo().height() - frame
.rect
.height();
252 frame
.y_hidden
= _screen
->screenInfo().height() - style
.hidden_height
;
256 frame
.rect
.setPos(x
, y
);
260 time_t ttmp
= time(NULL
);
262 unsigned int clock_w
= 0u, label_w
= 0u;
265 struct tm
*tt
= localtime(&ttmp
);
268 int len
= strftime(t
, 1024, options
.strftime_format
.c_str(), tt
);
269 if (len
== 0) { // invalid time format found
270 // so use the default
271 const_cast<std::string
&>(options
.strftime_format
) = "%I:%M %p";
272 len
= strftime(t
, 1024, options
.strftime_format
.c_str(), tt
);
275 * find the length of the rendered string and add room for two extra
276 * characters to it. This allows for variable width output of the fonts.
277 * two 'w' are used to get the widest possible width
280 bt::textRect(_screen
->screenNumber(), style
.font
,
281 bt::toUnicode(t
)).width() +
282 bt::textRect(_screen
->screenNumber(), style
.font
,
283 bt::toUnicode("ww")).width();
287 for (unsigned int i
= 0; i
< _screen
->workspaceCount(); i
++) {
289 bt::textRect(_screen
->screenNumber(), style
.font
,
290 _screen
->resource().workspaceName(i
)).width();
291 label_w
= std::max(label_w
, width
);
294 label_w
= clock_w
= std::max(label_w
, clock_w
) + (style
.label_margin
* 2);
296 unsigned int window_label_w
=
297 (frame
.rect
.width() - (border_width
* 2)
298 - (clock_w
+ (style
.button_width
* 4) + label_w
299 + (style
.frame_margin
* 8))
302 XMoveResizeWindow(display
, frame
.window
, frame
.rect
.x(),
303 hidden
? frame
.y_hidden
: frame
.rect
.y(),
304 frame
.rect
.width(), frame
.rect
.height());
307 frame
.slabel_rect
.setRect(border_width
+ style
.frame_margin
,
308 border_width
+ style
.frame_margin
,
311 // previous workspace button
312 frame
.ps_rect
.setRect(border_width
+ (style
.frame_margin
* 2) + label_w
314 border_width
+ style
.frame_margin
,
317 // next workspace button
318 frame
.ns_rect
.setRect(border_width
+ (style
.frame_margin
* 3)
319 + label_w
+ style
.button_width
- (extra
* 2),
320 border_width
+ style
.frame_margin
,
324 frame
.wlabel_rect
.setRect(border_width
+ (style
.frame_margin
* 4)
325 + (style
.button_width
* 2) + label_w
- (extra
* 3),
326 border_width
+ style
.frame_margin
,
329 // previous window button
330 frame
.pw_rect
.setRect(border_width
+ (style
.frame_margin
* 5)
331 + (style
.button_width
* 2) + label_w
332 + window_label_w
- (extra
* 4),
333 border_width
+ style
.frame_margin
,
336 // next window button
337 frame
.nw_rect
.setRect(border_width
+ (style
.frame_margin
* 6)
338 + (style
.button_width
* 3) + label_w
339 + window_label_w
- (extra
* 5),
340 border_width
+ style
.frame_margin
,
344 frame
.clock_rect
.setRect(frame
.rect
.width() - clock_w
- style
.frame_margin
346 border_width
+ style
.frame_margin
,
350 XMoveResizeWindow(display
, frame
.workspace_label
,
351 frame
.slabel_rect
.x(), frame
.slabel_rect
.y(),
352 frame
.slabel_rect
.width(), frame
.slabel_rect
.height());
353 XMoveResizeWindow(display
, frame
.psbutton
,
354 frame
.ps_rect
.x(), frame
.ps_rect
.y(),
355 frame
.ps_rect
.width(), frame
.ps_rect
.height());
356 XMoveResizeWindow(display
, frame
.nsbutton
,
357 frame
.ns_rect
.x(), frame
.ns_rect
.y(),
358 frame
.ns_rect
.width(), frame
.ns_rect
.height());
359 XMoveResizeWindow(display
, frame
.window_label
,
360 frame
.wlabel_rect
.x(), frame
.wlabel_rect
.y(),
361 frame
.wlabel_rect
.width(), frame
.wlabel_rect
.height());
362 XMoveResizeWindow(display
, frame
.pwbutton
,
363 frame
.pw_rect
.x(), frame
.pw_rect
.y(),
364 frame
.pw_rect
.width(), frame
.pw_rect
.height());
365 XMoveResizeWindow(display
, frame
.nwbutton
,
366 frame
.nw_rect
.x(), frame
.nw_rect
.y(),
367 frame
.nw_rect
.width(), frame
.nw_rect
.height());
368 XMoveResizeWindow(display
, frame
.clock
,
369 frame
.clock_rect
.x(), frame
.clock_rect
.y(),
370 frame
.clock_rect
.width(), frame
.clock_rect
.height());
373 bt::PixmapCache::find(_screen
->screenNumber(), style
.toolbar
,
374 frame
.rect
.width(), frame
.rect
.height(),
377 bt::PixmapCache::find(_screen
->screenNumber(), style
.slabel
,
378 frame
.slabel_rect
.width(),
379 frame
.slabel_rect
.height(),
382 bt::PixmapCache::find(_screen
->screenNumber(), style
.wlabel
,
383 frame
.wlabel_rect
.width(),
384 frame
.wlabel_rect
.height(),
387 bt::PixmapCache::find(_screen
->screenNumber(), style
.clock
,
388 frame
.clock_rect
.width(),
389 frame
.clock_rect
.height(),
392 bt::PixmapCache::find(_screen
->screenNumber(), style
.button
,
393 style
.button_width
, style
.button_width
,
396 bt::PixmapCache::find(_screen
->screenNumber(),
398 style
.button_width
, style
.button_width
,
401 XClearArea(display
, frame
.window
, 0, 0,
402 frame
.rect
.width(), frame
.rect
.height(), True
);
404 XClearArea(display
, frame
.workspace_label
, 0, 0,
405 label_w
, style
.label_height
, True
);
406 XClearArea(display
, frame
.window_label
, 0, 0,
407 window_label_w
, style
.label_height
, True
);
408 XClearArea(display
, frame
.clock
, 0, 0,
409 clock_w
, style
.label_height
, True
);
411 XClearArea(display
, frame
.psbutton
, 0, 0,
412 style
.button_width
, style
.button_width
, True
);
413 XClearArea(display
, frame
.nsbutton
, 0, 0,
414 style
.button_width
, style
.button_width
, True
);
415 XClearArea(display
, frame
.pwbutton
, 0, 0,
416 style
.button_width
, style
.button_width
, True
);
417 XClearArea(display
, frame
.nwbutton
, 0, 0,
418 style
.button_width
, style
.button_width
, True
);
422 void Toolbar::updateStrut(void) {
423 // left and right are always 0
424 strut
.top
= strut
.bottom
= 0;
426 switch(_screen
->resource().toolbarOptions().placement
) {
430 strut
.top
= exposedHeight();
433 strut
.bottom
= exposedHeight();
436 _screen
->updateStrut();
440 void Toolbar::redrawClockLabel(void) {
441 const ToolbarOptions
&options
= _screen
->resource().toolbarOptions();
442 const ToolbarStyle
&style
= _screen
->resource().toolbarStyle();
444 bt::Rect
u(0, 0, frame
.clock_rect
.width(), frame
.clock_rect
.height());
445 if (frame
.clk
== ParentRelative
) {
446 bt::Rect
t(-frame
.clock_rect
.x(), -frame
.clock_rect
.y(),
447 frame
.rect
.width(), frame
.rect
.height());
448 bt::drawTexture(_screen
->screenNumber(), style
.toolbar
,
449 frame
.clock
, t
, u
, frame
.base
);
451 bt::drawTexture(_screen
->screenNumber(), style
.clock
,
452 frame
.clock
, u
, u
, frame
.clk
);
458 if ((tmp
= time(NULL
)) == -1)
459 return; // should not happen
460 tt
= localtime(&tmp
);
463 if (! strftime(str
, sizeof(str
), options
.strftime_format
.c_str(), tt
))
466 bt::Pen
pen(_screen
->screenNumber(), style
.clock_text
);
467 bt::drawText(style
.font
, pen
, frame
.clock
, u
, style
.alignment
,
472 void Toolbar::redrawWindowLabel(void) {
473 const ToolbarStyle
&style
= _screen
->resource().toolbarStyle();
475 bt::Rect
u(0, 0, frame
.wlabel_rect
.width(), frame
.wlabel_rect
.height());
476 if (frame
.wlabel
== ParentRelative
) {
477 bt::Rect
t(-frame
.wlabel_rect
.x(), -frame
.wlabel_rect
.y(),
478 frame
.rect
.width(), frame
.rect
.height());
479 bt::drawTexture(_screen
->screenNumber(), style
.toolbar
,
480 frame
.window_label
, t
, u
, frame
.base
);
482 bt::drawTexture(_screen
->screenNumber(), style
.wlabel
,
483 frame
.window_label
, u
, u
, frame
.wlabel
);
486 BlackboxWindow
*foc
= _screen
->blackbox()->focusedWindow();
487 if (! foc
|| foc
->screen() != _screen
)
490 bt::Pen
pen(_screen
->screenNumber(), style
.wlabel_text
);
491 bt::drawText(style
.font
, pen
, frame
.window_label
, u
,
493 bt::ellideText(foc
->title(), u
.width(), bt::toUnicode("..."),
494 _screen
->screenNumber(), style
.font
));
498 void Toolbar::redrawWorkspaceLabel(void) {
499 const bt::ustring
&name
=
500 _screen
->resource().workspaceName(_screen
->currentWorkspace());
501 const ToolbarStyle
&style
= _screen
->resource().toolbarStyle();
503 bt::Rect
u(0, 0, frame
.slabel_rect
.width(), frame
.slabel_rect
.height());
504 if (frame
.slabel
== ParentRelative
) {
505 bt::Rect
t(-frame
.slabel_rect
.x(), -frame
.slabel_rect
.y(),
506 frame
.rect
.width(), frame
.rect
.height());
507 bt::drawTexture(_screen
->screenNumber(), style
.toolbar
,
508 frame
.workspace_label
, t
, u
, frame
.base
);
510 bt::drawTexture(_screen
->screenNumber(), style
.slabel
,
511 frame
.workspace_label
, u
, u
, frame
.slabel
);
514 bt::Pen
pen(_screen
->screenNumber(), style
.slabel_text
);
515 bt::drawText(style
.font
, pen
, frame
.workspace_label
, u
,
516 style
.alignment
, name
);
520 void Toolbar::redrawPrevWorkspaceButton(bool pressed
) {
521 const ToolbarStyle
&style
=
522 _screen
->resource().toolbarStyle();
524 Pixmap p
= pressed
? frame
.pbutton
: frame
.button
;
525 bt::Rect
u(0, 0, style
.button_width
, style
.button_width
);
526 if (p
== ParentRelative
) {
527 bt::Rect
t(-frame
.ps_rect
.x(), -frame
.ps_rect
.y(),
528 frame
.rect
.width(), frame
.rect
.height());
529 bt::drawTexture(_screen
->screenNumber(), style
.toolbar
,
530 frame
.psbutton
, t
, u
, frame
.base
);
532 bt::drawTexture(_screen
->screenNumber(),
533 pressed
? style
.pressed
: style
.button
,
534 frame
.psbutton
, u
, u
, p
);
537 const bt::Pen
pen(_screen
->screenNumber(), style
.foreground
);
538 bt::drawBitmap(bt::Bitmap::leftArrow(_screen
->screenNumber()),
539 pen
, frame
.psbutton
, u
);
543 void Toolbar::redrawNextWorkspaceButton(bool pressed
) {
544 const ToolbarStyle
&style
=
545 _screen
->resource().toolbarStyle();
547 Pixmap p
= pressed
? frame
.pbutton
: frame
.button
;
548 bt::Rect
u(0, 0, style
.button_width
, style
.button_width
);
549 if (p
== ParentRelative
) {
550 bt::Rect
t(-frame
.ns_rect
.x(), -frame
.ns_rect
.y(),
551 frame
.rect
.width(), frame
.rect
.height());
552 bt::drawTexture(_screen
->screenNumber(), style
.toolbar
,
553 frame
.nsbutton
, t
, u
, frame
.base
);
555 bt::drawTexture(_screen
->screenNumber(),
556 pressed
? style
.pressed
: style
.button
,
557 frame
.nsbutton
, u
, u
, p
);
560 const bt::Pen
pen(_screen
->screenNumber(), style
.foreground
);
561 bt::drawBitmap(bt::Bitmap::rightArrow(_screen
->screenNumber()),
562 pen
, frame
.nsbutton
, u
);
566 void Toolbar::redrawPrevWindowButton(bool pressed
) {
567 const ToolbarStyle
&style
=
568 _screen
->resource().toolbarStyle();
570 Pixmap p
= pressed
? frame
.pbutton
: frame
.button
;
571 bt::Rect
u(0, 0, style
.button_width
, style
.button_width
);
572 if (p
== ParentRelative
) {
573 bt::Rect
t(-frame
.pw_rect
.x(), -frame
.pw_rect
.y(),
574 frame
.rect
.width(), frame
.rect
.height());
575 bt::drawTexture(_screen
->screenNumber(), style
.toolbar
,
576 frame
.pwbutton
, t
, u
, frame
.base
);
578 bt::drawTexture(_screen
->screenNumber(),
579 pressed
? style
.pressed
: style
.button
,
580 frame
.pwbutton
, u
, u
, p
);
583 const bt::Pen
pen(_screen
->screenNumber(), style
.foreground
);
584 bt::drawBitmap(bt::Bitmap::leftArrow(_screen
->screenNumber()),
585 pen
, frame
.pwbutton
, u
);
589 void Toolbar::redrawNextWindowButton(bool pressed
) {
590 const ToolbarStyle
&style
=
591 _screen
->resource().toolbarStyle();
593 Pixmap p
= pressed
? frame
.pbutton
: frame
.button
;
594 bt::Rect
u(0, 0, style
.button_width
, style
.button_width
);
595 if (p
== ParentRelative
) {
596 bt::Rect
t(-frame
.nw_rect
.x(), -frame
.nw_rect
.y(),
597 frame
.rect
.width(), frame
.rect
.height());
598 bt::drawTexture(_screen
->screenNumber(), style
.toolbar
,
599 frame
.nwbutton
, t
, u
, frame
.base
);
601 bt::drawTexture(_screen
->screenNumber(),
602 pressed
? style
.pressed
: style
.button
,
603 frame
.nwbutton
, u
, u
, p
);
606 const bt::Pen
pen(_screen
->screenNumber(), style
.foreground
);
607 bt::drawBitmap(bt::Bitmap::rightArrow(_screen
->screenNumber()),
608 pen
, frame
.nwbutton
, u
);
612 void Toolbar::buttonPressEvent(const XButtonEvent
* const event
) {
613 if (event
->state
== Mod1Mask
) {
614 if (event
->button
== 1)
615 _screen
->raiseWindow(this);
616 else if (event
->button
== 2)
617 _screen
->lowerWindow(this);
621 if (event
->button
== 1) {
622 if (event
->window
== frame
.psbutton
)
623 redrawPrevWorkspaceButton(True
);
624 else if (event
->window
== frame
.nsbutton
)
625 redrawNextWorkspaceButton(True
);
626 else if (event
->window
== frame
.pwbutton
)
627 redrawPrevWindowButton(True
);
628 else if (event
->window
== frame
.nwbutton
)
629 redrawNextWindowButton(True
);
633 if (event
->window
== frame
.window_label
) {
634 BlackboxWindow
*focus
= blackbox
->focusedWindow();
635 if (focus
&& focus
->screen() == _screen
) {
636 if (event
->button
== 2) {
637 _screen
->lowerWindow(focus
);
638 } else if (event
->button
== 3) {
639 Windowmenu
*windowmenu
= _screen
->windowmenu(focus
);
640 windowmenu
->popup(event
->x_root
, event
->y_root
,
641 _screen
->availableArea());
642 } else if (blackbox
->resource().toolbarActionsWithMouseWheel() &&
643 blackbox
->resource().shadeWindowWithMouseWheel() &&
644 focus
->hasWindowFunction(WindowFunctionShade
)) {
645 if ((event
->button
== 4) && !focus
->isShaded()) {
646 focus
->setShaded(true);
647 } else if ((event
->button
== 5) && focus
->isShaded()) {
648 focus
->setShaded(false);
655 if ((event
->window
== frame
.pwbutton
) || (event
->window
== frame
.nwbutton
)) {
656 if (blackbox
->resource().toolbarActionsWithMouseWheel()) {
657 if (event
->button
== 4)
658 _screen
->nextFocus();
659 else if (event
->button
== 5)
660 _screen
->prevFocus();
662 // XXX: current-workspace window-list menu with button 2 or 3 here..
666 // XXX: workspace-menu with button 2 or 3 on workspace-items (prev/next/label) here
668 // default-handlers (scroll through workspaces, popup toolbar-menu)
669 if (event
->button
== 3) {
670 _screen
->toolbarmenu()->popup(event
->x_root
, event
->y_root
,
671 _screen
->availableArea());
675 if (blackbox
->resource().toolbarActionsWithMouseWheel()) {
676 if (event
->button
== 4)
677 _screen
->nextWorkspace();
678 else if (event
->button
== 5)
679 _screen
->prevWorkspace();
684 void Toolbar::buttonReleaseEvent(const XButtonEvent
* const event
) {
685 if (event
->button
== 1) {
686 const ToolbarStyle
&style
=
687 _screen
->resource().toolbarStyle();
689 if (event
->window
== frame
.psbutton
) {
690 redrawPrevWorkspaceButton(False
);
692 if (bt::within(event
->x
, event
->y
,
693 style
.button_width
, style
.button_width
)) {
694 _screen
->prevWorkspace();
696 } else if (event
->window
== frame
.nsbutton
) {
697 redrawNextWorkspaceButton(False
);
699 if (bt::within(event
->x
, event
->y
,
700 style
.button_width
, style
.button_width
)) {
701 _screen
->nextWorkspace();
703 } else if (event
->window
== frame
.pwbutton
) {
704 redrawPrevWindowButton(False
);
706 if (bt::within(event
->x
, event
->y
,
707 style
.button_width
, style
.button_width
))
708 _screen
->prevFocus();
709 } else if (event
->window
== frame
.nwbutton
) {
710 redrawNextWindowButton(False
);
712 if (bt::within(event
->x
, event
->y
,
713 style
.button_width
, style
.button_width
))
714 _screen
->nextFocus();
715 } else if (event
->window
== frame
.window_label
)
716 _screen
->raiseFocus();
721 void Toolbar::enterNotifyEvent(const XCrossingEvent
* const /*unused*/) {
722 if (!_screen
->resource().toolbarOptions().auto_hide
)
726 if (! hide_timer
->isTiming())
728 } else if (hide_timer
->isTiming()) {
733 void Toolbar::leaveNotifyEvent(const XCrossingEvent
* const /*unused*/) {
734 if (!_screen
->resource().toolbarOptions().auto_hide
)
738 if (hide_timer
->isTiming())
740 } else if (! hide_timer
->isTiming()) {
746 void Toolbar::exposeEvent(const XExposeEvent
* const event
) {
747 if (event
->window
== frame
.clock
) redrawClockLabel();
748 else if (event
->window
== frame
.workspace_label
) redrawWorkspaceLabel();
749 else if (event
->window
== frame
.window_label
) redrawWindowLabel();
750 else if (event
->window
== frame
.psbutton
) redrawPrevWorkspaceButton();
751 else if (event
->window
== frame
.nsbutton
) redrawNextWorkspaceButton();
752 else if (event
->window
== frame
.pwbutton
) redrawPrevWindowButton();
753 else if (event
->window
== frame
.nwbutton
) redrawNextWindowButton();
754 else if (event
->window
== frame
.window
) {
755 bt::Rect
t(0, 0, frame
.rect
.width(), frame
.rect
.height());
756 bt::Rect
r(event
->x
, event
->y
, event
->width
, event
->height
);
757 bt::drawTexture(_screen
->screenNumber(),
758 _screen
->resource().toolbarStyle().toolbar
,
759 frame
.window
, t
, r
& t
, frame
.base
);
764 void Toolbar::timeout(bt::Timer
*timer
) {
765 if (timer
== clock_timer
) {
768 clock_timer
->setTimeout(nextTimeout(clock_timer_resolution
));
769 } else if (timer
== hide_timer
) {
772 XMoveWindow(display
, frame
.window
,
773 frame
.rect
.x(), frame
.y_hidden
);
775 XMoveWindow(display
, frame
.window
,
776 frame
.rect
.x(), frame
.rect
.y());
778 // this should not happen
784 void Toolbar::toggleAutoHide(void) {
785 bool do_auto_hide
= !_screen
->resource().toolbarOptions().auto_hide
;
789 _screen
->slit()->reposition();
791 if (!do_auto_hide
&& hidden
) {
792 // force the toolbar to be visible
793 if (hide_timer
->isTiming()) hide_timer
->stop();
794 hide_timer
->fireTimeout();
799 void Toolbar::setPlacement(Placement place
) {
800 ToolbarOptions
&options
=
801 const_cast<ToolbarOptions
&>(_screen
->resource().toolbarOptions());
802 options
.placement
= place
;
805 // reposition the slit as well to make sure it doesn't intersect the
808 _screen
->slit()->reposition();
810 _screen
->saveResource();