1
// Window.cc for Fluxbox Window Manager
2
// Copyright (c) 2001 - 2002 Henrik Kinnunen (fluxgen@linuxmail.org)
4
// Window.cc for Blackbox - an X11 Window manager
5
// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
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.
25
// $Id: Window.cc,v 1.31 2002/02/27 22:04:01 fluxgen Exp $
33
# include "../config.h"
34
#endif // HAVE_CONFIG_H
42
#include "Windowmenu.hh"
43
#include "StringUtil.hh"
49
#include <X11/Xatom.h>
50
#include <X11/keysym.h>
54
#endif // STDC_HEADERS
59
# endif // HAVE_STDIO_H
66
FluxboxWindow::FluxboxWindow(Window w, BScreen *s):
68
moving(false), resizing(false), shaded(false), maximized(false),
69
visible(false), iconic(false), transient(false), focused(false),
70
stuck(false), modal(false), send_focus_message(false), managed(false),
74
lastButtonPressTime(0),
76
m_layer(LAYER_NORMAL),
88
WindowSet, WindowCreating,
92
"FluxboxWindow::FluxboxWindow(): creating 0x%lx\n"),
96
Fluxbox *fluxbox = Fluxbox::instance();
97
display = fluxbox->getXDisplay();
98
BaseDisplay::GrabGuard gg(*fluxbox);
100
blackbox_attrib.workspace = workspace_number = window_number = -1;
102
blackbox_attrib.flags = blackbox_attrib.attrib = blackbox_attrib.stack = 0l;
103
blackbox_attrib.premax_x = blackbox_attrib.premax_y = 0;
104
blackbox_attrib.premax_w = blackbox_attrib.premax_h = 0;
106
decorations.tab = true;
108
frame.window = frame.plate = frame.title = frame.handle = None;
109
frame.right_grip = frame.left_grip = None;
111
frame.utitle = frame.ftitle = frame.uhandle = frame.fhandle = None;
112
frame.ulabel = frame.flabel = frame.ubutton = frame.fbutton = None;
113
frame.pbutton = frame.ugrip = frame.fgrip = None;
116
vector<Fluxbox::Titlebar> dir = fluxbox->getTitlebarLeft();
117
for (char c=0; c<2; c++) {
118
for (unsigned int i=0; i<dir.size(); i++) {
121
decorations.shade = true;
123
case Fluxbox::MAXIMIZE:
124
decorations.maximize = true;
126
case Fluxbox::MINIMIZE:
127
decorations.iconify = true;
130
decorations.sticky = true;
133
decorations.close = true;
136
decorations.menu = true;
143
dir = fluxbox->getTitlebarRight();
146
decorations.menu = true; //override menu option
148
decorations.titlebar = decorations.border = decorations.handle = true;
149
functions.resize = functions.move = functions.iconify = functions.maximize = true;
150
functions.close = decorations.close = false;
152
client.wm_hint_flags = client.normal_hint_flags = 0;
153
client.transient_for = client.transient = 0;
155
client.title_len = 0;
156
client.icon_title = 0;
157
client.mwm_hint = (MwmHints *) 0;
158
client.blackbox_hint = 0;
161
if (! validateClient())
164
// fetch client size and placement
165
XWindowAttributes wattrib;
166
if ((! XGetWindowAttributes(display, client.window, &wattrib)) ||
167
(! wattrib.screen) || wattrib.override_redirect) {
174
screen = fluxbox->searchScreen(RootWindowOfScreen(wattrib.screen));
179
image_ctrl = screen->getImageControl();
181
client.x = wattrib.x;
182
client.y = wattrib.y;
183
client.width = wattrib.width;
184
client.height = wattrib.height;
185
client.old_bw = wattrib.border_width;
187
timer = new BTimer(fluxbox, this);
188
timer->setTimeout(fluxbox->getAutoRaiseDelay());
189
timer->fireOnce(true);
192
if (! client.blackbox_hint)
195
// get size, aspect, minimum/maximum size and other hints set by the
203
if (client.initial_state == WithdrawnState) {
204
screen->getSlit()->addClient(client.window);
209
managed = true; //mark for usage
211
fluxbox->saveWindowSearch(client.window, this);
213
// determine if this is a transient window
215
if (XGetTransientForHint(display, client.window, &win)) {
216
if (win && (win != client.window)) {
218
if ((tr = fluxbox->searchWindow(win))) {
220
while (tr->client.transient)
221
tr = tr->client.transient;
223
client.transient_for = tr;
224
tr->client.transient = this;
225
stuck = client.transient_for->stuck;
227
} else if (win == client.window_group) {
228
if ((tr = fluxbox->searchGroup(win, this))) {
230
while (tr->client.transient)
231
tr = tr->client.transient;
233
client.transient_for = tr;
234
tr->client.transient = this;
235
stuck = client.transient_for->stuck;
241
if (win == screen->getRootWindow())
245
// adjust the window decorations based on transience and window sizes
247
decorations.maximize = decorations.handle =
248
decorations.border = functions.maximize = false;
251
if ((client.normal_hint_flags & PMinSize) &&
252
(client.normal_hint_flags & PMaxSize) &&
253
client.max_width <= client.min_width &&
254
client.max_height <= client.min_height) {
255
decorations.maximize = decorations.handle =
256
functions.resize = functions.maximize = false;
257
decorations.tab = false; //no tab for this window
262
bool place_window = true;
263
if (fluxbox->isStartup() || transient ||
264
client.normal_hint_flags & (PPosition|USPosition)) {
267
if (! fluxbox->isStartup()) { // is going to be used when position
268
if (decorations.tab) { // window is cleanly fixed
269
int real_x = frame.x;
270
int real_y = frame.y;
272
if (screen->getTabPlacement() == Tab::PTOP)
273
real_y -= screen->getTabHeight();
275
else if (screen->getTabPlacement() == Tab::PLEFT) {
276
if (screen->isTabRotateVertical())
277
real_x -= screen->getTabHeight();
279
real_x -= screen->getTabWidth();
283
real_y + frame.y_border >= 0 &&
284
real_x <= (signed) screen->getWidth() &&
285
real_y <= (signed) screen->getHeight())
286
place_window = false;
288
} else if (frame.x >= 0 && // non tab
289
(signed) (frame.y + frame.y_border) >= 0 &&
290
frame.x <= (signed) screen->getWidth() &&
291
frame.y <= (signed) screen->getHeight())
292
place_window = false;
294
place_window = false;
296
/* if ((fluxbox->isStartup()) ||
298
(signed) (frame.y + frame.y_border) >= 0 &&
299
frame.x <= (signed) screen->getWidth() &&
300
frame.y <= (signed) screen->getHeight()))
301
place_window = false; */
305
frame.window = createToplevelWindow(frame.x, frame.y, frame.width,
307
screen->getBorderWidth()); //create frame window
309
fluxbox->saveWindowSearch(frame.window, this); //save frame window
311
frame.plate = createChildWindow(frame.window); //Create plate window
312
fluxbox->saveWindowSearch(frame.plate, this); //save plate window
314
frame.title = createChildWindow(frame.window); //create titlebar win
315
if (decorations.titlebar) { //have titlebar decorations?
316
fluxbox->saveWindowSearch(frame.title, this); //save titlebar win
317
frame.label = createChildWindow(frame.title); //create label win in titlebar
318
fluxbox->saveWindowSearch(frame.label, this); //save label win
321
if (decorations.handle) { //have handle decorations ?
322
frame.handle = createChildWindow(frame.window); //create handle win
323
fluxbox->saveWindowSearch(frame.handle, this); //save handle win
325
frame.left_grip = // create left handle
326
createChildWindow(frame.handle, fluxbox->getLowerLeftAngleCursor());
327
fluxbox->saveWindowSearch(frame.left_grip, this); //save left handle
329
frame.right_grip = // create right handle
330
createChildWindow(frame.handle, fluxbox->getLowerRightAngleCursor());
331
fluxbox->saveWindowSearch(frame.right_grip, this); //save right handle
335
associateClientWindow();
341
//use tab? delayed this so that tabs wont "flicker" when creating windows
342
if (decorations.tab && fluxbox->useTabs())
343
tab = new Tab(this, 0, 0);
346
XRaiseWindow(display, frame.plate);
347
XMapSubwindows(display, frame.plate);
348
if (decorations.titlebar)
349
XMapSubwindows(display, frame.title);
351
XMapSubwindows(display, frame.window);
353
if (decorations.menu)
354
windowmenu = new Windowmenu(this);
356
if (workspace_number < 0 || workspace_number >= screen->getCount())
357
screen->getCurrentWorkspace()->addWindow(this, place_window);
359
screen->getWorkspace(workspace_number)->addWindow(this, place_window);
361
configure(frame.x, frame.y, frame.width, frame.height);
368
if (maximized && functions.maximize) {
382
fprintf(stderr, "%s(%d): FluxboxWindow(this=%p)\n", __FILE__, __LINE__, this);
389
FluxboxWindow::~FluxboxWindow(void) {
390
if (screen==0) //the window wasn't created
393
Fluxbox *fluxbox = Fluxbox::instance();
396
if (moving || resizing) {
397
screen->hideGeometry();
398
XUngrabPointer(display, CurrentTime);
401
if (workspace_number != -1 && window_number != -1)
402
screen->getWorkspace(workspace_number)->removeWindow(this);
404
screen->removeIcon(this);
407
if (timer->isTiming()) timer->stop();
416
delete [] client.title;
418
if (client.icon_title)
419
delete [] client.icon_title;
425
if (client.mwm_hint!=0)
426
XFree(client.mwm_hint);
428
if (client.blackbox_hint!=0)
429
XFree(client.blackbox_hint);
431
//TODO: Move this to Workspace::removeWindow
432
if (client.transient_for!=0)
433
fluxbox->setFocusedWindow(client.transient_for);
435
if (client.window_group)
436
fluxbox->removeGroupSearch(client.window_group);
438
if (transient && client.transient_for)
439
client.transient_for->client.transient = client.transient;
440
if (client.transient)
441
client.transient->client.transient_for = client.transient_for;
443
while ( !buttonlist.empty()) { //destroy all buttons on titlebar
444
fluxbox->removeWindowSearch(buttonlist.back().win);
445
XDestroyWindow(display, buttonlist.back().win);
446
buttonlist.pop_back();
451
image_ctrl->removeImage(frame.ftitle);
454
image_ctrl->removeImage(frame.utitle);
457
image_ctrl->removeImage(frame.flabel);
460
image_ctrl->removeImage(frame.ulabel);
462
fluxbox->removeWindowSearch(frame.label);
463
fluxbox->removeWindowSearch(frame.title);
464
XDestroyWindow(display, frame.label);
465
XDestroyWindow(display, frame.title);
470
image_ctrl->removeImage(frame.fhandle);
473
image_ctrl->removeImage(frame.uhandle);
476
image_ctrl->removeImage(frame.fgrip);
479
image_ctrl->removeImage(frame.ugrip);
481
fluxbox->removeWindowSearch(frame.right_grip);
482
fluxbox->removeWindowSearch(frame.left_grip);
483
fluxbox->removeWindowSearch(frame.handle);
485
XDestroyWindow(display, frame.right_grip);
486
XDestroyWindow(display, frame.left_grip);
487
XDestroyWindow(display, frame.handle);
491
image_ctrl->removeImage(frame.fbutton);
494
image_ctrl->removeImage(frame.ubutton);
497
image_ctrl->removeImage(frame.pbutton);
500
if (frame.plate) { //NOTE
501
fluxbox->removeWindowSearch(frame.plate);
502
XDestroyWindow(display, frame.plate);
506
fluxbox->removeWindowSearch(frame.window);
507
XDestroyWindow(display, frame.window);
511
fluxbox->removeWindowSearch(client.window);
512
screen->removeNetizen(client.window);
517
cerr<<__FILE__<<"("<<__LINE__<<"): ~FluxboxWindow(this="<<this<<") done"<<endl;
521
void FluxboxWindow::showError(FluxboxWindow::Error error) {
527
case XGETWINDOWATTRIB:
532
WindowSet, WindowXGetWindowAttributesFail,
536
"FluxboxWindow::FluxboxWindow(): XGetWindowAttributes "
545
WindowSet, WindowCannotFindScreen,
549
"FluxboxWindow::FluxboxWindow(): can't find screen\n"
550
" for root window"));
556
Window FluxboxWindow::createToplevelWindow(
557
int x, int y, unsigned int width,
559
unsigned int borderwidth)
561
XSetWindowAttributes attrib_create;
562
unsigned long create_mask = CWBackPixmap | CWBorderPixel | CWColormap |
563
CWOverrideRedirect | CWEventMask;
565
attrib_create.background_pixmap = None;
566
attrib_create.colormap = screen->getColormap();
567
attrib_create.override_redirect = True;
568
attrib_create.event_mask = ButtonPressMask | ButtonReleaseMask |
569
ButtonMotionMask | EnterWindowMask;
571
return (XCreateWindow(display, screen->getRootWindow(), x, y, width, height,
572
borderwidth, screen->getDepth(), InputOutput,
573
screen->getVisual(), create_mask,
578
Window FluxboxWindow::createChildWindow(Window parent, Cursor cursor) {
579
XSetWindowAttributes attrib_create;
580
unsigned long create_mask = CWBackPixmap | CWBorderPixel | CWEventMask;
582
attrib_create.background_pixmap = None;
583
attrib_create.event_mask = ButtonPressMask | ButtonReleaseMask |
584
ButtonMotionMask | ExposureMask |
585
EnterWindowMask | LeaveWindowMask;
588
create_mask |= CWCursor;
589
attrib_create.cursor = cursor;
592
return (XCreateWindow(display, parent, 0, 0, 1, 1, 0,
593
screen->getDepth(), InputOutput, screen->getVisual(),
594
create_mask, &attrib_create));
598
void FluxboxWindow::associateClientWindow(void) {
599
XSetWindowBorderWidth(display, client.window, 0);
603
XChangeSaveSet(display, client.window, SetModeInsert);
604
XSetWindowAttributes attrib_set;
606
XSelectInput(display, frame.plate, NoEventMask);
607
XReparentWindow(display, client.window, frame.plate, 0, 0);
608
XSelectInput(display, frame.plate, SubstructureRedirectMask);
612
attrib_set.event_mask =
613
PropertyChangeMask | StructureNotifyMask | FocusChangeMask;
614
attrib_set.do_not_propagate_mask =
615
ButtonPressMask | ButtonReleaseMask | ButtonMotionMask;
617
XChangeWindowAttributes(display, client.window, CWEventMask|CWDontPropagate,
621
if (Fluxbox::instance()->hasShapeExtensions()) {
622
XShapeSelectInput(display, client.window, ShapeNotifyMask);
627
XShapeQueryExtents(display, client.window, &frame.shaped, &foo, &foo,
628
&ufoo, &ufoo, &foo, &foo, &foo, &ufoo, &ufoo);
631
XShapeCombineShape(display, frame.window, ShapeBounding,
632
frame.mwm_border_w, frame.y_border +
633
frame.mwm_border_w, client.window,
634
ShapeBounding, ShapeSet);
638
xrect[0].x = xrect[0].y = 0;
639
xrect[0].width = frame.width;
640
xrect[0].height = frame.y_border;
642
if (decorations.handle) {
644
xrect[1].y = frame.y_handle;
645
xrect[1].width = frame.width;
646
xrect[1].height = frame.handle_h + screen->getBorderWidth();
650
XShapeCombineRectangles(display, frame.window, ShapeBounding, 0, 0,
651
xrect, num, ShapeUnion, Unsorted);
656
if (decorations.iconify)
657
createButton(Fluxbox::MINIMIZE, FluxboxWindow::iconifyPressed_cb,
658
FluxboxWindow::iconifyButton_cb, FluxboxWindow::iconifyDraw_cb);
659
if (decorations.maximize)
660
createButton(Fluxbox::MAXIMIZE, FluxboxWindow::maximizePressed_cb,
661
FluxboxWindow::maximizeButton_cb, FluxboxWindow::maximizeDraw_cb);
662
if (decorations.close)
663
createButton(Fluxbox::CLOSE, FluxboxWindow::closePressed_cb,
664
FluxboxWindow::closeButton_cb, FluxboxWindow::closeDraw_cb);
665
if (decorations.sticky)
666
createButton(Fluxbox::STICK, FluxboxWindow::stickyPressed_cb,
667
FluxboxWindow::stickyButton_cb, FluxboxWindow::stickyDraw_cb);
669
if (decorations.menu)//TODO
670
createButton(Fluxbox::MENU, 0, 0, 0);
672
if (decorations.shade)
673
createButton(Fluxbox::SHADE, 0, FluxboxWindow::shadeButton_cb, FluxboxWindow::shadeDraw_cb);
676
for (unsigned int i=0; i<buttonlist.size(); i++)
677
XSetWindowBackgroundPixmap(display, buttonlist[i].win, frame.ubutton);
680
for (unsigned int i=0; i<buttonlist.size(); i++)
681
XSetWindowBackground(display, buttonlist[i].win, frame.ubutton_pixel);
686
void FluxboxWindow::decorate(void) {
691
Pixmap tmp = frame.fbutton;
692
BTexture *texture = &(screen->getWindowStyle()->b_focus);
693
if (texture->getTexture() == (BImage::FLAT | BImage::SOLID)) {
694
frame.fbutton = None;
695
frame.fbutton_pixel = texture->getColor()->getPixel();
698
image_ctrl->renderImage(frame.button_w, frame.button_h, texture);
699
if (tmp) image_ctrl->removeImage(tmp);
702
texture = &(screen->getWindowStyle()->b_unfocus);
703
if (texture->getTexture() == (BImage::FLAT | BImage::SOLID)) {
704
frame.ubutton = None;
705
frame.ubutton_pixel = texture->getColor()->getPixel();
708
image_ctrl->renderImage(frame.button_w, frame.button_h, texture);
709
if (tmp) image_ctrl->removeImage(tmp);
712
texture = &(screen->getWindowStyle()->b_pressed);
713
if (texture->getTexture() == (BImage::FLAT | BImage::SOLID)) {
714
frame.pbutton = None;
715
frame.pbutton_pixel = texture->getColor()->getPixel();
718
image_ctrl->renderImage(frame.button_w, frame.button_h, texture);
719
if (tmp) image_ctrl->removeImage(tmp);
721
if (decorations.titlebar) {
723
texture = &(screen->getWindowStyle()->t_focus);
724
if (texture->getTexture() == (BImage::FLAT | BImage::SOLID)) {
726
frame.ftitle_pixel = texture->getColor()->getPixel();
729
image_ctrl->renderImage(frame.width, frame.title_h, texture);
732
image_ctrl->removeImage(tmp);
735
texture = &(screen->getWindowStyle()->t_unfocus);
736
if (texture->getTexture() == (BImage::FLAT | BImage::SOLID)) {
738
frame.utitle_pixel = texture->getColor()->getPixel();
741
image_ctrl->renderImage(frame.width, frame.title_h, texture);
742
if (tmp) image_ctrl->removeImage(tmp);
744
XSetWindowBorder(display, frame.title,
745
screen->getBorderColor()->getPixel());
751
if (decorations.border) {
752
frame.fborder_pixel = screen->getWindowStyle()->f_focus.getPixel();
753
frame.uborder_pixel = screen->getWindowStyle()->f_unfocus.getPixel();
756
if (decorations.handle) {
758
texture = &(screen->getWindowStyle()->h_focus);
759
if (texture->getTexture() == (BImage::FLAT | BImage::SOLID)) {
760
frame.fhandle = None;
761
frame.fhandle_pixel = texture->getColor()->getPixel();
764
image_ctrl->renderImage(frame.width, frame.handle_h, texture);
765
if (tmp) image_ctrl->removeImage(tmp);
768
texture = &(screen->getWindowStyle()->h_unfocus);
769
if (texture->getTexture() == (BImage::FLAT | BImage::SOLID)) {
770
frame.uhandle = None;
771
frame.uhandle_pixel = texture->getColor()->getPixel();
774
image_ctrl->renderImage(frame.width, frame.handle_h, texture);
776
image_ctrl->removeImage(tmp);
779
texture = &(screen->getWindowStyle()->g_focus);
780
if (texture->getTexture() == (BImage::FLAT | BImage::SOLID)) {
782
frame.fgrip_pixel = texture->getColor()->getPixel();
785
image_ctrl->renderImage(frame.grip_w, frame.grip_h, texture);
787
image_ctrl->removeImage(tmp);
790
texture = &(screen->getWindowStyle()->g_unfocus);
791
if (texture->getTexture() == (BImage::FLAT | BImage::SOLID)) {
793
frame.ugrip_pixel = texture->getColor()->getPixel();
796
image_ctrl->renderImage(frame.grip_w, frame.grip_h, texture);
797
if (tmp) image_ctrl->removeImage(tmp);
799
XSetWindowBorder(display, frame.handle,
800
screen->getBorderColor()->getPixel());
801
XSetWindowBorder(display, frame.left_grip,
802
screen->getBorderColor()->getPixel());
803
XSetWindowBorder(display, frame.right_grip,
804
screen->getBorderColor()->getPixel());
807
XSetWindowBorder(display, frame.window,
808
screen->getBorderColor()->getPixel());
812
void FluxboxWindow::decorateLabel(void) {
813
Pixmap tmp = frame.flabel;
814
BTexture *texture = &(screen->getWindowStyle()->l_focus);
815
if (texture->getTexture() == (BImage::FLAT | BImage::SOLID)) {
817
frame.flabel_pixel = texture->getColor()->getPixel();
819
frame.flabel = image_ctrl->renderImage(frame.label_w, frame.label_h, texture);
821
if (tmp) image_ctrl->removeImage(tmp);
824
texture = &(screen->getWindowStyle()->l_unfocus);
825
if (texture->getTexture() == (BImage::FLAT | BImage::SOLID)) {
827
frame.ulabel_pixel = texture->getColor()->getPixel();
829
frame.ulabel = image_ctrl->renderImage(frame.label_w, frame.label_h, texture);
831
if (tmp) image_ctrl->removeImage(tmp);
834
void FluxboxWindow::grabButtons() {
835
Fluxbox *fluxbox = Fluxbox::instance();
837
XGrabButton(display, Button1, AnyModifier,
838
frame.plate, True, ButtonPressMask,
839
GrabModeSync, GrabModeSync, None, None);
840
XUngrabButton(display, Button1, Mod1Mask|Mod2Mask|Mod3Mask, frame.plate);
843
XGrabButton(display, Button1, Mod1Mask, frame.window, True,
844
ButtonReleaseMask | ButtonMotionMask, GrabModeAsync,
845
GrabModeAsync, None, fluxbox->getMoveCursor());
847
//----grab with "all" modifiers
848
grabButton(display, Button1, frame.window, fluxbox->getMoveCursor());
850
XGrabButton(display, Button2, Mod1Mask, frame.window, True,
851
ButtonReleaseMask, GrabModeAsync, GrabModeAsync, None, None);
853
XGrabButton(display, Button3, Mod1Mask, frame.window, True,
854
ButtonReleaseMask | ButtonMotionMask, GrabModeAsync,
855
GrabModeAsync, None, fluxbox->getLowerRightAngleCursor());
857
//---grab with "all" modifiers
858
grabButton(display, Button3, frame.window, fluxbox->getLowerRightAngleCursor());
861
void FluxboxWindow::createButton(int type, ButtonEventProc pressed, ButtonEventProc released, ButtonDrawProc draw) {
863
b.win = createChildWindow(frame.title);
864
Fluxbox::instance()->saveWindowSearch(b.win, this);
869
b.released = released;
870
buttonlist.push_back(b);
875
void FluxboxWindow::updateGnomeAtoms() {
876
updateGnomeWorkspaceAtom();
877
updateGnomeStateAtom();
878
updateGnomeLayerAtom();
879
updateGnomeWorkspaceAtom();
882
void FluxboxWindow::updateGnomeStateAtom() {
883
BaseDisplay *bd = screen->getBaseDisplay();
884
int val = getGnomeWindowState();
885
XChangeProperty(display, client.window, bd->getGnomeStateAtom(),
886
XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&val, 1);
889
void FluxboxWindow::updateGnomeLayerAtom() {
890
BaseDisplay *bd = screen->getBaseDisplay();
891
int val = getGnomeLayer();
892
XChangeProperty(display, client.window, bd->getGnomeLayerAtom(),
893
XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&val, 1);
896
void FluxboxWindow::updateGnomeWorkspaceAtom() {
897
BaseDisplay *bd = screen->getBaseDisplay();
898
int val = workspace_number;
899
XChangeProperty(display, client.window, bd->getGnomeWorkspaceAtom(),
900
XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&val, 1);
904
int FluxboxWindow::getGnomeWindowState() {
907
state |= WIN_STATE_STICKY;
909
state |= WIN_STATE_MINIMIZED;
911
state |= WIN_STATE_SHADED;
913
WIN_STATE_MAXIMIZED_VERT // window in maximized V state
914
WIN_STATE_MAXIMIZED_HORIZ // window in maximized H state
915
WIN_STATE_HIDDEN // not on taskbar but window visible
916
WIN_STATE_HID_WORKSPACE // not on current desktop
917
WIN_STATE_HID_TRANSIENT // owner of transient is hidden
918
WIN_STATE_FIXED_POSITION // window is fixed in position even
919
WIN_STATE_ARRANGE_IGNORE // ignore for auto arranging
925
int FluxboxWindow::getGnomeLayer() {
928
return WIN_LAYER_NORMAL;
930
return WIN_LAYER_BELOW;
932
return WIN_LAYER_ONTOP;
934
return WIN_LAYER_BELOW;
938
return WIN_LAYER_NORMAL;
941
bool FluxboxWindow::handleGnomePropertyNotify(Atom atom) {
942
BaseDisplay *bd = screen->getBaseDisplay();
944
if (atom == bd->getGnomeStateAtom()) {
946
cerr<<__FILE__<<"("<<__LINE__<<"): gnome state"<<endl;
948
loadGnomeStateAtom();
949
} else if (atom == bd->getGnomeWorkspaceAtom()) {
951
cerr<<__FILE__<<"("<<__LINE__<<"): gnome workspace"<<endl;
953
} else if (atom == bd->getGnomeHintsAtom()) {
955
cerr<<__FILE__<<"("<<__LINE__<<"): gnome hints"<<endl;
957
loadGnomeHintsAtom();
958
} else if (atom == bd->getGnomeLayerAtom()){
960
cerr<<__FILE__<<"("<<__LINE__<<"): gnome layer"<<endl;
962
loadGnomeLayerAtom();
970
void FluxboxWindow::setGnomeState(int state) {
972
cerr<<"state=0x"<<hex<<state<<dec<<endl;
975
if ( state & WIN_STATE_STICKY) {
976
cerr<<"Sticky"<<endl;
979
} else if (isStuck())
982
if (state & WIN_STATE_MINIMIZED) {
983
cerr<<"Minimized"<<endl;
986
} else if (isIconic())
987
deiconify(true, true);
989
if (state & WIN_STATE_MAXIMIZED_VERT)
990
cerr<<"Maximize Vert"<<endl;
991
if (state & WIN_STATE_MAXIMIZED_HORIZ)
992
cerr<<"Maximize Horiz"<<endl;
993
if (state & WIN_STATE_HIDDEN)
994
cerr<<"Hidden"<<endl;
995
if (state & WIN_STATE_SHADED) {
996
cerr<<"Shaded"<<endl;
997
if (!isShaded()) shade();
998
} else if (isShaded())
1001
if (state & WIN_STATE_HID_WORKSPACE)
1002
cerr<<"HID Workspace"<<endl;
1003
if (state & WIN_STATE_HID_TRANSIENT)
1004
cerr<<"HID Transient"<<endl;
1005
if (state & WIN_STATE_FIXED_POSITION)
1006
cerr<<"Fixed Position"<<endl;
1007
if (state & WIN_STATE_ARRANGE_IGNORE)
1008
cerr<<"Arrange Ignore"<<endl;
1012
void FluxboxWindow::setGnomeLayer(int layer) {
1014
case WIN_LAYER_DESKTOP:
1015
m_layer = LAYER_BOTTOM;
1017
case WIN_LAYER_BELOW:
1018
m_layer = LAYER_BELOW;
1020
case WIN_LAYER_NORMAL:
1021
m_layer = LAYER_NORMAL;
1023
case WIN_LAYER_ONTOP:
1024
case WIN_LAYER_DOCK:
1025
case WIN_LAYER_ABOVE_DOCK:
1026
case WIN_LAYER_MENU:
1027
m_layer = LAYER_TOP;
1030
m_layer = LAYER_NORMAL;
1034
//------------ loadGnomeAtoms ------------
1035
// Loads the values from the atoms
1036
//----------------------------------------
1037
void FluxboxWindow::loadGnomeAtoms() {
1038
loadGnomeStateAtom();
1039
loadGnomeHintsAtom();
1040
loadGnomeLayerAtom();
1042
//----------- loadGnomeStateAtom -------
1043
// Gets gnome state from the atom
1044
//----------------------------------------
1045
void FluxboxWindow::loadGnomeStateAtom() {
1048
unsigned long nitems, bytes_after;
1049
long flags, *data = 0;
1050
BaseDisplay *bd = screen->getBaseDisplay();
1051
if (XGetWindowProperty (bd->getXDisplay(), getClientWindow(),
1052
bd->getGnomeStateAtom(), 0, 1, False, XA_CARDINAL,
1053
&ret_type, &fmt, &nitems, &bytes_after,
1054
(unsigned char **) &data) == Success && data) {
1056
setGnomeState(flags);
1061
//--------- loadGnomeHintsAtom ---------
1062
// Gets the gnome hint from the atom
1063
//----------------------------------------
1064
void FluxboxWindow::loadGnomeHintsAtom() {
1067
unsigned long nitems, bytes_after;
1069
BaseDisplay *bd = screen->getBaseDisplay();
1070
if (XGetWindowProperty (bd->getXDisplay(), getClientWindow(),
1071
bd->getGnomeHintsAtom(), 0, 1, False, XA_CARDINAL,
1072
&ret_type, &fmt, &nitems, &bytes_after,
1073
(unsigned char **) &data) == Success && data) {
1074
gnome_hints = static_cast<int>(*data);
1076
cerr<<__FILE__<<"("<<__LINE__<<"): gnome hints:0x"<<hex<<gnome_hints<<dec<<endl;
1081
//---------- loadGnomeLayerAtom ------------
1082
// Gets the gnome layer from the atom
1083
//------------------------------------------
1084
void FluxboxWindow::loadGnomeLayerAtom() {
1087
unsigned long nitems, bytes_after;
1089
BaseDisplay *bd = screen->getBaseDisplay();
1090
if (XGetWindowProperty (bd->getXDisplay(), getClientWindow(),
1091
bd->getGnomeLayerAtom(), 0, 1, False, XA_CARDINAL,
1092
&ret_type, &fmt, &nitems, &bytes_after,
1093
(unsigned char **) &data) == Success && data) {
1094
setGnomeLayer(static_cast<int>(*data));
1096
cerr<<__FILE__<<"("<<__LINE__<<"): gnome hints:0x"<<hex<<*data<<dec<<endl;
1106
void FluxboxWindow::updateNETWMAtoms() {
1110
int FluxboxWindow::getNETWMWindowState() {
1114
void FluxboxWindow::loadNETWMWorkspaceAtom() {
1120
Window FluxboxWindow::findTitleButton(int type) {
1121
for (unsigned int i=0; i<buttonlist.size(); i++) {
1122
if (buttonlist[i].type == type)
1123
return buttonlist[i].win;
1127
void FluxboxWindow::stickyButton_cb(FluxboxWindow *t, XButtonEvent *be) {
1129
FluxboxWindow::stickyDraw_cb(t, be->window, false);
1132
void FluxboxWindow::stickyPressed_cb(FluxboxWindow *t, XButtonEvent *be) {
1133
FluxboxWindow::stickyDraw_cb(t, be->window, true);
1136
void FluxboxWindow::iconifyButton_cb(FluxboxWindow *t, XButtonEvent *be) {
1138
FluxboxWindow::iconifyDraw_cb(t, be->window, false);
1141
void FluxboxWindow::iconifyPressed_cb(FluxboxWindow *t, XButtonEvent *be) {
1142
t->screen->getWorkspace(t->workspace_number)->lowerWindow(t);
1143
FluxboxWindow::iconifyDraw_cb(t, be->window, true);
1146
void FluxboxWindow::maximizeButton_cb(FluxboxWindow *t, XButtonEvent *be) {
1147
FluxboxWindow::maximizeDraw_cb(t, be->window, false);
1148
t->maximize(be->button);
1151
void FluxboxWindow::maximizePressed_cb(FluxboxWindow *t, XButtonEvent *be) {
1152
FluxboxWindow::maximizeDraw_cb(t, be->window, true);
1155
void FluxboxWindow::closeButton_cb(FluxboxWindow *t, XButtonEvent *be) {
1157
FluxboxWindow::closeDraw_cb(t, be->window, false);
1160
void FluxboxWindow::closePressed_cb(FluxboxWindow *t, XButtonEvent *be) {
1161
FluxboxWindow::closeDraw_cb(t, be->window, true);
1164
void FluxboxWindow::shadeButton_cb(FluxboxWindow *t, XButtonEvent *be) {
1165
FluxboxWindow::shadeDraw_cb(t, be->window, false);
1171
void FluxboxWindow::stickyDraw_cb(FluxboxWindow *t, Window w, bool pressed) {
1172
t->drawButtonBase(w, pressed);
1174
XFillRectangle(t->display, w,
1175
((t->focused) ? t->screen->getWindowStyle()->b_pic_focus_gc :
1176
t->screen->getWindowStyle()->b_pic_unfocus_gc),
1177
t->frame.button_w/2-t->frame.button_w/4, t->frame.button_h/2-t->frame.button_h/4,
1178
t->frame.button_w/2, t->frame.button_h/2);
1180
XFillRectangle(t->display, w,
1181
((t->focused) ? t->screen->getWindowStyle()->b_pic_focus_gc :
1182
t->screen->getWindowStyle()->b_pic_unfocus_gc),
1183
t->frame.button_w/2, t->frame.button_h/2,
1184
t->frame.button_w/5, t->frame.button_h/5);
1188
void FluxboxWindow::iconifyDraw_cb(FluxboxWindow *t, Window w, bool pressed) {
1189
t->drawButtonBase(w, pressed);
1190
XDrawRectangle(t->display, w,
1191
((t->focused) ? t->screen->getWindowStyle()->b_pic_focus_gc :
1192
t->screen->getWindowStyle()->b_pic_unfocus_gc),
1193
2, t->frame.button_h - 5, t->frame.button_w - 5, 2);
1196
void FluxboxWindow::maximizeDraw_cb(FluxboxWindow *t, Window w, bool pressed) {
1197
t->drawButtonBase(w, pressed);
1198
XDrawRectangle(t->display, w,
1199
((t->focused) ? t->screen->getWindowStyle()->b_pic_focus_gc :
1200
t->screen->getWindowStyle()->b_pic_unfocus_gc),
1201
2, 2, t->frame.button_w - 5, t->frame.button_h - 5);
1202
XDrawLine(t->display, w,
1203
((t->focused) ? t->screen->getWindowStyle()->b_pic_focus_gc :
1204
t->screen->getWindowStyle()->b_pic_unfocus_gc),
1205
2, 3, t->frame.button_w - 3, 3);
1208
void FluxboxWindow::closeDraw_cb(FluxboxWindow *t, Window w, bool pressed) {
1209
t->drawButtonBase(w, pressed);
1210
XDrawLine(t->display, w,
1211
((t->focused) ? t->screen->getWindowStyle()->b_pic_focus_gc :
1212
t->screen->getWindowStyle()->b_pic_unfocus_gc), 2, 2,
1213
t->frame.button_w - 3, t->frame.button_h - 3);
1214
XDrawLine(t->display, w,
1215
((t->focused) ? t->screen->getWindowStyle()->b_pic_focus_gc :
1216
t->screen->getWindowStyle()->b_pic_unfocus_gc), 2,
1217
t->frame.button_h - 3,
1218
t->frame.button_w - 3, 2);
1221
void FluxboxWindow::shadeDraw_cb(FluxboxWindow *t, Window w, bool pressed) {
1222
t->drawButtonBase(w, pressed);
1225
void FluxboxWindow::grabButton(Display *display, unsigned int button,
1226
Window window, Cursor cursor) {
1229
XGrabButton(display, button, Mod1Mask|Mod2Mask, window, True,
1230
ButtonReleaseMask | ButtonMotionMask, GrabModeAsync,
1231
GrabModeAsync, None, cursor);
1233
XGrabButton(display, button, Mod1Mask|Mod5Mask, window, True,
1234
ButtonReleaseMask | ButtonMotionMask, GrabModeAsync,
1235
GrabModeAsync, None, cursor);
1238
XGrabButton(display, button, Mod1Mask|LockMask, window, True,
1239
ButtonReleaseMask | ButtonMotionMask, GrabModeAsync,
1240
GrabModeAsync, None, cursor);
1243
XGrabButton(display, Button1, Mod1Mask|LockMask|Mod2Mask, window, True,
1244
ButtonReleaseMask | ButtonMotionMask, GrabModeAsync,
1245
GrabModeAsync, None, cursor);
1247
//capslock+scrolllock
1248
XGrabButton(display, button, Mod1Mask|LockMask|Mod5Mask, window, True,
1249
ButtonReleaseMask | ButtonMotionMask, GrabModeAsync,
1250
GrabModeAsync, None, cursor);
1252
//capslock+numlock+scrolllock
1253
XGrabButton(display, button, Mod1Mask|LockMask|Mod2Mask|Mod5Mask, window, True,
1254
ButtonReleaseMask | ButtonMotionMask, GrabModeAsync,
1255
GrabModeAsync, None, cursor);
1257
//numlock+scrollLock
1258
XGrabButton(display, button, Mod1Mask|Mod2Mask|Mod5Mask, window, True,
1259
ButtonReleaseMask | ButtonMotionMask, GrabModeAsync,
1260
GrabModeAsync, None, cursor);
1264
void FluxboxWindow::drawButtonBase(Window w, bool pressed) {
1268
XSetWindowBackgroundPixmap(display, w, frame.fbutton);
1270
XSetWindowBackground(display, w, frame.fbutton_pixel);
1273
XSetWindowBackgroundPixmap(display, w, frame.ubutton);
1275
XSetWindowBackground(display, w, frame.ubutton_pixel);
1279
XSetWindowBackgroundPixmap(display, w, frame.pbutton);
1281
XSetWindowBackground(display, w, frame.pbutton_pixel);
1283
XClearWindow(display, w);
1287
void FluxboxWindow::positionButtons(bool redecorate_label) {
1288
unsigned int bw = frame.button_w + frame.bevel_w + 1,
1289
by = frame.bevel_w + 1, lx = by, lw = frame.width - by;
1290
Fluxbox *fluxbox = Fluxbox::instance();
1291
vector<Fluxbox::Titlebar> left = fluxbox->getTitlebarLeft();
1292
vector<Fluxbox::Titlebar> right = fluxbox->getTitlebarRight();
1295
for (unsigned int i=0; i<left.size(); i++) {
1296
Window w = findTitleButton(left[i]); //get Window of button
1298
XMoveResizeWindow(display, w, lx, by,
1299
frame.button_w, frame.button_h);
1300
XMapWindow(display, w);
1301
XClearWindow(display, w);
1307
int bx = frame.width - bw;
1309
//right side buttons
1310
for (int i=right.size()-1; i>=0; i--) {
1311
Window w = findTitleButton(right[i]); //get window of button
1313
XMoveResizeWindow(display, w, bx, by,
1314
frame.button_w, frame.button_h);
1315
XMapWindow(display, w);
1316
XClearWindow(display, w);
1323
frame.label_w = lw - by;
1324
XMoveResizeWindow(display, frame.label, lx, frame.bevel_w,
1325
frame.label_w, frame.label_h);
1326
if (redecorate_label)
1337
void FluxboxWindow::reconfigure(void) {
1340
if (Fluxbox::instance()->useTabs()) {
1341
//no tab and we allowed to use tab? then create it
1342
if (!tab && decorations.tab) {
1343
tab = new Tab(this, 0, 0);
1344
if (current_state == IconicState)
1346
else if (current_state == WithdrawnState)
1350
if (tab) { //got a tab? then destroy it
1356
client.x = frame.x + frame.mwm_border_w + screen->getBorderWidth();
1357
client.y = frame.y + frame.y_border + frame.mwm_border_w +
1358
screen->getBorderWidth();
1361
if (I18n::instance()->multibyte()) {
1362
XRectangle ink, logical;
1363
XmbTextExtents(screen->getWindowStyle()->font.set,
1364
client.title, client.title_len, &ink, &logical);
1365
client.title_text_w = logical.width;
1367
client.title_text_w = XTextWidth(screen->getWindowStyle()->font.fontstruct,
1368
client.title, client.title_len);
1371
client.title_text_w += (frame.bevel_w * 4);
1379
XClearWindow(display, frame.window);
1380
setFocusFlag(focused);
1382
configure(frame.x, frame.y, frame.width, frame.height);
1384
if (! (screen->isSloppyFocus() || screen->isSemiSloppyFocus())) {
1385
XGrabButton(display, Button1, AnyModifier, frame.plate, True, ButtonPressMask,
1386
GrabModeSync, GrabModeSync, None, None);
1387
XUngrabButton(display, Button1, Mod1Mask|Mod2Mask|Mod3Mask, frame.plate);
1389
XUngrabButton(display, Button1, AnyModifier, frame.plate);
1392
windowmenu->move(windowmenu->getX(), frame.y + frame.title_h);
1393
windowmenu->reconfigure();
1400
void FluxboxWindow::positionWindows(void) {
1401
XResizeWindow(display, frame.window, frame.width,
1402
((shaded) ? frame.title_h : frame.height));
1403
XSetWindowBorderWidth(display, frame.window, screen->getBorderWidth());
1404
XSetWindowBorderWidth(display, frame.plate, screen->getFrameWidth() *
1405
decorations.border);
1406
XMoveResizeWindow(display, frame.plate, 0, frame.y_border,
1407
client.width, client.height);
1408
XMoveResizeWindow(display, client.window, 0, 0, client.width, client.height);
1410
if (decorations.titlebar) {
1411
XSetWindowBorderWidth(display, frame.title, screen->getBorderWidth());
1412
XMoveResizeWindow(display, frame.title, -screen->getBorderWidth(),
1413
-screen->getBorderWidth(), frame.width, frame.title_h);
1416
} else if (frame.title)
1417
XUnmapWindow(display, frame.title);
1419
if (decorations.handle) {
1420
XSetWindowBorderWidth(display, frame.handle, screen->getBorderWidth());
1421
XSetWindowBorderWidth(display, frame.left_grip, screen->getBorderWidth());
1422
XSetWindowBorderWidth(display, frame.right_grip, screen->getBorderWidth());
1424
XMoveResizeWindow(display, frame.handle, -screen->getBorderWidth(),
1425
frame.y_handle - screen->getBorderWidth(),
1426
frame.width, frame.handle_h);
1427
XMoveResizeWindow(display, frame.left_grip, -screen->getBorderWidth(),
1428
-screen->getBorderWidth(), frame.grip_w, frame.grip_h);
1429
XMoveResizeWindow(display, frame.right_grip,
1430
frame.width - frame.grip_w - screen->getBorderWidth(),
1431
-screen->getBorderWidth(), frame.grip_w, frame.grip_h);
1432
XMapSubwindows(display, frame.handle);
1433
} else if (frame.handle)
1434
XUnmapWindow(display, frame.handle);
1440
void FluxboxWindow::getWMName(void) {
1442
delete [] client.title;
1446
XTextProperty text_prop;
1449
I18n *i18n = I18n::instance();
1451
if (XGetWMName(display, client.window, &text_prop)) {
1452
if (text_prop.value && text_prop.nitems > 0) {
1453
if (text_prop.encoding != XA_STRING) {
1455
text_prop.nitems = strlen((char *) text_prop.value);
1457
if ((XmbTextPropertyToTextList(display, &text_prop,
1458
&list, &num) == Success) &&
1459
(num > 0) && *list) {
1460
client.title = StringUtil::strdup(*list);
1461
XFreeStringList(list);
1463
client.title = StringUtil::strdup((char *) text_prop.value);
1466
client.title = StringUtil::strdup((char *) text_prop.value);
1468
XFree((char *) text_prop.value);
1470
client.title = StringUtil::strdup(i18n->getMessage(
1472
WindowSet, WindowUnnamed,
1478
client.title = StringUtil::strdup(i18n->getMessage(
1480
WindowSet, WindowUnnamed,
1487
client.title_len = strlen(client.title);
1489
if (i18n->multibyte()) {
1490
XRectangle ink, logical;
1491
XmbTextExtents(screen->getWindowStyle()->font.set,
1492
client.title, client.title_len, &ink, &logical);
1493
client.title_text_w = logical.width;
1495
client.title_len = strlen(client.title);
1496
client.title_text_w = XTextWidth(screen->getWindowStyle()->font.fontstruct,
1497
client.title, client.title_len);
1500
client.title_text_w += (frame.bevel_w * 4);
1504
void FluxboxWindow::getWMIconName(void) {
1505
if (client.icon_title) {
1506
delete [] client.icon_title;
1507
client.icon_title = (char *) 0;
1510
XTextProperty text_prop;
1514
if (XGetWMIconName(display, client.window, &text_prop)) {
1515
if (text_prop.value && text_prop.nitems > 0) {
1516
if (text_prop.encoding != XA_STRING) {
1517
text_prop.nitems = strlen((char *) text_prop.value);
1519
if ((XmbTextPropertyToTextList(display, &text_prop,
1520
&list, &num) == Success) &&
1521
(num > 0) && *list) {
1522
client.icon_title = StringUtil::strdup(*list);
1523
XFreeStringList(list);
1525
client.icon_title = StringUtil::strdup((char *) text_prop.value);
1527
client.icon_title = StringUtil::strdup((char *) text_prop.value);
1529
XFree((char *) text_prop.value);
1531
client.icon_title = StringUtil::strdup(client.title);
1533
client.icon_title = StringUtil::strdup(client.title);
1537
void FluxboxWindow::getWMProtocols(void) {
1540
Fluxbox *fluxbox = Fluxbox::instance();
1542
if (XGetWMProtocols(display, client.window, &proto, &num_return)) {
1543
for (int i = 0; i < num_return; ++i) {
1544
if (proto[i] == fluxbox->getWMDeleteAtom())
1545
functions.close = decorations.close = true;
1546
else if (proto[i] == fluxbox->getWMTakeFocusAtom())
1547
send_focus_message = true;
1548
else if (proto[i] == fluxbox->getFluxboxStructureMessagesAtom())
1549
screen->addNetizen(new Netizen(screen, client.window));
1557
void FluxboxWindow::getWMHints(void) {
1558
XWMHints *wmhint = XGetWMHints(display, client.window);
1562
focus_mode = F_PASSIVE;
1563
client.window_group = None;
1564
client.initial_state = NormalState;
1566
client.wm_hint_flags = wmhint->flags;
1567
if (wmhint->flags & InputHint) {
1568
if (wmhint->input == true) {
1569
if (send_focus_message)
1570
focus_mode = F_LOCALLYACTIVE;
1572
focus_mode = F_PASSIVE;
1574
if (send_focus_message)
1575
focus_mode = F_GLOBALLYACTIVE;
1577
focus_mode = F_NOINPUT;
1580
focus_mode = F_PASSIVE;
1582
if (wmhint->flags & StateHint)
1583
client.initial_state = wmhint->initial_state;
1585
client.initial_state = NormalState;
1587
if (wmhint->flags & WindowGroupHint) {
1588
if (! client.window_group) {
1589
client.window_group = wmhint->window_group;
1590
Fluxbox::instance()->saveGroupSearch(client.window_group, this);
1593
client.window_group = None;
1600
void FluxboxWindow::getWMNormalHints(void) {
1602
XSizeHints sizehint;
1603
if (! XGetWMNormalHints(display, client.window, &sizehint, &icccm_mask)) {
1604
client.min_width = client.min_height =
1605
client.base_width = client.base_height =
1606
client.width_inc = client.height_inc = 1;
1607
client.max_width = screen->getWidth();
1608
client.max_height = screen->getHeight();
1609
client.min_aspect_x = client.min_aspect_y =
1610
client.max_aspect_x = client.max_aspect_y = 1;
1611
client.win_gravity = NorthWestGravity;
1613
client.normal_hint_flags = sizehint.flags;
1615
if (sizehint.flags & PMinSize) {
1616
client.min_width = sizehint.min_width;
1617
client.min_height = sizehint.min_height;
1619
client.min_width = client.min_height = 1;
1621
if (sizehint.flags & PMaxSize) {
1622
client.max_width = sizehint.max_width;
1623
client.max_height = sizehint.max_height;
1625
client.max_width = screen->getWidth();
1626
client.max_height = screen->getHeight();
1629
if (sizehint.flags & PResizeInc) {
1630
client.width_inc = sizehint.width_inc;
1631
client.height_inc = sizehint.height_inc;
1633
client.width_inc = client.height_inc = 1;
1635
if (sizehint.flags & PAspect) {
1636
client.min_aspect_x = sizehint.min_aspect.x;
1637
client.min_aspect_y = sizehint.min_aspect.y;
1638
client.max_aspect_x = sizehint.max_aspect.x;
1639
client.max_aspect_y = sizehint.max_aspect.y;
1641
client.min_aspect_x = client.min_aspect_y =
1642
client.max_aspect_x = client.max_aspect_y = 1;
1644
if (sizehint.flags & PBaseSize) {
1645
client.base_width = sizehint.base_width;
1646
client.base_height = sizehint.base_height;
1648
client.base_width = client.base_height = 0;
1650
if (sizehint.flags & PWinGravity)
1651
client.win_gravity = sizehint.win_gravity;
1653
client.win_gravity = NorthWestGravity;
1658
void FluxboxWindow::getMWMHints(void) {
1661
unsigned long num, len;
1662
Fluxbox *fluxbox = Fluxbox::instance();
1663
if (XGetWindowProperty(display, client.window,
1664
fluxbox->getMotifWMHintsAtom(), 0,
1665
PropMwmHintsElements, false,
1666
fluxbox->getMotifWMHintsAtom(), &atom_return,
1667
&format, &num, &len,
1668
(unsigned char **) &client.mwm_hint) == Success &&
1670
if (num == PropMwmHintsElements) {
1671
if (client.mwm_hint->flags & MwmHintsDecorations)
1672
if (client.mwm_hint->decorations & MwmDecorAll)
1673
decorations.titlebar = decorations.handle = decorations.border =
1674
decorations.iconify = decorations.maximize =
1675
decorations.close = decorations.menu = true;
1677
decorations.titlebar = decorations.handle = decorations.border =
1678
decorations.iconify = decorations.maximize =
1679
decorations.close = decorations.menu = decorations.tab = false;
1681
if (client.mwm_hint->decorations & MwmDecorBorder)
1682
decorations.border = true;
1683
if (client.mwm_hint->decorations & MwmDecorHandle)
1684
decorations.handle = true;
1685
if (client.mwm_hint->decorations & MwmDecorTitle)
1686
decorations.titlebar = decorations.tab = true; //only tab on windows with titlebar
1687
if (client.mwm_hint->decorations & MwmDecorMenu)
1688
decorations.menu = true;
1689
if (client.mwm_hint->decorations & MwmDecorIconify)
1690
decorations.iconify = true;
1691
if (client.mwm_hint->decorations & MwmDecorMaximize)
1692
decorations.maximize = true;
1695
if (client.mwm_hint->flags & MwmHintsFunctions)
1696
if (client.mwm_hint->functions & MwmFuncAll) {
1697
functions.resize = functions.move = functions.iconify =
1698
functions.maximize = functions.close = true;
1700
functions.resize = functions.move = functions.iconify =
1701
functions.maximize = functions.close = false;
1703
if (client.mwm_hint->functions & MwmFuncResize)
1704
functions.resize = true;
1705
if (client.mwm_hint->functions & MwmFuncMove)
1706
functions.move = true;
1707
if (client.mwm_hint->functions & MwmFuncIconify)
1708
functions.iconify = true;
1709
if (client.mwm_hint->functions & MwmFuncMaximize)
1710
functions.maximize = true;
1711
if (client.mwm_hint->functions & MwmFuncClose)
1712
functions.close = true;
1718
void FluxboxWindow::getBlackboxHints(void) {
1721
unsigned long num, len;
1722
Fluxbox *fluxbox = Fluxbox::instance();
1724
if (XGetWindowProperty(display, client.window,
1725
fluxbox->getFluxboxHintsAtom(), 0,
1726
PropBlackboxHintsElements, false,
1727
fluxbox->getFluxboxHintsAtom(), &atom_return,
1728
&format, &num, &len,
1729
(unsigned char **) &client.blackbox_hint) == Success &&
1730
client.blackbox_hint)
1731
if (num == PropBlackboxHintsElements) {
1732
if (client.blackbox_hint->flags & BaseDisplay::ATTRIB_SHADED)
1733
shaded = (client.blackbox_hint->attrib & BaseDisplay::ATTRIB_SHADED);
1735
if ((client.blackbox_hint->flags & BaseDisplay::ATTRIB_MAXHORIZ) &&
1736
(client.blackbox_hint->flags & BaseDisplay::ATTRIB_MAXVERT))
1737
maximized = ((client.blackbox_hint->attrib &
1738
(BaseDisplay::ATTRIB_MAXHORIZ | BaseDisplay::ATTRIB_MAXVERT)) ? 1 : 0);
1739
else if (client.blackbox_hint->flags & BaseDisplay::ATTRIB_MAXVERT)
1740
maximized = ((client.blackbox_hint->attrib & BaseDisplay::ATTRIB_MAXVERT) ? 2 : 0);
1741
else if (client.blackbox_hint->flags & BaseDisplay::ATTRIB_MAXHORIZ)
1742
maximized = ((client.blackbox_hint->attrib & BaseDisplay::ATTRIB_MAXHORIZ) ? 3 : 0);
1744
if (client.blackbox_hint->flags & BaseDisplay::ATTRIB_OMNIPRESENT)
1745
stuck = (client.blackbox_hint->attrib & BaseDisplay::ATTRIB_OMNIPRESENT);
1747
if (client.blackbox_hint->flags & BaseDisplay::ATTRIB_WORKSPACE)
1748
workspace_number = client.blackbox_hint->workspace;
1751
if (client.blackbox_hint->flags & BaseDisplay::ATTRIB_DECORATION) {
1752
switch (client.blackbox_hint->decoration) {
1753
case BaseDisplay::DECOR_NONE:
1754
decorations.titlebar = decorations.border = decorations.handle =
1755
decorations.iconify = decorations.maximize =
1756
decorations.menu = decorations.tab = false; //tab is also a decor
1757
functions.resize = functions.move = functions.iconify =
1758
functions.maximize = false;
1763
case BaseDisplay::DECOR_NORMAL:
1764
decorations.titlebar = decorations.border = decorations.handle =
1765
decorations.iconify = decorations.maximize =
1766
decorations.menu = true;
1767
functions.resize = functions.move = functions.iconify =
1768
functions.maximize = true;
1772
case BaseDisplay::DECOR_TINY:
1773
decorations.titlebar = decorations.iconify = decorations.menu =
1774
functions.move = functions.iconify = true;
1775
decorations.border = decorations.handle = decorations.maximize =
1776
functions.resize = functions.maximize = false;
1780
case BaseDisplay::DECOR_TOOL:
1781
decorations.titlebar = decorations.menu = functions.move = true;
1782
decorations.iconify = decorations.border = decorations.handle =
1783
decorations.maximize = functions.resize = functions.maximize =
1784
functions.iconify = false;
1795
void FluxboxWindow::configure(int dx, int dy,
1796
unsigned int dw, unsigned int dh) {
1797
//we don't want negative size
1801
bool send_event = (frame.x != dx || frame.y != dy);
1803
if ((dw != frame.width) || (dh != frame.height)) {
1804
if ((((signed) frame.width) + dx) < 0) dx = 0;
1805
if ((((signed) frame.height) + dy) < 0) dy = 0;
1815
if (Fluxbox::instance()->hasShapeExtensions() && frame.shaped) {
1816
XShapeCombineShape(display, frame.window, ShapeBounding,
1817
frame.mwm_border_w, frame.y_border +
1818
frame.mwm_border_w, client.window,
1819
ShapeBounding, ShapeSet);
1822
XRectangle xrect[2];
1823
xrect[0].x = xrect[0].y = 0;
1824
xrect[0].width = frame.width;
1825
xrect[0].height = frame.y_border;
1827
if (decorations.handle) {
1829
xrect[1].y = frame.y_handle;
1830
xrect[1].width = frame.width;
1831
xrect[1].height = frame.handle_h + screen->getBorderWidth();
1835
XShapeCombineRectangles(display, frame.window, ShapeBounding, 0, 0,
1836
xrect, num, ShapeUnion, Unsorted);
1840
XMoveResizeWindow(display, frame.window, frame.x, frame.y,
1841
frame.width, frame.height);
1844
setFocusFlag(focused);
1851
XMoveWindow(display, frame.window, frame.x, frame.y);
1852
//move the tab and the chain
1856
if (! moving) send_event = true;
1859
if (send_event && ! moving) {
1860
client.x = dx + frame.mwm_border_w + screen->getBorderWidth();
1861
client.y = dy + frame.y_border + frame.mwm_border_w +
1862
screen->getBorderWidth();
1865
event.type = ConfigureNotify;
1867
event.xconfigure.display = display;
1868
event.xconfigure.event = client.window;
1869
event.xconfigure.window = client.window;
1870
event.xconfigure.x = client.x;
1871
event.xconfigure.y = client.y;
1872
event.xconfigure.width = client.width;
1873
event.xconfigure.height = client.height;
1874
event.xconfigure.border_width = client.old_bw;
1875
event.xconfigure.above = frame.window;
1876
event.xconfigure.override_redirect = false;
1878
XSendEvent(display, client.window, True, NoEventMask, &event);
1880
screen->updateNetizenConfigNotify(&event);
1885
bool FluxboxWindow::setInputFocus(void) {
1887
if (gnome_hints & WIN_HINTS_SKIP_FOCUS)
1890
if (((signed) (frame.x + frame.width)) < 0) {
1891
if (((signed) (frame.y + frame.y_border)) < 0)
1892
configure(screen->getBorderWidth(), screen->getBorderWidth(),
1893
frame.width, frame.height);
1894
else if (frame.y > (signed) screen->getHeight())
1895
configure(screen->getBorderWidth(), screen->getHeight() - frame.height,
1896
frame.width, frame.height);
1898
configure(screen->getBorderWidth(), frame.y + screen->getBorderWidth(),
1899
frame.width, frame.height);
1900
} else if (frame.x > (signed) screen->getWidth()) {
1901
if (((signed) (frame.y + frame.y_border)) < 0)
1902
configure(screen->getWidth() - frame.width, screen->getBorderWidth(),
1903
frame.width, frame.height);
1904
else if (frame.y > (signed) screen->getHeight())
1905
configure(screen->getWidth() - frame.width,
1906
screen->getHeight() - frame.height, frame.width, frame.height);
1908
configure(screen->getWidth() - frame.width,
1909
frame.y + screen->getBorderWidth(), frame.width, frame.height);
1912
Fluxbox *fluxbox = Fluxbox::instance();
1913
BaseDisplay::GrabGuard gg(*fluxbox);
1915
if (! validateClient()) return false;
1919
if (client.transient && modal)
1920
ret = client.transient->setInputFocus();
1923
if (focus_mode == F_LOCALLYACTIVE || focus_mode == F_PASSIVE)
1924
XSetInputFocus(display, client.window,
1925
RevertToPointerRoot, CurrentTime);
1927
XSetInputFocus(display, screen->getRootWindow(),
1928
RevertToNone, CurrentTime);
1930
fluxbox->setFocusedWindow(this);
1932
if (send_focus_message) {
1934
ce.xclient.type = ClientMessage;
1935
ce.xclient.message_type = fluxbox->getWMProtocolsAtom();
1936
ce.xclient.display = display;
1937
ce.xclient.window = client.window;
1938
ce.xclient.format = 32;
1939
ce.xclient.data.l[0] = fluxbox->getWMTakeFocusAtom();
1940
ce.xclient.data.l[1] = fluxbox->getLastTime();
1941
ce.xclient.data.l[2] = 0l;
1942
ce.xclient.data.l[3] = 0l;
1943
ce.xclient.data.l[4] = 0l;
1944
XSendEvent(display, client.window, false, NoEventMask, &ce);
1947
if ((screen->isSloppyFocus() || screen->isSemiSloppyFocus())
1948
&& screen->doAutoRaise())
1960
//------------ setTab --------------
1961
// Enables or disables the tab on the window
1962
//----------------------------------
1963
void FluxboxWindow::setTab(bool flag) {
1966
tab = new Tab(this, 0, 0);
1967
tab->focus(); // draws the tab with correct texture
1968
tab->setPosition(); // set tab windows position
1974
decorations.tab = flag;
1977
//------------- iconify ----------------
1978
// Unmaps the window and removes it from workspace list
1979
//--------------------------------------
1980
void FluxboxWindow::iconify(void) {
1988
setState(IconicState);
1990
XSelectInput(display, client.window, NoEventMask);
1991
XUnmapWindow(display, client.window);
1992
XSelectInput(display, client.window,
1993
PropertyChangeMask | StructureNotifyMask | FocusChangeMask);
1995
XUnmapWindow(display, frame.window);
1999
screen->getWorkspace(workspace_number)->removeWindow(this);
2001
if (transient && client.transient_for) {
2002
if (! client.transient_for->iconic)
2003
client.transient_for->iconify();
2005
screen->addIcon(this);
2007
if (tab) //if this window got a tab then iconify it too
2010
if (client.transient) {
2011
if (! client.transient->iconic)
2012
client.transient->iconify();
2017
void FluxboxWindow::deiconify(bool reassoc, bool raise) {
2018
if (iconic || reassoc)
2019
screen->reassociateWindow(this, -1, false);
2020
else if (workspace_number != screen->getCurrentWorkspace()->getWorkspaceID())
2023
setState(NormalState);
2025
XSelectInput(display, client.window, NoEventMask);
2026
XMapWindow(display, client.window);
2027
XSelectInput(display, client.window,
2028
PropertyChangeMask | StructureNotifyMask | FocusChangeMask);
2030
XMapSubwindows(display, frame.window);
2031
XMapWindow(display, frame.window);
2033
if (iconic && screen->doFocusNew()) setInputFocus();
2038
if (reassoc && client.transient) client.transient->deiconify(true, false);
2044
screen->getWorkspace(workspace_number)->raiseWindow(this);
2051
void FluxboxWindow::close(void) {
2052
Fluxbox *fluxbox = Fluxbox::instance();
2054
ce.xclient.type = ClientMessage;
2055
ce.xclient.message_type = fluxbox->getWMProtocolsAtom();
2056
ce.xclient.display = display;
2057
ce.xclient.window = client.window;
2058
ce.xclient.format = 32;
2059
ce.xclient.data.l[0] = fluxbox->getWMDeleteAtom();
2060
ce.xclient.data.l[1] = CurrentTime;
2061
ce.xclient.data.l[2] = 0l;
2062
ce.xclient.data.l[3] = 0l;
2063
ce.xclient.data.l[4] = 0l;
2064
XSendEvent(display, client.window, false, NoEventMask, &ce);
2068
void FluxboxWindow::withdraw(void) {
2072
XUnmapWindow(display, frame.window);
2074
XSelectInput(display, client.window, NoEventMask);
2075
XUnmapWindow(display, client.window);
2076
XSelectInput(display, client.window,
2077
PropertyChangeMask | StructureNotifyMask | FocusChangeMask);
2087
void FluxboxWindow::maximize(unsigned int button) {
2090
unsigned int dw, dh, slitModL = 0, slitModR = 0, slitModT = 0, slitModB = 0;
2092
Slit* mSlt = screen->getSlit();
2094
if(!screen->doMaxOverSlit() && !screen->doFullMax() && (mSlt->getWidth() > 1))
2096
switch(screen->getSlitDirection())
2098
case Slit::VERTICAL:
2099
switch(screen->getSlitPlacement())
2101
case Slit::TOPRIGHT:
2102
case Slit::CENTERRIGHT:
2103
case Slit::BOTTOMRIGHT:
2104
slitModR = mSlt->getWidth() + screen->getBevelWidth();
2107
slitModL = mSlt->getWidth() + screen->getBevelWidth();
2111
case Slit::HORIZONTAL:
2112
switch(screen->getSlitPlacement())
2115
case Slit::TOPCENTER:
2116
case Slit::TOPRIGHT:
2117
slitModT = mSlt->getHeight() + screen->getBevelWidth();
2118
switch (screen->getToolbarPlacement()) {
2119
case Toolbar::TOPLEFT:
2120
case Toolbar::TOPCENTER:
2121
case Toolbar::TOPRIGHT:
2122
slitModT -= screen->getToolbar()->getExposedHeight() +
2123
screen->getBorderWidth();
2130
slitModB = mSlt->getHeight() + screen->getBevelWidth();
2131
switch (screen->getToolbarPlacement()) {
2132
case Toolbar::BOTTOMLEFT:
2133
case Toolbar::BOTTOMCENTER:
2134
case Toolbar::BOTTOMRIGHT:
2135
slitModB -= screen->getToolbar()->getExposedHeight() +
2136
screen->getBorderWidth();
2148
blackbox_attrib.premax_x = frame.x;
2149
blackbox_attrib.premax_y = frame.y;
2150
blackbox_attrib.premax_w = frame.width;
2151
blackbox_attrib.premax_h = frame.height;
2153
dw = screen->getWidth() - slitModL - slitModR;
2154
dw -= screen->getBorderWidth2x();
2155
dw -= frame.mwm_border_w * 2;
2156
dw -= client.base_width;
2158
dh = screen->getHeight() - slitModT - slitModB;
2159
dh -= screen->getBorderWidth2x();
2160
dh -= frame.mwm_border_w * 2;
2161
dh -= ((frame.handle_h + screen->getBorderWidth()) * decorations.handle);
2162
dh -= client.base_height;
2163
dh -= frame.y_border;
2165
if (! screen->doFullMax())
2166
dh -= screen->getToolbar()->getExposedHeight() +
2167
screen->getBorderWidth2x();
2169
if (dw < client.min_width) dw = client.min_width;
2170
if (dh < client.min_height) dh = client.min_height;
2171
if (dw > client.max_width) dw = client.max_width;
2172
if (dh > client.max_height) dh = client.max_height;
2174
dw -= (dw % client.width_inc);
2175
dw += client.base_width;
2176
dh -= (dh % client.height_inc);
2177
dh += client.base_height;
2179
dw += frame.mwm_border_w * 2;
2181
dh += frame.y_border;
2182
dh += (frame.handle_h + screen->getBorderWidth());
2183
dh += frame.mwm_border_w * 2;
2185
dx = ((screen->getWidth()+ slitModL - slitModR - dw) / 2) - screen->getBorderWidth();
2187
if (screen->doFullMax()) {
2188
dy = ((screen->getHeight() - dh) / 2) - screen->getBorderWidth();
2190
dy = (((screen->getHeight() + slitModT - slitModB - (screen->getToolbar()->getExposedHeight()))
2191
- dh) / 2) - screen->getBorderWidth2x();
2193
switch (screen->getToolbarPlacement()) {
2194
case Toolbar::TOPLEFT:
2195
case Toolbar::TOPCENTER:
2196
case Toolbar::TOPRIGHT:
2197
dy += screen->getToolbar()->getExposedHeight() +
2198
screen->getBorderWidth2x();
2206
switch(screen->getTabPlacement()) {
2208
dy += screen->getTabHeight();
2209
dh -= screen->getTabHeight();
2212
if (screen->isTabRotateVertical()) {
2213
dx += screen->getTabHeight();
2214
dw -= screen->getTabHeight();
2216
dx += screen->getTabWidth();
2217
dw -= screen->getTabWidth();
2221
if (screen->isTabRotateVertical())
2222
dw -= screen->getTabHeight();
2224
dw -= screen->getTabWidth();
2227
dh -= screen->getTabHeight();
2230
dy += screen->getTabHeight();
2231
dh -= screen->getTabHeight();
2236
if (button == 2) { //expand max width
2239
} else if (button == 3) { //expand max height
2246
blackbox_attrib.flags |= BaseDisplay::ATTRIB_MAXHORIZ | BaseDisplay::ATTRIB_MAXVERT;
2247
blackbox_attrib.attrib |= BaseDisplay::ATTRIB_MAXHORIZ | BaseDisplay::ATTRIB_MAXVERT;
2252
blackbox_attrib.flags |= BaseDisplay::ATTRIB_MAXVERT;
2253
blackbox_attrib.attrib |= BaseDisplay::ATTRIB_MAXVERT;
2258
blackbox_attrib.flags |= BaseDisplay::ATTRIB_MAXHORIZ;
2259
blackbox_attrib.attrib |= BaseDisplay::ATTRIB_MAXHORIZ;
2265
blackbox_attrib.flags ^= BaseDisplay::ATTRIB_SHADED;
2266
blackbox_attrib.attrib ^= BaseDisplay::ATTRIB_SHADED;
2274
configure(dx, dy, dw, dh);
2277
screen->getWorkspace(workspace_number)->raiseWindow(this);
2278
setState(current_state);
2289
blackbox_attrib.flags &= ! (BaseDisplay::ATTRIB_MAXHORIZ | BaseDisplay::ATTRIB_MAXVERT);
2290
blackbox_attrib.attrib &= ! (BaseDisplay::ATTRIB_MAXHORIZ | BaseDisplay::ATTRIB_MAXVERT);
2292
configure(blackbox_attrib.premax_x, blackbox_attrib.premax_y,
2293
blackbox_attrib.premax_w, blackbox_attrib.premax_h);
2295
blackbox_attrib.premax_x = blackbox_attrib.premax_y = 0;
2296
blackbox_attrib.premax_w = blackbox_attrib.premax_h = 0;
2299
setState(current_state);
2302
if (tab) //resize all the windows in the tab group
2307
void FluxboxWindow::setWorkspace(int n) {
2308
workspace_number = n;
2310
blackbox_attrib.flags |= BaseDisplay::ATTRIB_WORKSPACE;
2311
blackbox_attrib.workspace = workspace_number;
2313
updateGnomeWorkspaceAtom();
2318
void FluxboxWindow::shade(void) {
2319
if (decorations.titlebar) {
2321
XResizeWindow(display, frame.window, frame.width, frame.height);
2323
blackbox_attrib.flags ^= BaseDisplay::ATTRIB_SHADED;
2324
blackbox_attrib.attrib ^= BaseDisplay::ATTRIB_SHADED;
2326
setState(NormalState);
2328
XResizeWindow(display, frame.window, frame.width, frame.title_h);
2330
blackbox_attrib.flags |= BaseDisplay::ATTRIB_SHADED;
2331
blackbox_attrib.attrib |= BaseDisplay::ATTRIB_SHADED;
2333
setState(IconicState);
2336
updateGnomeStateAtom();
2342
void FluxboxWindow::stick(void) {
2344
if (tab) //if it got a tab then do tab's stick on all of the objects in the list
2345
tab->stick(); //this window will stick too.
2347
blackbox_attrib.flags ^= BaseDisplay::ATTRIB_OMNIPRESENT;
2348
blackbox_attrib.attrib ^= BaseDisplay::ATTRIB_OMNIPRESENT;
2353
screen->reassociateWindow(this, -1, true);
2359
blackbox_attrib.flags |= BaseDisplay::ATTRIB_OMNIPRESENT;
2360
blackbox_attrib.attrib |= BaseDisplay::ATTRIB_OMNIPRESENT;
2363
//find a STICK button in window
2365
setState(current_state);
2367
updateGnomeStateAtom();
2372
void FluxboxWindow::setFocusFlag(bool focus) {
2375
if (decorations.titlebar) {
2378
XSetWindowBackgroundPixmap(display, frame.title, frame.ftitle);
2380
XSetWindowBackground(display, frame.title, frame.ftitle_pixel);
2383
XSetWindowBackgroundPixmap(display, frame.title, frame.utitle);
2385
XSetWindowBackground(display, frame.title, frame.utitle_pixel);
2387
XClearWindow(display, frame.title);
2393
if (decorations.handle) {
2396
XSetWindowBackgroundPixmap(display, frame.handle, frame.fhandle);
2398
XSetWindowBackground(display, frame.handle, frame.fhandle_pixel);
2401
XSetWindowBackgroundPixmap(display, frame.right_grip, frame.fgrip);
2402
XSetWindowBackgroundPixmap(display, frame.left_grip, frame.fgrip);
2404
XSetWindowBackground(display, frame.right_grip, frame.fgrip_pixel);
2405
XSetWindowBackground(display, frame.left_grip, frame.fgrip_pixel);
2409
XSetWindowBackgroundPixmap(display, frame.handle, frame.uhandle);
2411
XSetWindowBackground(display, frame.handle, frame.uhandle_pixel);
2414
XSetWindowBackgroundPixmap(display, frame.right_grip, frame.ugrip);
2415
XSetWindowBackgroundPixmap(display, frame.left_grip, frame.ugrip);
2417
XSetWindowBackground(display, frame.right_grip, frame.ugrip_pixel);
2418
XSetWindowBackground(display, frame.left_grip, frame.ugrip_pixel);
2421
XClearWindow(display, frame.handle);
2422
XClearWindow(display, frame.right_grip);
2423
XClearWindow(display, frame.left_grip);
2429
if (decorations.border) {
2431
XSetWindowBorder(display, frame.plate, frame.fborder_pixel);
2433
XSetWindowBorder(display, frame.plate, frame.uborder_pixel);
2436
if ((screen->isSloppyFocus() || screen->isSemiSloppyFocus()) &&
2437
screen->doAutoRaise() && timer!=0 )
2442
void FluxboxWindow::installColormap(bool install) {
2443
Fluxbox *fluxbox = Fluxbox::instance();
2444
BaseDisplay::GrabGuard gg(*fluxbox);
2446
if (! validateClient()) return;
2448
int i = 0, ncmap = 0;
2449
Colormap *cmaps = XListInstalledColormaps(display, client.window, &ncmap);
2450
XWindowAttributes wattrib;
2452
if (XGetWindowAttributes(display, client.window, &wattrib)) {
2454
// install the window's colormap
2455
for (i = 0; i < ncmap; i++) {
2456
if (*(cmaps + i) == wattrib.colormap) {
2457
// this window is using an installed color map... do not install
2459
break; //end for-loop (we dont need to check more)
2462
// otherwise, install the window's colormap
2464
XInstallColormap(display, wattrib.colormap);
2466
for (i = 0; i < ncmap; i++) // uninstall the window's colormap
2467
if (*(cmaps + i) == wattrib.colormap)
2468
XUninstallColormap(display, wattrib.colormap); // we found the colormap to uninstall
2479
void FluxboxWindow::setState(unsigned long new_state) {
2480
current_state = new_state;
2481
Fluxbox *fluxbox = Fluxbox::instance();
2482
unsigned long state[2];
2483
state[0] = (unsigned long) current_state;
2484
state[1] = (unsigned long) None;
2485
XChangeProperty(display, client.window, fluxbox->getWMStateAtom(),
2486
fluxbox->getWMStateAtom(), 32, PropModeReplace,
2487
(unsigned char *) state, 2);
2489
XChangeProperty(display, client.window, fluxbox->getFluxboxAttributesAtom(),
2490
fluxbox->getFluxboxAttributesAtom(), 32, PropModeReplace,
2491
(unsigned char *) &blackbox_attrib, PropBlackboxAttributesElements);
2494
//TODO: why ungrab in if-statement?
2495
bool FluxboxWindow::getState(void) {
2501
unsigned long *state, ulfoo, nitems;
2502
Fluxbox *fluxbox = Fluxbox::instance();
2503
if ((XGetWindowProperty(display, client.window, fluxbox->getWMStateAtom(),
2504
0l, 2l, false, fluxbox->getWMStateAtom(),
2505
&atom_return, &foo, &nitems, &ulfoo,
2506
(unsigned char **) &state) != Success) ||
2513
current_state = static_cast<unsigned long>(state[0]);
2517
XFree(static_cast<void *>(state));
2523
void FluxboxWindow::setGravityOffsets(void) {
2524
// translate x coordinate
2525
switch (client.win_gravity) {
2526
// handle Westward gravity
2527
case NorthWestGravity:
2529
case SouthWestGravity:
2534
// handle Eastward gravity
2535
case NorthEastGravity:
2537
case SouthEastGravity:
2538
frame.x = (client.x + client.width) - frame.width;
2541
// no x translation desired - default
2545
frame.x = client.x - frame.mwm_border_w + screen->getBorderWidth();
2548
// translate y coordinate
2549
switch (client.win_gravity) {
2550
// handle Northbound gravity
2551
case NorthWestGravity:
2553
case NorthEastGravity:
2558
// handle Southbound gravity
2559
case SouthWestGravity:
2561
case SouthEastGravity:
2562
frame.y = (client.y + client.height) - frame.height;
2565
// no y translation desired - default
2569
frame.y = client.y - frame.y_border - frame.mwm_border_w -
2570
screen->getBorderWidth();
2576
void FluxboxWindow::restoreAttributes(void) {
2578
current_state = NormalState;
2582
unsigned long ulfoo, nitems;
2583
Fluxbox *fluxbox = Fluxbox::instance();
2585
BaseDisplay::BlackboxAttributes *net;
2586
if (XGetWindowProperty(display, client.window,
2587
fluxbox->getFluxboxAttributesAtom(), 0l,
2588
PropBlackboxAttributesElements, false,
2589
fluxbox->getFluxboxAttributesAtom(), &atom_return, &foo,
2590
&nitems, &ulfoo, (unsigned char **) &net) ==
2591
Success && net && nitems == PropBlackboxAttributesElements) {
2592
blackbox_attrib.flags = net->flags;
2593
blackbox_attrib.attrib = net->attrib;
2594
blackbox_attrib.workspace = net->workspace;
2595
blackbox_attrib.stack = net->stack;
2596
blackbox_attrib.premax_x = net->premax_x;
2597
blackbox_attrib.premax_y = net->premax_y;
2598
blackbox_attrib.premax_w = net->premax_w;
2599
blackbox_attrib.premax_h = net->premax_h;
2601
XFree(static_cast<void *>(net));
2605
if (blackbox_attrib.flags & BaseDisplay::ATTRIB_SHADED &&
2606
blackbox_attrib.attrib & BaseDisplay::ATTRIB_SHADED) {
2608
((current_state == IconicState) ? NormalState : current_state);
2615
current_state = save_state;
2618
if (((int) blackbox_attrib.workspace != screen->getCurrentWorkspaceID()) &&
2619
((int) blackbox_attrib.workspace < screen->getCount())) {
2620
screen->reassociateWindow(this, blackbox_attrib.workspace, true);
2622
if (current_state == NormalState) current_state = WithdrawnState;
2623
} else if (current_state == WithdrawnState)
2624
current_state = NormalState;
2626
if (blackbox_attrib.flags & BaseDisplay::ATTRIB_OMNIPRESENT &&
2627
blackbox_attrib.attrib & BaseDisplay::ATTRIB_OMNIPRESENT) {
2631
current_state = NormalState;
2634
if ((blackbox_attrib.flags & BaseDisplay::ATTRIB_MAXHORIZ) ||
2635
(blackbox_attrib.flags & BaseDisplay::ATTRIB_MAXVERT)) {
2636
int x = blackbox_attrib.premax_x, y = blackbox_attrib.premax_y;
2637
unsigned int w = blackbox_attrib.premax_w, h = blackbox_attrib.premax_h;
2641
if ((blackbox_attrib.flags & BaseDisplay::ATTRIB_MAXHORIZ) &&
2642
(blackbox_attrib.flags & BaseDisplay::ATTRIB_MAXVERT))
2643
m = ((blackbox_attrib.attrib & (BaseDisplay::ATTRIB_MAXHORIZ | BaseDisplay::ATTRIB_MAXVERT)) ?
2645
else if (blackbox_attrib.flags & BaseDisplay::ATTRIB_MAXVERT)
2646
m = ((blackbox_attrib.attrib & BaseDisplay::ATTRIB_MAXVERT) ? 2 : 0);
2647
else if (blackbox_attrib.flags & BaseDisplay::ATTRIB_MAXHORIZ)
2648
m = ((blackbox_attrib.attrib & BaseDisplay::ATTRIB_MAXHORIZ) ? 3 : 0);
2654
blackbox_attrib.premax_x = x;
2655
blackbox_attrib.premax_y = y;
2656
blackbox_attrib.premax_w = w;
2657
blackbox_attrib.premax_h = h;
2660
setState(current_state);
2664
void FluxboxWindow::restoreGravity(void) {
2665
// restore x coordinate
2666
switch (client.win_gravity) {
2667
// handle Westward gravity
2668
case NorthWestGravity:
2670
case SouthWestGravity:
2675
// handle Eastward gravity
2676
case NorthEastGravity:
2678
case SouthEastGravity:
2679
client.x = (frame.x + frame.width) - client.width;
2683
// restore y coordinate
2684
switch (client.win_gravity) {
2685
// handle Northbound gravity
2686
case NorthWestGravity:
2688
case NorthEastGravity:
2693
// handle Southbound gravity
2694
case SouthWestGravity:
2696
case SouthEastGravity:
2697
client.y = (frame.y + frame.height) - client.height;
2703
void FluxboxWindow::redrawLabel(void) {
2706
XSetWindowBackgroundPixmap(display, frame.label, frame.flabel);
2708
XSetWindowBackground(display, frame.label, frame.flabel_pixel);
2711
XSetWindowBackgroundPixmap(display, frame.label, frame.ulabel);
2713
XSetWindowBackground(display, frame.label, frame.ulabel_pixel);
2716
GC gc = ((focused) ? screen->getWindowStyle()->l_text_focus_gc :
2717
screen->getWindowStyle()->l_text_unfocus_gc);
2719
DrawUtil::DrawString(display, frame.label, gc,
2720
&screen->getWindowStyle()->font,
2721
client.title_text_w, frame.label_w,
2722
frame.bevel_w, client.title);
2726
void FluxboxWindow::redrawAllButtons(void) {
2727
for (unsigned int i=0; i<buttonlist.size(); i++)
2728
if (buttonlist[i].draw)
2729
buttonlist[i].draw(this, buttonlist[i].win, false);
2733
void FluxboxWindow::mapRequestEvent(XMapRequestEvent *re) {
2734
if (re->window == client.window) {
2737
I18n::instance()->getMessage(
2739
WindowSet, WindowMapRequest,
2743
"FluxboxWindow::mapRequestEvent() for 0x%lx\n"),
2746
Fluxbox *fluxbox = Fluxbox::instance();
2747
BaseDisplay::GrabGuard gg(*fluxbox);
2749
if (! validateClient())
2752
bool get_state_ret = getState();
2753
if (! (get_state_ret && fluxbox->isStartup())) {
2754
if ((client.wm_hint_flags & StateHint) &&
2755
(! (current_state == NormalState || current_state == IconicState)))
2756
current_state = client.initial_state;
2758
current_state = NormalState;
2760
current_state = NormalState;
2762
switch (current_state) {
2768
case WithdrawnState:
2787
void FluxboxWindow::mapNotifyEvent(XMapEvent *ne) {
2791
if ((ne->window == client.window) && (! ne->override_redirect) && (visible)) {
2792
Fluxbox *fluxbox = Fluxbox::instance();
2793
BaseDisplay::GrabGuard gg(*fluxbox);
2795
if (! validateClient())
2798
if (decorations.titlebar)
2801
setState(NormalState);
2805
if (transient || screen->doFocusNew())
2808
setFocusFlag(false);
2818
//------------------- unmapNotify ------------------
2819
// Unmaps frame window and client window if
2820
// event.window == client.window
2821
// Returns true if *this should die
2823
//-------------------------------------------------
2824
bool FluxboxWindow::unmapNotifyEvent(XUnmapEvent *ue) {
2825
if (ue->window == client.window) {
2828
I18n::instance()->getMessage(
2830
WindowSet, WindowUnmapNotify,
2834
"FluxboxWindow::unmapNotifyEvent() for 0x%lx\n"),
2838
Fluxbox *fluxbox = Fluxbox::instance();
2839
BaseDisplay::GrabGuard gg(*fluxbox);
2841
if (! validateClient())
2844
XChangeSaveSet(display, client.window, SetModeDelete);
2845
XSelectInput(display, client.window, NoEventMask);
2847
XDeleteProperty(display, client.window, fluxbox->getWMStateAtom());
2848
XDeleteProperty(display, client.window, fluxbox->getFluxboxAttributesAtom());
2850
XUnmapWindow(display, frame.window);
2851
XUnmapWindow(display, client.window);
2854
if (! XCheckTypedWindowEvent(display, client.window, ReparentNotify,
2858
I18n::instance()->getMessage(
2860
WindowSet, WindowUnmapNotifyReparent,
2864
"FluxboxWindow::unmapNotifyEvent(): reparent 0x%lx to "
2865
"root.\n"), client.window);
2868
XReparentWindow(display, client.window, screen->getRootWindow(),
2869
client.x, client.y);
2882
//----------- destroyNotifyEvent -------------
2883
// Checks if event is for client.window.
2884
// Unmaps frame.window and returns true for destroy
2885
// of this FluxboxWindow else returns false.
2886
//--------------------------------------------
2887
bool FluxboxWindow::destroyNotifyEvent(XDestroyWindowEvent *de) {
2888
if (de->window == client.window) {
2890
cerr<<__FILE__<<"("<<__LINE__<<":) DestroyNotifyEvent this="<<this<<endl;
2892
XUnmapWindow(display, frame.window);
2899
void FluxboxWindow::propertyNotifyEvent(Atom atom) {
2900
Fluxbox *fluxbox = Fluxbox::instance();
2901
BaseDisplay::GrabGuard gg(*fluxbox);
2903
if (! validateClient()) return;
2907
case XA_WM_CLIENT_MACHINE:
2911
case XA_WM_TRANSIENT_FOR:
2912
// determine if this is a transient window
2914
if (XGetTransientForHint(display, client.window, &win)) {
2915
if (win && (win != client.window))
2916
if ((client.transient_for = fluxbox->searchWindow(win))) {
2917
client.transient_for->client.transient = this;
2918
stuck = client.transient_for->stuck;
2920
} else if (win == client.window_group) {
2921
//jr This doesn't look quite right...
2922
if ((client.transient_for = fluxbox->searchGroup(win, this))) {
2923
client.transient_for->client.transient = this;
2924
stuck = client.transient_for->stuck;
2929
if (win == screen->getRootWindow()) modal = true;
2932
// adjust the window decorations based on transience
2934
decorations.maximize = decorations.handle =
2935
decorations.border = functions.maximize = false;
2945
case XA_WM_ICON_NAME:
2947
if (iconic) screen->iconUpdate();
2953
if (decorations.titlebar)
2956
if (hasTab()) // update tab
2957
getTab()->draw(false);
2960
screen->getWorkspace(workspace_number)->update();
2961
else if (Fluxbox::instance()->useIconBar()) {
2962
IconBar *iconbar = 0;
2963
IconBarObj *icon = 0;
2964
if ((iconbar = screen->getToolbar()->getIconBar()) != 0) {
2965
if ((icon = iconbar->findIcon(this)) != 0)
2966
iconbar->draw(icon, icon->getWidth());
2969
cerr<<__FILE__<<"("<<__LINE__<<"): can't find icon!"<<endl;
2974
cerr<<__FILE__<<"("<<__LINE__<<"): can't find iconbar!"<<endl;
2980
case XA_WM_NORMAL_HINTS: {
2983
if ((client.normal_hint_flags & PMinSize) &&
2984
(client.normal_hint_flags & PMaxSize)) {
2985
if (client.max_width <= client.min_width &&
2986
client.max_height <= client.min_height)
2987
decorations.maximize = decorations.handle =
2988
functions.resize = functions.maximize = false;
2990
decorations.maximize = decorations.handle =
2991
functions.resize = functions.maximize = true;
2994
int x = frame.x, y = frame.y;
2995
unsigned int w = frame.width, h = frame.height;
2999
if ((x != frame.x) || (y != frame.y) ||
3000
(w != frame.width) || (h != frame.height))
3007
if (atom == fluxbox->getWMProtocolsAtom()) {
3010
if (decorations.close && !findTitleButton(Fluxbox::CLOSE)) {
3011
createButton(Fluxbox::CLOSE, FluxboxWindow::closePressed_cb,
3012
FluxboxWindow::closeButton_cb, FluxboxWindow::closeDraw_cb);
3014
if (decorations.titlebar)
3015
positionButtons(true);
3017
windowmenu->reconfigure();
3022
val = handleGnomePropertyNotify(atom);
3026
handleNETWMPropertyNotify(atom);
3036
void FluxboxWindow::exposeEvent(XExposeEvent *ee) {
3037
if (frame.label == ee->window && decorations.titlebar)
3045
void FluxboxWindow::configureRequestEvent(XConfigureRequestEvent *cr) {
3046
if (cr->window == client.window) {
3047
Fluxbox *fluxbox = Fluxbox::instance();
3048
BaseDisplay::GrabGuard gg(*fluxbox);
3050
if (! validateClient())
3053
int cx = frame.x, cy = frame.y;
3054
unsigned int cw = frame.width, ch = frame.height;
3056
if (cr->value_mask & CWBorderWidth)
3057
client.old_bw = cr->border_width;
3059
if (cr->value_mask & CWX)
3060
cx = cr->x - frame.mwm_border_w - screen->getBorderWidth();
3062
if (cr->value_mask & CWY)
3063
cy = cr->y - frame.y_border - frame.mwm_border_w -
3064
screen->getBorderWidth();
3066
if (cr->value_mask & CWWidth)
3067
cw = cr->width + (frame.mwm_border_w * 2);
3069
if (cr->value_mask & CWHeight)
3070
ch = cr->height + frame.y_border + (frame.mwm_border_w * 2) +
3071
(screen->getBorderWidth() * decorations.handle) + frame.handle_h;
3073
if (frame.x != cx || frame.y != cy ||
3074
frame.width != cw || frame.height != ch) {
3075
configure(cx, cy, cw, ch);
3079
if (cr->value_mask & CWStackMode) {
3080
switch (cr->detail) {
3086
//!!TODO check this and the line below..
3089
screen->getWorkspace(workspace_number)->raiseWindow(this);
3099
screen->getWorkspace(workspace_number)->lowerWindow(this);
3109
void FluxboxWindow::buttonPressEvent(XButtonEvent *be) {
3110
Fluxbox *fluxbox = Fluxbox::instance();
3111
BaseDisplay::GrabGuard gg(*fluxbox);
3114
if (! validateClient())
3117
if (be->button == 1 || (be->button == 3 && be->state == Mod1Mask)) {
3118
if ((! focused) && (! screen->isSloppyFocus())) //check focus
3122
for (unsigned int i=0; i<buttonlist.size(); i++) {
3123
if (be->window == buttonlist[i].win && buttonlist[i].draw)
3124
buttonlist[i].draw(this, be->window, true);
3127
if (frame.plate == be->window) {
3129
if (windowmenu && windowmenu->isVisible()) //hide menu if its visible
3131
//raise tab first, if there is any, so the focus on windows get
3132
//right and dont "hide" the tab behind other windows
3136
screen->getWorkspace(workspace_number)->raiseWindow(this);
3138
XAllowEvents(display, ReplayPointer, be->time);
3142
if (frame.title == be->window || frame.label == be->window) {
3143
if (((be->time - lastButtonPressTime) <=
3144
fluxbox->getDoubleClickInterval()) ||
3145
(be->state & ControlMask)) {
3146
lastButtonPressTime = 0;
3148
if (tab) //shade windows in the tablist too
3151
lastButtonPressTime = be->time;
3155
frame.grab_x = be->x_root - frame.x - screen->getBorderWidth();
3156
frame.grab_y = be->y_root - frame.y - screen->getBorderWidth();
3158
if (windowmenu && windowmenu->isVisible())
3160
//raise tab first if there is any
3164
screen->getWorkspace(workspace_number)->raiseWindow(this);
3166
} else if (be->button == 2 && be->window == frame.label) {
3167
screen->getWorkspace(workspace_number)->lowerWindow(this);
3169
getTab()->lower(); //lower the tab AND it's windows
3171
} else if (windowmenu && be->button == 3 &&
3172
(frame.title == be->window || frame.label == be->window ||
3173
frame.handle == be->window)) {
3177
if (frame.title == be->window || frame.label == be->window) {
3178
mx = be->x_root - (windowmenu->getWidth() / 2);
3179
my = frame.y + frame.title_h;
3180
} else if (frame.handle == be->window) {
3181
mx = be->x_root - (windowmenu->getWidth() / 2);
3182
my = frame.y + frame.y_handle - windowmenu->getHeight();
3184
bool buttonproc=false;
3187
mx = be->x_root - (windowmenu->getWidth() / 2);
3189
if (be->y <= (signed) frame.bevel_w)
3190
my = frame.y + frame.y_border;
3192
my = be->y_root - (windowmenu->getHeight() / 2);
3195
if (mx > (signed) (frame.x + frame.width - windowmenu->getWidth()))
3196
mx = frame.x + frame.width - windowmenu->getWidth();
3200
if (my > (signed) (frame.y + frame.y_handle - windowmenu->getHeight()))
3201
my = frame.y + frame.y_handle - windowmenu->getHeight();
3202
if (my < (signed) (frame.y + ((decorations.titlebar) ? frame.title_h :
3205
((decorations.titlebar) ? frame.title_h : frame.y_border);
3208
if (! windowmenu->isVisible()) { // if not window menu is visible then show it
3209
windowmenu->move(mx, my);
3211
XRaiseWindow(display, windowmenu->getWindowID());
3212
XRaiseWindow(display, windowmenu->getSendToMenu()->getWindowID());
3213
XRaiseWindow(display, windowmenu->getSendGroupToMenu()->getWindowID());
3214
} else //else hide menu
3218
} else if (be->button == 4) { //scroll to tab right
3219
if (tab && tab->next()) {
3220
tab->next()->getWindow()->setInputFocus();
3221
screen->getWorkspace(workspace_number)->raiseWindow(tab->next()->getWindow());
3223
} else if (be->button == 5) { //scroll to tab left
3224
if (tab && tab->prev()) {
3225
tab->prev()->getWindow()->setInputFocus();
3226
screen->getWorkspace(workspace_number)->raiseWindow(tab->prev()->getWindow());
3234
void FluxboxWindow::buttonReleaseEvent(XButtonEvent *re) {
3235
Fluxbox *fluxbox = Fluxbox::instance();
3236
BaseDisplay::GrabGuard gg(*fluxbox);
3239
if (! validateClient())
3245
fluxbox->maskWindowEvents(0, (FluxboxWindow *) 0);
3247
if (! screen->doOpaqueMove()) {
3248
XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(),
3249
frame.move_x, frame.move_y, frame.resize_w,
3252
configure(frame.move_x, frame.move_y, frame.width, frame.height);
3255
configure(frame.x, frame.y, frame.width, frame.height);
3257
screen->hideGeometry();
3258
XUngrabPointer(display, CurrentTime);
3259
} else if (resizing) {
3260
XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(),
3261
frame.resize_x, frame.resize_y,
3262
frame.resize_w, frame.resize_h);
3264
screen->hideGeometry();
3266
if (re->window == frame.left_grip)
3272
configure(frame.resize_x, frame.resize_y,
3273
frame.resize_w - screen->getBorderWidth2x(),
3274
frame.resize_h - screen->getBorderWidth2x());
3280
XUngrabPointer(display, CurrentTime);
3281
} else if (re->window == frame.window) {
3282
if (re->button == 2 && re->state == Mod1Mask)
3283
XUngrabPointer(display, CurrentTime);
3285
if ((re->x >= 0) && ((unsigned) re->x <= frame.button_w) &&
3286
(re->y >= 0) && ((unsigned) re->y <= frame.button_h)) {
3287
for (unsigned int i=0; i<buttonlist.size(); i++) {
3288
if (re->window == buttonlist[i].win &&
3289
buttonlist[i].released) {
3290
buttonlist[i].released(this, re);
3302
void FluxboxWindow::motionNotifyEvent(XMotionEvent *me) {
3303
Fluxbox *fluxbox = Fluxbox::instance();
3304
if ((me->state & Button1Mask) && functions.move &&
3305
(frame.title == me->window || frame.label == me->window ||
3306
frame.handle == me->window || frame.window == me->window) && !resizing) {
3309
XGrabPointer(display, me->window, False, Button1MotionMask |
3310
ButtonReleaseMask, GrabModeAsync, GrabModeAsync,
3311
None, fluxbox->getMoveCursor(), CurrentTime);
3313
if (windowmenu && windowmenu->isVisible())
3318
fluxbox->maskWindowEvents(client.window, this);
3320
if (! screen->doOpaqueMove()) {
3323
frame.move_x = frame.x;
3324
frame.move_y = frame.y;
3325
frame.resize_w = frame.width + screen->getBorderWidth2x();
3326
frame.resize_h = ((shaded) ? frame.title_h : frame.height) +
3327
screen->getBorderWidth2x();
3329
screen->showPosition(frame.x, frame.y);
3331
XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(),
3332
frame.move_x, frame.move_y,
3333
frame.resize_w, frame.resize_h);
3336
int dx = me->x_root - frame.grab_x, dy = me->y_root - frame.grab_y;
3338
dx -= screen->getBorderWidth();
3339
dy -= screen->getBorderWidth();
3341
if (screen->getEdgeSnapThreshold()) {
3342
int drx = screen->getWidth() - (dx + frame.snap_w);
3344
if (dx > 0 && dx < drx && dx < screen->getEdgeSnapThreshold())
3346
else if (drx > 0 && drx < screen->getEdgeSnapThreshold())
3347
dx = screen->getWidth() - frame.snap_w;
3349
int dtty, dbby, dty, dby;
3350
switch (screen->getToolbarPlacement()) {
3351
case Toolbar::TOPLEFT:
3352
case Toolbar::TOPCENTER:
3353
case Toolbar::TOPRIGHT:
3354
dtty = screen->getToolbar()->getExposedHeight() +
3355
screen->getBorderWidth();
3356
dbby = screen->getHeight();
3361
dbby = screen->getToolbar()->getY();
3366
dby = dbby - (dy + frame.snap_h);
3368
if (dy > 0 && dty < screen->getEdgeSnapThreshold())
3370
else if (dby > 0 && dby < screen->getEdgeSnapThreshold())
3371
dy = dbby - frame.snap_h;
3374
if (! screen->doOpaqueMove()) {
3375
XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(),
3376
frame.move_x, frame.move_y, frame.resize_w,
3382
XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(),
3383
frame.move_x, frame.move_y, frame.resize_w,
3386
configure(dx, dy, frame.width, frame.height);
3388
screen->showPosition(dx, dy);
3390
} else if (functions.resize &&
3391
(((me->state & Button1Mask) && (me->window == frame.right_grip ||
3392
me->window == frame.left_grip)) ||
3393
me->window == frame.window)) {
3394
bool left = (me->window == frame.left_grip);
3397
XGrabPointer(display, me->window, false, ButtonMotionMask |
3398
ButtonReleaseMask, GrabModeAsync, GrabModeAsync, None,
3399
((left) ? fluxbox->getLowerLeftAngleCursor() :
3400
fluxbox->getLowerRightAngleCursor()),
3408
frame.grab_x = me->x - screen->getBorderWidth();
3409
frame.grab_y = me->y - screen->getBorderWidth2x();
3410
frame.resize_x = frame.x;
3411
frame.resize_y = frame.y;
3412
frame.resize_w = frame.width + screen->getBorderWidth2x();
3413
frame.resize_h = frame.height + screen->getBorderWidth2x();
3416
left_fixsize(&gx, &gy);
3418
right_fixsize(&gx, &gy);
3420
screen->showGeometry(gx, gy);
3422
XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(),
3423
frame.resize_x, frame.resize_y,
3424
frame.resize_w, frame.resize_h);
3425
} else if (resizing) {
3426
XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(),
3427
frame.resize_x, frame.resize_y,
3428
frame.resize_w, frame.resize_h);
3432
frame.resize_h = frame.height + (me->y - frame.grab_y);
3433
if (frame.resize_h < 1)
3437
frame.resize_x = me->x_root - frame.grab_x;
3438
if (frame.resize_x > (signed) (frame.x + frame.width))
3439
frame.resize_x = frame.resize_x + frame.width - 1;
3441
left_fixsize(&gx, &gy);
3443
frame.resize_w = frame.width + (me->x - frame.grab_x);
3444
if (frame.resize_w < 1)
3447
right_fixsize(&gx, &gy);
3450
XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(),
3451
frame.resize_x, frame.resize_y,
3452
frame.resize_w, frame.resize_h);
3454
screen->showGeometry(gx, gy);
3461
void FluxboxWindow::shapeEvent(XShapeEvent *) {
3462
Fluxbox *fluxbox = Fluxbox::instance();
3463
BaseDisplay::GrabGuard gg(*fluxbox);
3465
if (fluxbox->hasShapeExtensions()) {
3468
if (! validateClient())
3470
XShapeCombineShape(display, frame.window, ShapeBounding,
3471
frame.mwm_border_w, frame.y_border +
3472
frame.mwm_border_w, client.window,
3473
ShapeBounding, ShapeSet);
3476
XRectangle xrect[2];
3477
xrect[0].x = xrect[0].y = 0;
3478
xrect[0].width = frame.width;
3479
xrect[0].height = frame.y_border;
3481
if (decorations.handle) {
3483
xrect[1].y = frame.y_handle;
3484
xrect[1].width = frame.width;
3485
xrect[1].height = frame.handle_h + screen->getBorderWidth();
3489
XShapeCombineRectangles(display, frame.window, ShapeBounding, 0, 0,
3490
xrect, num, ShapeUnion, Unsorted);
3498
bool FluxboxWindow::validateClient(void) {
3499
XSync(display, false);
3502
if (XCheckTypedWindowEvent(display, client.window, DestroyNotify, &e) ||
3503
XCheckTypedWindowEvent(display, client.window, UnmapNotify, &e)) {
3504
XPutBackEvent(display, &e);
3505
Fluxbox::instance()->ungrab();
3514
void FluxboxWindow::restore(void) {
3515
XChangeSaveSet(display, client.window, SetModeDelete);
3516
XSelectInput(display, client.window, NoEventMask);
3520
XUnmapWindow(display, frame.window);
3521
XUnmapWindow(display, client.window);
3523
XSetWindowBorderWidth(display, client.window, client.old_bw);
3524
XReparentWindow(display, client.window, screen->getRootWindow(),
3525
client.x, client.y);
3526
XMapWindow(display, client.window);
3532
void FluxboxWindow::timeout(void) {
3535
screen->getWorkspace(workspace_number)->raiseWindow(this);
3539
void FluxboxWindow::changeBlackboxHints(BaseDisplay::BlackboxHints *net) {
3540
if ((net->flags & BaseDisplay::ATTRIB_SHADED) &&
3541
((blackbox_attrib.attrib & BaseDisplay::ATTRIB_SHADED) !=
3542
(net->attrib & BaseDisplay::ATTRIB_SHADED)))
3545
if ((net->flags & (BaseDisplay::ATTRIB_MAXVERT | BaseDisplay::ATTRIB_MAXHORIZ)) &&
3546
((blackbox_attrib.attrib & (BaseDisplay::ATTRIB_MAXVERT | BaseDisplay::ATTRIB_MAXHORIZ)) !=
3547
(net->attrib & (BaseDisplay::ATTRIB_MAXVERT | BaseDisplay::ATTRIB_MAXHORIZ)))) {
3553
if ((net->flags & BaseDisplay::ATTRIB_MAXHORIZ) && (net->flags & BaseDisplay::ATTRIB_MAXVERT))
3554
m = ((net->attrib & (BaseDisplay::ATTRIB_MAXHORIZ | BaseDisplay::ATTRIB_MAXVERT)) ? 1 : 0);
3555
else if (net->flags & BaseDisplay::ATTRIB_MAXVERT)
3556
m = ((net->attrib & BaseDisplay::ATTRIB_MAXVERT) ? 2 : 0);
3557
else if (net->flags & BaseDisplay::ATTRIB_MAXHORIZ)
3558
m = ((net->attrib & BaseDisplay::ATTRIB_MAXHORIZ) ? 3 : 0);
3564
if ((net->flags & BaseDisplay::ATTRIB_OMNIPRESENT) &&
3565
((blackbox_attrib.attrib & BaseDisplay::ATTRIB_OMNIPRESENT) !=
3566
(net->attrib & BaseDisplay::ATTRIB_OMNIPRESENT)))
3569
if ((net->flags & BaseDisplay::ATTRIB_WORKSPACE) &&
3570
(workspace_number != (signed) net->workspace)) {
3571
screen->reassociateWindow(this, net->workspace, true);
3573
if (screen->getCurrentWorkspaceID() != (signed) net->workspace)
3579
if (net->flags & BaseDisplay::ATTRIB_DECORATION) {
3580
switch (net->decoration) {
3581
case BaseDisplay::DECOR_NONE:
3582
decorations.titlebar = decorations.border = decorations.handle =
3583
decorations.iconify = decorations.maximize =
3584
decorations.menu = decorations.tab = false; //tab is also a decor
3585
functions.resize = functions.move = functions.iconify =
3586
functions.maximize = false;
3591
case BaseDisplay::DECOR_NORMAL:
3592
decorations.titlebar = decorations.border = decorations.handle =
3593
decorations.iconify = decorations.maximize =
3594
decorations.menu = true;
3595
functions.resize = functions.move = functions.iconify =
3596
functions.maximize = true;
3600
case BaseDisplay::DECOR_TINY:
3601
decorations.titlebar = decorations.iconify = decorations.menu =
3602
functions.move = functions.iconify = true;
3603
decorations.border = decorations.handle = decorations.maximize =
3604
functions.resize = functions.maximize = false;
3608
case BaseDisplay::DECOR_TOOL:
3609
decorations.titlebar = decorations.menu = functions.move = true;
3610
decorations.iconify = decorations.border = decorations.handle =
3611
decorations.maximize = functions.resize = functions.maximize =
3612
functions.iconify = false;
3622
void FluxboxWindow::upsize(void) {
3623
// convert client.width/height into frame sizes
3625
frame.bevel_w = screen->getBevelWidth();
3626
frame.mwm_border_w = screen->getFrameWidth() * decorations.border;
3628
if (I18n::instance()->multibyte()) {
3629
frame.title_h = (screen->getWindowStyle()->font.set_extents->
3630
max_ink_extent.height +
3631
(frame.bevel_w * 2) + 2) * decorations.titlebar;
3633
frame.title_h = (screen->getWindowStyle()->font.fontstruct->ascent +
3634
screen->getWindowStyle()->font.fontstruct->descent +
3635
(frame.bevel_w * 2) + 2) * decorations.titlebar;
3637
frame.label_h = (frame.title_h - (frame.bevel_w * 2)) * decorations.titlebar;
3638
frame.button_w = frame.button_h = frame.label_h - 2;
3640
frame.y_border = (frame.title_h + screen->getBorderWidth()) * decorations.titlebar;
3641
frame.border_h = client.height + (frame.mwm_border_w * 2);
3643
frame.y_handle = frame.y_border + frame.border_h +
3644
(screen->getBorderWidth() * decorations.handle);
3645
frame.handle_h = decorations.handle * screen->getHandleWidth();
3647
frame.grip_w = (frame.button_h * 2) * decorations.handle;
3648
frame.grip_h = screen->getHandleWidth() * decorations.handle;
3650
frame.width = client.width + (frame.mwm_border_w * 2);
3651
frame.height = frame.y_handle + frame.handle_h;
3653
frame.snap_w = frame.width + screen->getBorderWidth2x();
3654
frame.snap_h = frame.height + screen->getBorderWidth2x();
3658
void FluxboxWindow::downsize(void) {
3659
// convert frame.width/height into client sizes
3661
frame.y_handle = frame.height - frame.handle_h;
3662
frame.border_h = frame.y_handle - frame.y_border -
3663
(screen->getBorderWidth() * decorations.handle);
3665
client.x = frame.x + frame.mwm_border_w + screen->getBorderWidth();
3666
client.y = frame.y + frame.y_border + frame.mwm_border_w +
3667
screen->getBorderWidth();
3669
client.width = frame.width - (frame.mwm_border_w * 2);
3670
client.height = frame.height - frame.y_border -
3671
(frame.mwm_border_w * 2) - frame.handle_h -
3672
(screen->getBorderWidth() * decorations.handle);
3674
frame.y_handle = frame.border_h + frame.y_border + screen->getBorderWidth();
3676
frame.snap_w = frame.width + screen->getBorderWidth2x();
3677
frame.snap_h = frame.height + screen->getBorderWidth2x();
3681
void FluxboxWindow::right_fixsize(int *gx, int *gy) {
3682
// calculate the size of the client window and conform it to the
3683
// size specified by the size hints of the client window...
3684
int dx = frame.resize_w - client.base_width - (frame.mwm_border_w * 2) -
3685
screen->getBorderWidth2x();
3686
int dy = frame.resize_h - frame.y_border - client.base_height -
3687
frame.handle_h - (screen->getBorderWidth() * 3) - (frame.mwm_border_w * 2);
3689
if (dx < (signed) client.min_width)
3690
dx = client.min_width;
3691
if (dy < (signed) client.min_height)
3692
dy = client.min_height;
3693
if ((unsigned) dx > client.max_width)
3694
dx = client.max_width;
3695
if ((unsigned) dy > client.max_height)
3696
dy = client.max_height;
3698
dx /= client.width_inc;
3699
dy /= client.height_inc;
3704
dx = (dx * client.width_inc) + client.base_width;
3705
dy = (dy * client.height_inc) + client.base_height;
3707
frame.resize_w = dx + (frame.mwm_border_w * 2) + screen->getBorderWidth2x();
3708
frame.resize_h = dy + frame.y_border + frame.handle_h +
3709
(frame.mwm_border_w * 2) + (screen->getBorderWidth() * 3);
3713
void FluxboxWindow::left_fixsize(int *gx, int *gy) {
3714
// calculate the size of the client window and conform it to the
3715
// size specified by the size hints of the client window...
3716
int dx = frame.x + frame.width - frame.resize_x - client.base_width -
3717
(frame.mwm_border_w * 2);
3718
int dy = frame.resize_h - frame.y_border - client.base_height -
3719
frame.handle_h - (screen->getBorderWidth() * 3) - (frame.mwm_border_w * 2);
3721
if (dx < (signed) client.min_width) dx = client.min_width;
3722
if (dy < (signed) client.min_height) dy = client.min_height;
3723
if ((unsigned) dx > client.max_width) dx = client.max_width;
3724
if ((unsigned) dy > client.max_height) dy = client.max_height;
3726
dx /= client.width_inc;
3727
dy /= client.height_inc;
3732
dx = (dx * client.width_inc) + client.base_width;
3733
dy = (dy * client.height_inc) + client.base_height;
3735
frame.resize_w = dx + (frame.mwm_border_w * 2) + screen->getBorderWidth2x();
3736
frame.resize_x = frame.x + frame.width - frame.resize_w +
3737
screen->getBorderWidth2x();
3738
frame.resize_h = dy + frame.y_border + frame.handle_h +
3739
(frame.mwm_border_w * 2) + (screen->getBorderWidth() * 3);