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
) {
45 gettimeofday(&now
, 0);
46 return (std::max(1000l, ((resolution
- (now
.tv_sec
% resolution
)) * 1000))
47 - (now
.tv_usec
/ 1000));
51 Toolbar::Toolbar(BScreen
*scrn
) {
53 blackbox
= _screen
->blackbox();
55 // get the clock updating every minute
56 clock_timer
= new bt::Timer(blackbox
, this);
57 clock_timer
->recurring(True
);
59 const ToolbarOptions
&options
= _screen
->resource().toolbarOptions();
61 const std::string
&time_format
= options
.strftime_format
;
62 if (time_format
.find("%S") != std::string::npos
63 || time_format
.find("%s") != std::string::npos
64 || time_format
.find("%r") != std::string::npos
65 || time_format
.find("%T") != std::string::npos
) {
66 clock_timer_resolution
= 1;
67 } else if (time_format
.find("%M") != std::string::npos
68 || time_format
.find("%R") != std::string::npos
) {
69 clock_timer_resolution
= 60;
71 clock_timer_resolution
= 3600;
74 hide_timer
= new bt::Timer(blackbox
, this);
75 hide_timer
->setTimeout(blackbox
->resource().autoRaiseDelay());
77 setLayer(options
.always_on_top
78 ? StackingList::LayerAbove
79 : StackingList::LayerNormal
);
80 hidden
= options
.auto_hide
;
84 display
= blackbox
->XDisplay();
85 XSetWindowAttributes attrib
;
86 unsigned long create_mask
= CWColormap
| CWOverrideRedirect
| CWEventMask
;
87 attrib
.colormap
= _screen
->screenInfo().colormap();
88 attrib
.override_redirect
= True
;
89 attrib
.event_mask
= ButtonPressMask
| ButtonReleaseMask
|
90 EnterWindowMask
| LeaveWindowMask
| ExposureMask
;
93 XCreateWindow(display
, _screen
->screenInfo().rootWindow(), 0, 0, 1, 1, 0,
94 _screen
->screenInfo().depth(), InputOutput
,
95 _screen
->screenInfo().visual(),
96 create_mask
, &attrib
);
97 blackbox
->insertEventHandler(frame
.window
, this);
100 ButtonPressMask
| ButtonReleaseMask
| ExposureMask
| EnterWindowMask
;
102 frame
.workspace_label
=
103 XCreateWindow(display
, frame
.window
, 0, 0, 1, 1, 0,
104 _screen
->screenInfo().depth(), InputOutput
,
105 _screen
->screenInfo().visual(),
106 create_mask
, &attrib
);
107 blackbox
->insertEventHandler(frame
.workspace_label
, this);
110 XCreateWindow(display
, frame
.window
, 0, 0, 1, 1, 0,
111 _screen
->screenInfo().depth(), InputOutput
,
112 _screen
->screenInfo().visual(),
113 create_mask
, &attrib
);
114 blackbox
->insertEventHandler(frame
.window_label
, this);
117 XCreateWindow(display
, frame
.window
, 0, 0, 1, 1, 0,
118 _screen
->screenInfo().depth(), InputOutput
,
119 _screen
->screenInfo().visual(),
120 create_mask
, &attrib
);
121 blackbox
->insertEventHandler(frame
.clock
, this);
124 XCreateWindow(display
,frame
.window
, 0, 0, 1, 1, 0,
125 _screen
->screenInfo().depth(), InputOutput
,
126 _screen
->screenInfo().visual(),
127 create_mask
, &attrib
);
128 blackbox
->insertEventHandler(frame
.psbutton
, this);
131 XCreateWindow(display
,frame
.window
, 0, 0, 1, 1, 0,
132 _screen
->screenInfo().depth(), InputOutput
,
133 _screen
->screenInfo().visual(),
134 create_mask
, &attrib
);
135 blackbox
->insertEventHandler(frame
.nsbutton
, this);
138 XCreateWindow(display
,frame
.window
, 0, 0, 1, 1, 0,
139 _screen
->screenInfo().depth(), InputOutput
,
140 _screen
->screenInfo().visual(),
141 create_mask
, &attrib
);
142 blackbox
->insertEventHandler(frame
.pwbutton
, this);
145 XCreateWindow(display
,frame
.window
, 0, 0, 1, 1, 0,
146 _screen
->screenInfo().depth(), InputOutput
,
147 _screen
->screenInfo().visual(),
148 create_mask
, &attrib
);
149 blackbox
->insertEventHandler(frame
.nwbutton
, this);
151 frame
.base
= frame
.slabel
= frame
.wlabel
= frame
.clk
= frame
.button
=
152 frame
.pbutton
= None
;
154 _screen
->addStrut(&strut
);
158 clock_timer
->setTimeout(nextTimeout(clock_timer_resolution
));
159 clock_timer
->start();
161 XMapSubwindows(display
, frame
.window
);
162 XMapWindow(display
, frame
.window
);
166 Toolbar::~Toolbar(void) {
167 _screen
->removeStrut(&strut
);
169 XUnmapWindow(display
, frame
.window
);
171 bt::PixmapCache::release(frame
.base
);
172 bt::PixmapCache::release(frame
.slabel
);
173 bt::PixmapCache::release(frame
.wlabel
);
174 bt::PixmapCache::release(frame
.clk
);
175 bt::PixmapCache::release(frame
.button
);
176 bt::PixmapCache::release(frame
.pbutton
);
178 blackbox
->removeEventHandler(frame
.window
);
179 blackbox
->removeEventHandler(frame
.workspace_label
);
180 blackbox
->removeEventHandler(frame
.window_label
);
181 blackbox
->removeEventHandler(frame
.clock
);
182 blackbox
->removeEventHandler(frame
.psbutton
);
183 blackbox
->removeEventHandler(frame
.nsbutton
);
184 blackbox
->removeEventHandler(frame
.pwbutton
);
185 blackbox
->removeEventHandler(frame
.nwbutton
);
187 // all children windows are destroyed by this call as well
188 XDestroyWindow(display
, frame
.window
);
195 unsigned int Toolbar::exposedHeight(void) const {
196 const ToolbarOptions
&options
= _screen
->resource().toolbarOptions();
197 const ToolbarStyle
&style
= _screen
->resource().toolbarStyle();
198 return (options
.auto_hide
? style
.hidden_height
: style
.toolbar_height
);
202 void Toolbar::reconfigure(void) {
203 ScreenResource
&resource
= _screen
->resource();
204 const ToolbarOptions
&options
= resource
.toolbarOptions();
205 const ToolbarStyle
&style
= resource
.toolbarStyle();
207 unsigned int width
= (_screen
->screenInfo().width() *
208 options
.width_percent
) / 100;
210 const unsigned int border_width
= style
.toolbar
.borderWidth();
211 const unsigned int extra
=
212 style
.frame_margin
== 0 ? style
.button
.borderWidth() : 0;
213 frame
.rect
.setSize(width
, style
.toolbar_height
);
216 switch (options
.placement
) {
220 switch (options
.placement
) {
225 x
= _screen
->screenInfo().width() - frame
.rect
.width();
228 x
= (_screen
->screenInfo().width() - frame
.rect
.width()) / 2;
232 frame
.y_hidden
= style
.hidden_height
- frame
.rect
.height();
239 switch (options
.placement
) {
244 x
= _screen
->screenInfo().width() - frame
.rect
.width();
247 x
= (_screen
->screenInfo().width() - frame
.rect
.width()) / 2;
250 y
= _screen
->screenInfo().height() - frame
.rect
.height();
251 frame
.y_hidden
= _screen
->screenInfo().height() - style
.hidden_height
;
255 frame
.rect
.setPos(x
, y
);
259 time_t ttmp
= time(NULL
);
261 unsigned int clock_w
= 0u, label_w
= 0u;
264 struct tm
*tt
= localtime(&ttmp
);
267 int len
= strftime(t
, 1024, options
.strftime_format
.c_str(), tt
);
268 if (len
== 0) { // invalid time format found
269 // so use the default
270 const_cast<std::string
&>(options
.strftime_format
) = "%I:%M %p";
271 len
= strftime(t
, 1024, options
.strftime_format
.c_str(), tt
);
274 * find the length of the rendered string and add room for two extra
275 * characters to it. This allows for variable width output of the fonts.
276 * two 'w' are used to get the widest possible width
279 bt::textRect(_screen
->screenNumber(), style
.font
,
280 bt::toUnicode(t
)).width() +
281 bt::textRect(_screen
->screenNumber(), style
.font
,
282 bt::toUnicode("ww")).width();
286 for (unsigned int i
= 0; i
< _screen
->workspaceCount(); i
++) {
288 bt::textRect(_screen
->screenNumber(), style
.font
,
289 _screen
->resource().workspaceName(i
)).width();
290 label_w
= std::max(label_w
, width
);
293 label_w
= clock_w
= std::max(label_w
, clock_w
) + (style
.label_margin
* 2);
295 unsigned int window_label_w
=
296 (frame
.rect
.width() - (border_width
* 2)
297 - (clock_w
+ (style
.button_width
* 4) + label_w
298 + (style
.frame_margin
* 8))
301 XMoveResizeWindow(display
, frame
.window
, frame
.rect
.x(),
302 hidden
? frame
.y_hidden
: frame
.rect
.y(),
303 frame
.rect
.width(), frame
.rect
.height());
306 frame
.slabel_rect
.setRect(border_width
+ style
.frame_margin
,
307 border_width
+ style
.frame_margin
,
310 // previous workspace button
311 frame
.ps_rect
.setRect(border_width
+ (style
.frame_margin
* 2) + label_w
313 border_width
+ style
.frame_margin
,
316 // next workspace button
317 frame
.ns_rect
.setRect(border_width
+ (style
.frame_margin
* 3)
318 + label_w
+ style
.button_width
- (extra
* 2),
319 border_width
+ style
.frame_margin
,
323 frame
.wlabel_rect
.setRect(border_width
+ (style
.frame_margin
* 4)
324 + (style
.button_width
* 2) + label_w
- (extra
* 3),
325 border_width
+ style
.frame_margin
,
328 // previous window button
329 frame
.pw_rect
.setRect(border_width
+ (style
.frame_margin
* 5)
330 + (style
.button_width
* 2) + label_w
331 + window_label_w
- (extra
* 4),
332 border_width
+ style
.frame_margin
,
335 // next window button
336 frame
.nw_rect
.setRect(border_width
+ (style
.frame_margin
* 6)
337 + (style
.button_width
* 3) + label_w
338 + window_label_w
- (extra
* 5),
339 border_width
+ style
.frame_margin
,
343 frame
.clock_rect
.setRect(frame
.rect
.width() - clock_w
- style
.frame_margin
345 border_width
+ style
.frame_margin
,
349 XMoveResizeWindow(display
, frame
.workspace_label
,
350 frame
.slabel_rect
.x(), frame
.slabel_rect
.y(),
351 frame
.slabel_rect
.width(), frame
.slabel_rect
.height());
352 XMoveResizeWindow(display
, frame
.psbutton
,
353 frame
.ps_rect
.x(), frame
.ps_rect
.y(),
354 frame
.ps_rect
.width(), frame
.ps_rect
.height());
355 XMoveResizeWindow(display
, frame
.nsbutton
,
356 frame
.ns_rect
.x(), frame
.ns_rect
.y(),
357 frame
.ns_rect
.width(), frame
.ns_rect
.height());
358 XMoveResizeWindow(display
, frame
.window_label
,
359 frame
.wlabel_rect
.x(), frame
.wlabel_rect
.y(),
360 frame
.wlabel_rect
.width(), frame
.wlabel_rect
.height());
361 XMoveResizeWindow(display
, frame
.pwbutton
,
362 frame
.pw_rect
.x(), frame
.pw_rect
.y(),
363 frame
.pw_rect
.width(), frame
.pw_rect
.height());
364 XMoveResizeWindow(display
, frame
.nwbutton
,
365 frame
.nw_rect
.x(), frame
.nw_rect
.y(),
366 frame
.nw_rect
.width(), frame
.nw_rect
.height());
367 XMoveResizeWindow(display
, frame
.clock
,
368 frame
.clock_rect
.x(), frame
.clock_rect
.y(),
369 frame
.clock_rect
.width(), frame
.clock_rect
.height());
372 bt::PixmapCache::find(_screen
->screenNumber(), style
.toolbar
,
373 frame
.rect
.width(), frame
.rect
.height(),
376 bt::PixmapCache::find(_screen
->screenNumber(), style
.slabel
,
377 frame
.slabel_rect
.width(),
378 frame
.slabel_rect
.height(),
381 bt::PixmapCache::find(_screen
->screenNumber(), style
.wlabel
,
382 frame
.wlabel_rect
.width(),
383 frame
.wlabel_rect
.height(),
386 bt::PixmapCache::find(_screen
->screenNumber(), style
.clock
,
387 frame
.clock_rect
.width(),
388 frame
.clock_rect
.height(),
391 bt::PixmapCache::find(_screen
->screenNumber(), style
.button
,
392 style
.button_width
, style
.button_width
,
395 bt::PixmapCache::find(_screen
->screenNumber(),
397 style
.button_width
, style
.button_width
,
400 XClearArea(display
, frame
.window
, 0, 0,
401 frame
.rect
.width(), frame
.rect
.height(), True
);
403 XClearArea(display
, frame
.workspace_label
, 0, 0,
404 label_w
, style
.label_height
, True
);
405 XClearArea(display
, frame
.window_label
, 0, 0,
406 window_label_w
, style
.label_height
, True
);
407 XClearArea(display
, frame
.clock
, 0, 0,
408 clock_w
, style
.label_height
, True
);
410 XClearArea(display
, frame
.psbutton
, 0, 0,
411 style
.button_width
, style
.button_width
, True
);
412 XClearArea(display
, frame
.nsbutton
, 0, 0,
413 style
.button_width
, style
.button_width
, True
);
414 XClearArea(display
, frame
.pwbutton
, 0, 0,
415 style
.button_width
, style
.button_width
, True
);
416 XClearArea(display
, frame
.nwbutton
, 0, 0,
417 style
.button_width
, style
.button_width
, True
);
421 void Toolbar::updateStrut(void) {
422 // left and right are always 0
423 strut
.top
= strut
.bottom
= 0;
425 switch(_screen
->resource().toolbarOptions().placement
) {
429 strut
.top
= exposedHeight();
432 strut
.bottom
= exposedHeight();
435 _screen
->updateStrut();
439 void Toolbar::redrawClockLabel(void) {
440 const ToolbarOptions
&options
= _screen
->resource().toolbarOptions();
441 const ToolbarStyle
&style
= _screen
->resource().toolbarStyle();
443 bt::Rect
u(0, 0, frame
.clock_rect
.width(), frame
.clock_rect
.height());
444 if (frame
.clk
== ParentRelative
) {
445 bt::Rect
t(-frame
.clock_rect
.x(), -frame
.clock_rect
.y(),
446 frame
.rect
.width(), frame
.rect
.height());
447 bt::drawTexture(_screen
->screenNumber(), style
.toolbar
,
448 frame
.clock
, t
, u
, frame
.base
);
450 bt::drawTexture(_screen
->screenNumber(), style
.clock
,
451 frame
.clock
, u
, u
, frame
.clk
);
457 if ((tmp
= time(NULL
)) == -1)
458 return; // should not happen
459 tt
= localtime(&tmp
);
462 if (! strftime(str
, 1024, options
.strftime_format
.c_str(), tt
))
465 bt::Pen
pen(_screen
->screenNumber(), style
.clock_text
);
466 bt::drawText(style
.font
, pen
, frame
.clock
, u
, style
.alignment
,
471 void Toolbar::redrawWindowLabel(void) {
472 const ToolbarStyle
&style
= _screen
->resource().toolbarStyle();
474 bt::Rect
u(0, 0, frame
.wlabel_rect
.width(), frame
.wlabel_rect
.height());
475 if (frame
.wlabel
== ParentRelative
) {
476 bt::Rect
t(-frame
.wlabel_rect
.x(), -frame
.wlabel_rect
.y(),
477 frame
.rect
.width(), frame
.rect
.height());
478 bt::drawTexture(_screen
->screenNumber(), style
.toolbar
,
479 frame
.window_label
, t
, u
, frame
.base
);
481 bt::drawTexture(_screen
->screenNumber(), style
.wlabel
,
482 frame
.window_label
, u
, u
, frame
.wlabel
);
485 BlackboxWindow
*foc
= _screen
->blackbox()->focusedWindow();
486 if (! foc
|| foc
->screen() != _screen
)
489 bt::Pen
pen(_screen
->screenNumber(), style
.wlabel_text
);
490 bt::drawText(style
.font
, pen
, frame
.window_label
, u
,
492 bt::ellideText(foc
->title(), u
.width(), bt::toUnicode("..."),
493 _screen
->screenNumber(), style
.font
));
497 void Toolbar::redrawWorkspaceLabel(void) {
498 const bt::ustring
&name
=
499 _screen
->resource().workspaceName(_screen
->currentWorkspace());
500 const ToolbarStyle
&style
= _screen
->resource().toolbarStyle();
502 bt::Rect
u(0, 0, frame
.slabel_rect
.width(), frame
.slabel_rect
.height());
503 if (frame
.slabel
== ParentRelative
) {
504 bt::Rect
t(-frame
.slabel_rect
.x(), -frame
.slabel_rect
.y(),
505 frame
.rect
.width(), frame
.rect
.height());
506 bt::drawTexture(_screen
->screenNumber(), style
.toolbar
,
507 frame
.workspace_label
, t
, u
, frame
.base
);
509 bt::drawTexture(_screen
->screenNumber(), style
.slabel
,
510 frame
.workspace_label
, u
, u
, frame
.slabel
);
513 bt::Pen
pen(_screen
->screenNumber(), style
.slabel_text
);
514 bt::drawText(style
.font
, pen
, frame
.workspace_label
, u
,
515 style
.alignment
, name
);
519 void Toolbar::redrawPrevWorkspaceButton(bool pressed
) {
520 const ToolbarStyle
&style
=
521 _screen
->resource().toolbarStyle();
523 Pixmap p
= pressed
? frame
.pbutton
: frame
.button
;
524 bt::Rect
u(0, 0, style
.button_width
, style
.button_width
);
525 if (p
== ParentRelative
) {
526 bt::Rect
t(-frame
.ps_rect
.x(), -frame
.ps_rect
.y(),
527 frame
.rect
.width(), frame
.rect
.height());
528 bt::drawTexture(_screen
->screenNumber(), style
.toolbar
,
529 frame
.psbutton
, t
, u
, frame
.base
);
531 bt::drawTexture(_screen
->screenNumber(),
532 pressed
? style
.pressed
: style
.button
,
533 frame
.psbutton
, u
, u
, p
);
536 const bt::Pen
pen(_screen
->screenNumber(), style
.foreground
);
537 bt::drawBitmap(bt::Bitmap::leftArrow(_screen
->screenNumber()),
538 pen
, frame
.psbutton
, u
);
542 void Toolbar::redrawNextWorkspaceButton(bool pressed
) {
543 const ToolbarStyle
&style
=
544 _screen
->resource().toolbarStyle();
546 Pixmap p
= pressed
? frame
.pbutton
: frame
.button
;
547 bt::Rect
u(0, 0, style
.button_width
, style
.button_width
);
548 if (p
== ParentRelative
) {
549 bt::Rect
t(-frame
.ns_rect
.x(), -frame
.ns_rect
.y(),
550 frame
.rect
.width(), frame
.rect
.height());
551 bt::drawTexture(_screen
->screenNumber(), style
.toolbar
,
552 frame
.nsbutton
, t
, u
, frame
.base
);
554 bt::drawTexture(_screen
->screenNumber(),
555 pressed
? style
.pressed
: style
.button
,
556 frame
.nsbutton
, u
, u
, p
);
559 const bt::Pen
pen(_screen
->screenNumber(), style
.foreground
);
560 bt::drawBitmap(bt::Bitmap::rightArrow(_screen
->screenNumber()),
561 pen
, frame
.nsbutton
, u
);
565 void Toolbar::redrawPrevWindowButton(bool pressed
) {
566 const ToolbarStyle
&style
=
567 _screen
->resource().toolbarStyle();
569 Pixmap p
= pressed
? frame
.pbutton
: frame
.button
;
570 bt::Rect
u(0, 0, style
.button_width
, style
.button_width
);
571 if (p
== ParentRelative
) {
572 bt::Rect
t(-frame
.pw_rect
.x(), -frame
.pw_rect
.y(),
573 frame
.rect
.width(), frame
.rect
.height());
574 bt::drawTexture(_screen
->screenNumber(), style
.toolbar
,
575 frame
.pwbutton
, t
, u
, frame
.base
);
577 bt::drawTexture(_screen
->screenNumber(),
578 pressed
? style
.pressed
: style
.button
,
579 frame
.pwbutton
, u
, u
, p
);
582 const bt::Pen
pen(_screen
->screenNumber(), style
.foreground
);
583 bt::drawBitmap(bt::Bitmap::leftArrow(_screen
->screenNumber()),
584 pen
, frame
.pwbutton
, u
);
588 void Toolbar::redrawNextWindowButton(bool pressed
) {
589 const ToolbarStyle
&style
=
590 _screen
->resource().toolbarStyle();
592 Pixmap p
= pressed
? frame
.pbutton
: frame
.button
;
593 bt::Rect
u(0, 0, style
.button_width
, style
.button_width
);
594 if (p
== ParentRelative
) {
595 bt::Rect
t(-frame
.nw_rect
.x(), -frame
.nw_rect
.y(),
596 frame
.rect
.width(), frame
.rect
.height());
597 bt::drawTexture(_screen
->screenNumber(), style
.toolbar
,
598 frame
.nwbutton
, t
, u
, frame
.base
);
600 bt::drawTexture(_screen
->screenNumber(),
601 pressed
? style
.pressed
: style
.button
,
602 frame
.nwbutton
, u
, u
, p
);
605 const bt::Pen
pen(_screen
->screenNumber(), style
.foreground
);
606 bt::drawBitmap(bt::Bitmap::rightArrow(_screen
->screenNumber()),
607 pen
, frame
.nwbutton
, u
);
611 void Toolbar::buttonPressEvent(const XButtonEvent
* const event
) {
612 if (event
->button
== 1) {
613 _screen
->raiseWindow(this);
614 if (event
->window
== frame
.psbutton
)
615 redrawPrevWorkspaceButton(True
);
616 else if (event
->window
== frame
.nsbutton
)
617 redrawNextWorkspaceButton(True
);
618 else if (event
->window
== frame
.pwbutton
)
619 redrawPrevWindowButton(True
);
620 else if (event
->window
== frame
.nwbutton
)
621 redrawNextWindowButton(True
);
622 } else if (event
->button
== 2) {
623 _screen
->lowerWindow(this);
624 } else if (event
->button
== 3) {
625 BlackboxWindow
*focus
= blackbox
->focusedWindow();
626 if (event
->window
== frame
.window_label
&&
627 focus
&& focus
->screen() == _screen
) {
628 Windowmenu
*windowmenu
= _screen
->windowmenu(focus
);
629 windowmenu
->popup(event
->x_root
, event
->y_root
,
630 _screen
->availableArea());
632 _screen
->toolbarmenu()->popup(event
->x_root
, event
->y_root
,
633 _screen
->availableArea());
639 void Toolbar::buttonReleaseEvent(const XButtonEvent
* const event
) {
640 if (event
->button
== 1) {
641 const ToolbarStyle
&style
=
642 _screen
->resource().toolbarStyle();
644 if (event
->window
== frame
.psbutton
) {
645 redrawPrevWorkspaceButton(False
);
647 if (bt::within(event
->x
, event
->y
,
648 style
.button_width
, style
.button_width
)) {
650 if (_screen
->currentWorkspace() > 0)
651 new_workspace
= _screen
->currentWorkspace() - 1;
653 new_workspace
= _screen
->workspaceCount() - 1;
654 _screen
->setCurrentWorkspace(new_workspace
);
656 } else if (event
->window
== frame
.nsbutton
) {
657 redrawNextWorkspaceButton(False
);
659 if (bt::within(event
->x
, event
->y
,
660 style
.button_width
, style
.button_width
))
661 if (_screen
->currentWorkspace() < _screen
->workspaceCount() - 1)
662 _screen
->setCurrentWorkspace(_screen
->currentWorkspace() + 1);
664 _screen
->setCurrentWorkspace(0);
665 } else if (event
->window
== frame
.pwbutton
) {
666 redrawPrevWindowButton(False
);
668 if (bt::within(event
->x
, event
->y
,
669 style
.button_width
, style
.button_width
))
670 _screen
->prevFocus();
671 } else if (event
->window
== frame
.nwbutton
) {
672 redrawNextWindowButton(False
);
674 if (bt::within(event
->x
, event
->y
,
675 style
.button_width
, style
.button_width
))
676 _screen
->nextFocus();
677 } else if (event
->window
== frame
.window_label
)
678 _screen
->raiseFocus();
683 void Toolbar::enterNotifyEvent(const XCrossingEvent
* const /*unused*/) {
684 if (!_screen
->resource().toolbarOptions().auto_hide
)
688 if (! hide_timer
->isTiming())
690 } else if (hide_timer
->isTiming()) {
695 void Toolbar::leaveNotifyEvent(const XCrossingEvent
* const /*unused*/) {
696 if (!_screen
->resource().toolbarOptions().auto_hide
)
700 if (hide_timer
->isTiming())
702 } else if (! hide_timer
->isTiming()) {
708 void Toolbar::exposeEvent(const XExposeEvent
* const event
) {
709 if (event
->window
== frame
.clock
) redrawClockLabel();
710 else if (event
->window
== frame
.workspace_label
) redrawWorkspaceLabel();
711 else if (event
->window
== frame
.window_label
) redrawWindowLabel();
712 else if (event
->window
== frame
.psbutton
) redrawPrevWorkspaceButton();
713 else if (event
->window
== frame
.nsbutton
) redrawNextWorkspaceButton();
714 else if (event
->window
== frame
.pwbutton
) redrawPrevWindowButton();
715 else if (event
->window
== frame
.nwbutton
) redrawNextWindowButton();
716 else if (event
->window
== frame
.window
) {
717 bt::Rect
t(0, 0, frame
.rect
.width(), frame
.rect
.height());
718 bt::Rect
r(event
->x
, event
->y
, event
->width
, event
->height
);
719 bt::drawTexture(_screen
->screenNumber(),
720 _screen
->resource().toolbarStyle().toolbar
,
721 frame
.window
, t
, r
& t
, frame
.base
);
726 void Toolbar::timeout(bt::Timer
*timer
) {
727 if (timer
== clock_timer
) {
730 clock_timer
->setTimeout(nextTimeout(clock_timer_resolution
));
731 } else if (timer
== hide_timer
) {
734 XMoveWindow(display
, frame
.window
,
735 frame
.rect
.x(), frame
.y_hidden
);
737 XMoveWindow(display
, frame
.window
,
738 frame
.rect
.x(), frame
.rect
.y());
740 // this should not happen
746 void Toolbar::toggleAutoHide(void) {
747 bool do_auto_hide
= !_screen
->resource().toolbarOptions().auto_hide
;
751 _screen
->slit()->reposition();
753 if (!do_auto_hide
&& hidden
) {
754 // force the toolbar to be visible
755 if (hide_timer
->isTiming()) hide_timer
->stop();
756 hide_timer
->fireTimeout();
761 void Toolbar::setPlacement(Placement place
) {
762 ToolbarOptions
&options
=
763 const_cast<ToolbarOptions
&>(_screen
->resource().toolbarOptions());
764 options
.placement
= place
;
767 // reposition the slit as well to make sure it doesn't intersect the
770 _screen
->slit()->reposition();
772 _screen
->saveResource();