~ubuntu-branches/ubuntu/vivid/blackbox/vivid

« back to all changes in this revision

Viewing changes to src/Slit.cc

  • Committer: Bazaar Package Importer
  • Author(s): Jesus Climent
  • Date: 2003-10-15 15:38:53 UTC
  • Revision ID: james.westby@ubuntu.com-20031015153853-c08p60n6fes52hs1
Tags: 0.65.0-1.2
* Non Maintainer Upload
* Patch by Matt Kraai to solve FTBFS: Closes: #208814.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
1
2
// Slit.cc for Blackbox - an X11 Window manager
2
 
// Copyright (c) 2001 Sean 'Shaleh' Perry <shaleh@debian.org>
 
3
// Copyright (c) 2001 - 2002 Sean 'Shaleh' Perry <shaleh@debian.org>
3
4
// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
4
5
//
5
6
// Permission is hereby granted, free of charge, to any person obtaining a
20
21
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21
22
// DEALINGS IN THE SOFTWARE.
22
23
 
23
 
// stupid macros needed to access some functions in version 2 of the GNU C
24
 
// library
25
 
#ifndef   _GNU_SOURCE
26
 
#define   _GNU_SOURCE
27
 
#endif // _GNU_SOURCE
28
 
 
29
24
#ifdef    HAVE_CONFIG_H
30
25
#  include "../config.h"
31
26
#endif // HAVE_CONFIG_H
32
27
 
33
 
#ifdef    SLIT
34
 
 
 
28
extern "C" {
35
29
#include <X11/keysym.h>
 
30
}
36
31
 
37
32
#include "i18n.hh"
38
33
#include "blackbox.hh"
54
49
 
55
50
  timer = new BTimer(blackbox, this);
56
51
  timer->setTimeout(blackbox->getAutoRaiseDelay());
57
 
  timer->fireOnce(True);
58
 
 
59
 
  clientList = new LinkedList<SlitClient>;
60
52
 
61
53
  slitmenu = new Slitmenu(this);
62
54
 
65
57
                              CWColormap | CWOverrideRedirect | CWEventMask;
66
58
  attrib.background_pixmap = None;
67
59
  attrib.background_pixel = attrib.border_pixel =
68
 
    screen->getBorderColor()->getPixel();
 
60
    screen->getBorderColor()->pixel();
69
61
  attrib.colormap = screen->getColormap();
70
62
  attrib.override_redirect = True;
71
63
  attrib.event_mask = SubstructureRedirectMask | ButtonPressMask |
72
64
                      EnterWindowMask | LeaveWindowMask;
73
65
 
74
 
  frame.x = frame.y = 0;
75
 
  frame.width = frame.height = 1;
 
66
  frame.rect.setSize(1, 1);
76
67
 
77
68
  frame.window =
78
 
    XCreateWindow(display, screen->getRootWindow(), frame.x, frame.y,
79
 
                  frame.width, frame.height, screen->getBorderWidth(),
80
 
                  screen->getDepth(), InputOutput, screen->getVisual(),
81
 
                  create_mask, &attrib);
 
69
    XCreateWindow(display, screen->getRootWindow(),
 
70
                  frame.rect.x(), frame.rect.y(),
 
71
                  frame.rect.width(), frame.rect.height(),
 
72
                  screen->getBorderWidth(), screen->getDepth(), InputOutput,
 
73
                  screen->getVisual(), create_mask, &attrib);
82
74
  blackbox->saveSlitSearch(frame.window, this);
83
75
 
 
76
  screen->addStrut(&strut);
 
77
 
84
78
  reconfigure();
85
79
}
86
80
 
87
81
 
88
 
Slit::~Slit() {
89
 
  blackbox->grab();
90
 
 
91
 
  if (timer->isTiming()) timer->stop();
 
82
Slit::~Slit(void) {
92
83
  delete timer;
93
84
 
94
 
  delete clientList;
95
85
  delete slitmenu;
96
86
 
 
87
  screen->removeStrut(&strut);
 
88
  screen->updateAvailableArea();
 
89
 
97
90
  screen->getImageControl()->removeImage(frame.pixmap);
98
91
 
99
92
  blackbox->removeSlitSearch(frame.window);
100
93
 
101
94
  XDestroyWindow(display, frame.window);
102
 
 
103
 
  blackbox->ungrab();
104
95
}
105
96
 
106
97
 
107
98
void Slit::addClient(Window w) {
108
 
  blackbox->grab();
109
 
 
110
 
  if (blackbox->validateWindow(w)) {
111
 
    SlitClient *client = new SlitClient;
112
 
    client->client_window = w;
113
 
 
114
 
    XWMHints *wmhints = XGetWMHints(display, w);
115
 
 
116
 
    if (wmhints) {
117
 
      if ((wmhints->flags & IconWindowHint) &&
118
 
          (wmhints->icon_window != None)) {
119
 
        XMoveWindow(display, client->client_window, screen->getWidth() + 10,
120
 
                    screen->getHeight() + 10);
121
 
        XMapWindow(display, client->client_window);
122
 
 
123
 
        client->icon_window = wmhints->icon_window;
124
 
        client->window = client->icon_window;
125
 
      } else {
126
 
        client->icon_window = None;
127
 
        client->window = client->client_window;
128
 
      }
129
 
 
130
 
      XFree(wmhints);
 
99
  if (! blackbox->validateWindow(w))
 
100
    return;
 
101
 
 
102
  SlitClient *client = new SlitClient;
 
103
  client->client_window = w;
 
104
 
 
105
  XWMHints *wmhints = XGetWMHints(display, w);
 
106
 
 
107
  if (wmhints) {
 
108
    if ((wmhints->flags & IconWindowHint) &&
 
109
        (wmhints->icon_window != None)) {
 
110
      // some dock apps use separate windows, we need to hide these
 
111
      XMoveWindow(display, client->client_window, screen->getWidth() + 10,
 
112
                  screen->getHeight() + 10);
 
113
      XMapWindow(display, client->client_window);
 
114
 
 
115
      client->icon_window = wmhints->icon_window;
 
116
      client->window = client->icon_window;
131
117
    } else {
132
118
      client->icon_window = None;
133
119
      client->window = client->client_window;
134
120
    }
135
121
 
136
 
    XWindowAttributes attrib;
137
 
    if (XGetWindowAttributes(display, client->window, &attrib)) {
138
 
      client->width = attrib.width;
139
 
      client->height = attrib.height;
140
 
    } else {
141
 
      client->width = client->height = 64;
 
122
    XFree(wmhints);
 
123
  } else {
 
124
    client->icon_window = None;
 
125
    client->window = client->client_window;
 
126
  }
 
127
 
 
128
  XWindowAttributes attrib;
 
129
  if (XGetWindowAttributes(display, client->window, &attrib)) {
 
130
    client->rect.setSize(attrib.width, attrib.height);
 
131
  } else {
 
132
    client->rect.setSize(64, 64);
 
133
  }
 
134
 
 
135
  Atom *proto;
 
136
  int num_return = 0;
 
137
  if (XGetWMProtocols(display, client->window, &proto, &num_return)) {
 
138
    for (int i = 0; i < num_return; ++i) {
 
139
      if (proto[i] == blackbox->getBlackboxStructureMessagesAtom()) {
 
140
        screen->addNetizen(new Netizen(screen, client->window));
 
141
      }
142
142
    }
143
 
 
144
 
    XSetWindowBorderWidth(display, client->window, 0);
145
 
 
146
 
    XSelectInput(display, frame.window, NoEventMask);
147
 
    XSelectInput(display, client->window, NoEventMask);
148
 
 
149
 
    XReparentWindow(display, client->window, frame.window, 0, 0);
150
 
    XMapRaised(display, client->window);
151
 
    XChangeSaveSet(display, client->window, SetModeInsert);
152
 
 
153
 
    XSelectInput(display, frame.window, SubstructureRedirectMask |
154
 
                 ButtonPressMask | EnterWindowMask | LeaveWindowMask);
155
 
    XSelectInput(display, client->window, StructureNotifyMask |
156
 
                 SubstructureNotifyMask | EnterWindowMask);
157
 
    XFlush(display);
158
 
 
159
 
    clientList->insert(client);
160
 
 
161
 
    blackbox->saveSlitSearch(client->client_window, this);
162
 
    blackbox->saveSlitSearch(client->icon_window, this);
163
 
    reconfigure();
164
143
  }
165
144
 
166
 
  blackbox->ungrab();
 
145
  XSetWindowBorderWidth(display, client->window, 0);
 
146
 
 
147
  XGrabServer(display);
 
148
  XSelectInput(display, frame.window, NoEventMask);
 
149
  XSelectInput(display, client->window, NoEventMask);
 
150
  XReparentWindow(display, client->window, frame.window, 0, 0);
 
151
  XMapRaised(display, client->window);
 
152
  XChangeSaveSet(display, client->window, SetModeInsert);
 
153
  XSelectInput(display, frame.window, SubstructureRedirectMask |
 
154
               ButtonPressMask | EnterWindowMask | LeaveWindowMask);
 
155
  XSelectInput(display, client->window, StructureNotifyMask |
 
156
               SubstructureNotifyMask | EnterWindowMask);
 
157
 
 
158
  XUngrabServer(display);
 
159
 
 
160
  clientList.push_back(client);
 
161
 
 
162
  blackbox->saveSlitSearch(client->client_window, this);
 
163
  blackbox->saveSlitSearch(client->icon_window, this);
 
164
  reconfigure();
167
165
}
168
166
 
169
167
 
170
 
void Slit::removeClient(SlitClient *client, Bool remap) {
 
168
void Slit::removeClient(SlitClient *client, bool remap) {
171
169
  blackbox->removeSlitSearch(client->client_window);
172
170
  blackbox->removeSlitSearch(client->icon_window);
173
 
  clientList->remove(client);
 
171
  clientList.remove(client);
174
172
 
175
173
  screen->removeNetizen(client->window);
176
174
 
177
175
  if (remap && blackbox->validateWindow(client->window)) {
 
176
    XGrabServer(display);
178
177
    XSelectInput(display, frame.window, NoEventMask);
179
178
    XSelectInput(display, client->window, NoEventMask);
180
179
    XReparentWindow(display, client->window, screen->getRootWindow(),
181
 
                    client->x, client->y);
 
180
                    client->rect.x(), client->rect.y());
182
181
    XChangeSaveSet(display, client->window, SetModeDelete);
183
182
    XSelectInput(display, frame.window, SubstructureRedirectMask |
184
 
                 ButtonPressMask | EnterWindowMask | LeaveWindowMask);
185
 
    XFlush(display);
 
183
                 ButtonPressMask | EnterWindowMask | LeaveWindowMask);
 
184
    XUngrabServer(display);
186
185
  }
187
186
 
188
187
  delete client;
190
189
}
191
190
 
192
191
 
193
 
void Slit::removeClient(Window w, Bool remap) {
194
 
  blackbox->grab();
195
 
 
196
 
  Bool reconf = False;
197
 
 
198
 
  LinkedListIterator<SlitClient> it(clientList);
199
 
  for (SlitClient *tmp = it.current(); tmp; it++, tmp = it.current()) {
200
 
    if (tmp->window == w) {
201
 
      removeClient(tmp, remap);
202
 
      reconf = True;
203
 
 
204
 
      break;
205
 
    }
206
 
  }
207
 
 
208
 
  if (reconf) reconfigure();
209
 
 
210
 
  blackbox->ungrab();
 
192
struct SlitClientMatch {
 
193
  Window window;
 
194
  SlitClientMatch(Window w): window(w) {}
 
195
  inline bool operator()(const Slit::SlitClient* client) const {
 
196
    return (client->window == window);
 
197
  }
 
198
};
 
199
 
 
200
 
 
201
void Slit::removeClient(Window w, bool remap) {
 
202
  SlitClientList::iterator it = clientList.begin();
 
203
  const SlitClientList::iterator end = clientList.end();
 
204
 
 
205
  it = std::find_if(it, end, SlitClientMatch(w));
 
206
  if (it != end) {
 
207
    removeClient(*it, remap);
 
208
    reconfigure();
 
209
  }
211
210
}
212
211
 
213
212
 
214
213
void Slit::reconfigure(void) {
215
 
  frame.width = 0;
216
 
  frame.height = 0;
217
 
  LinkedListIterator<SlitClient> it(clientList);
 
214
  SlitClientList::iterator it = clientList.begin();
 
215
  const SlitClientList::iterator end = clientList.end();
218
216
  SlitClient *client;
219
217
 
 
218
  unsigned int width = 0, height = 0;
 
219
 
220
220
  switch (screen->getSlitDirection()) {
221
221
  case Vertical:
222
 
    for (client = it.current(); client; it++, client = it.current()) {
223
 
      frame.height += client->height + screen->getBevelWidth();
 
222
    for (; it != end; ++it) {
 
223
      client = *it;
 
224
      height += client->rect.height() + screen->getBevelWidth();
224
225
 
225
 
      if (frame.width < client->width)
226
 
        frame.width = client->width;
 
226
      if (width < client->rect.width())
 
227
        width = client->rect.width();
227
228
    }
228
229
 
229
 
    if (frame.width < 1)
230
 
      frame.width = 1;
 
230
    if (width < 1)
 
231
      width = 1;
231
232
    else
232
 
      frame.width += (screen->getBevelWidth() * 2);
 
233
      width += (screen->getBevelWidth() * 2);
233
234
 
234
 
    if (frame.height < 1)
235
 
      frame.height = 1;
 
235
    if (height < 1)
 
236
      height = 1;
236
237
    else
237
 
      frame.height += screen->getBevelWidth();
 
238
      height += screen->getBevelWidth();
238
239
 
239
240
    break;
240
241
 
241
242
  case Horizontal:
242
 
    for (client = it.current(); client; it++, client = it.current()) {
243
 
      frame.width += client->width + screen->getBevelWidth();
 
243
    for (; it != end; ++it) {
 
244
      client = *it;
 
245
      width += client->rect.width() + screen->getBevelWidth();
244
246
 
245
 
      if (frame.height < client->height)
246
 
        frame.height = client->height;
 
247
      if (height < client->rect.height())
 
248
        height = client->rect.height();
247
249
    }
248
250
 
249
 
    if (frame.width < 1)
250
 
      frame.width = 1;
 
251
    if (width < 1)
 
252
      width = 1;
251
253
    else
252
 
      frame.width += screen->getBevelWidth();
 
254
      width += screen->getBevelWidth();
253
255
 
254
 
    if (frame.height < 1)
255
 
      frame.height = 1;
 
256
    if (height < 1)
 
257
      height = 1;
256
258
    else
257
 
      frame.height += (screen->getBevelWidth() * 2);
 
259
      height += (screen->getBevelWidth() * 2);
258
260
 
259
261
    break;
260
262
  }
 
263
  frame.rect.setSize(width, height);
261
264
 
262
265
  reposition();
263
266
 
264
267
  XSetWindowBorderWidth(display ,frame.window, screen->getBorderWidth());
265
268
  XSetWindowBorder(display, frame.window,
266
 
                   screen->getBorderColor()->getPixel());
 
269
                   screen->getBorderColor()->pixel());
267
270
 
268
 
  if (! clientList->count())
 
271
  if (clientList.empty())
269
272
    XUnmapWindow(display, frame.window);
270
273
  else
271
274
    XMapWindow(display, frame.window);
272
275
 
273
 
  Pixmap tmp = frame.pixmap;
274
 
  BImageControl *image_ctrl = screen->getImageControl();
275
276
  BTexture *texture = &(screen->getToolbarStyle()->toolbar);
276
 
  if (texture->getTexture() == (BImage_Flat | BImage_Solid)) {
277
 
    frame.pixmap = None;
278
 
    XSetWindowBackground(display, frame.window,
279
 
                         texture->getColor()->getPixel());
280
 
  } else {
281
 
    frame.pixmap = image_ctrl->renderImage(frame.width, frame.height,
282
 
                                           texture);
 
277
  frame.pixmap = texture->render(frame.rect.width(), frame.rect.height(),
 
278
                                 frame.pixmap);
 
279
  if (! frame.pixmap)
 
280
    XSetWindowBackground(display, frame.window, texture->color().pixel());
 
281
  else
283
282
    XSetWindowBackgroundPixmap(display, frame.window, frame.pixmap);
284
 
  }
285
 
  if (tmp) image_ctrl->removeImage(tmp);
 
283
 
286
284
  XClearWindow(display, frame.window);
287
285
 
 
286
  it = clientList.begin();
 
287
 
288
288
  int x, y;
289
 
  it.reset();
290
289
 
291
290
  switch (screen->getSlitDirection()) {
292
291
  case Vertical:
293
292
    x = 0;
294
293
    y = screen->getBevelWidth();
295
294
 
296
 
    for (client = it.current(); client; it++, client = it.current()) {
297
 
      x = (frame.width - client->width) / 2;
 
295
    for (; it != end; ++it) {
 
296
      client = *it;
 
297
      x = (frame.rect.width() - client->rect.width()) / 2;
298
298
 
299
299
      XMoveResizeWindow(display, client->window, x, y,
300
 
                        client->width, client->height);
 
300
                        client->rect.width(), client->rect.height());
301
301
      XMapWindow(display, client->window);
302
302
 
303
303
      // for ICCCM compliance
304
 
      client->x = x;
305
 
      client->y = y;
 
304
      client->rect.setPos(x, y);
306
305
 
307
306
      XEvent event;
308
307
      event.type = ConfigureNotify;
312
311
      event.xconfigure.window = client->window;
313
312
      event.xconfigure.x = x;
314
313
      event.xconfigure.y = y;
315
 
      event.xconfigure.width = client->width;
316
 
      event.xconfigure.height = client->height;
 
314
      event.xconfigure.width = client->rect.width();
 
315
      event.xconfigure.height = client->rect.height();
317
316
      event.xconfigure.border_width = 0;
318
317
      event.xconfigure.above = frame.window;
319
318
      event.xconfigure.override_redirect = False;
320
319
 
321
320
      XSendEvent(display, client->window, False, StructureNotifyMask, &event);
322
321
 
323
 
      y += client->height + screen->getBevelWidth();
 
322
      y += client->rect.height() + screen->getBevelWidth();
324
323
    }
325
324
 
326
325
    break;
329
328
    x = screen->getBevelWidth();
330
329
    y = 0;
331
330
 
332
 
    for (client = it.current(); client; it++, client = it.current()) {
333
 
      y = (frame.height - client->height) / 2;
 
331
    for (; it != end; ++it) {
 
332
      client = *it;
 
333
      y = (frame.rect.height() - client->rect.height()) / 2;
334
334
 
335
335
      XMoveResizeWindow(display, client->window, x, y,
336
 
                        client->width, client->height);
 
336
                        client->rect.width(), client->rect.height());
337
337
      XMapWindow(display, client->window);
338
338
 
339
339
      // for ICCCM compliance
340
 
      client->x = x;
341
 
      client->y = y;
 
340
      client->rect.setPos(x, y);
342
341
 
343
342
      XEvent event;
344
343
      event.type = ConfigureNotify;
348
347
      event.xconfigure.window = client->window;
349
348
      event.xconfigure.x = x;
350
349
      event.xconfigure.y = y;
351
 
      event.xconfigure.width = client->width;
352
 
      event.xconfigure.height = client->height;
 
350
      event.xconfigure.width = client->rect.width();
 
351
      event.xconfigure.height = client->rect.height();
353
352
      event.xconfigure.border_width = 0;
354
353
      event.xconfigure.above = frame.window;
355
354
      event.xconfigure.override_redirect = False;
356
355
 
357
356
      XSendEvent(display, client->window, False, StructureNotifyMask, &event);
358
357
 
359
 
      x += client->width + screen->getBevelWidth();
 
358
      x += client->rect.width() + screen->getBevelWidth();
360
359
    }
361
 
 
362
360
    break;
363
361
  }
364
362
 
366
364
}
367
365
 
368
366
 
 
367
void Slit::updateStrut(void) {
 
368
  strut.top = strut.bottom = strut.left = strut.right = 0;
 
369
 
 
370
  if (! clientList.empty()) {
 
371
    // when not hidden both borders are in use, when hidden only one is
 
372
    unsigned int border_width = screen->getBorderWidth();
 
373
    if (! do_auto_hide)
 
374
      border_width *= 2;
 
375
 
 
376
    switch (screen->getSlitDirection()) {
 
377
    case Vertical:
 
378
      switch (screen->getSlitPlacement()) {
 
379
      case TopCenter:
 
380
        strut.top = getExposedHeight() + border_width;
 
381
        break;
 
382
      case BottomCenter:
 
383
        strut.bottom = getExposedHeight() + border_width;
 
384
        break;
 
385
      case TopLeft:
 
386
      case CenterLeft:
 
387
      case BottomLeft:
 
388
        strut.left = getExposedWidth() + border_width;
 
389
        break;
 
390
      case TopRight:
 
391
      case CenterRight:
 
392
      case BottomRight:
 
393
        strut.right = getExposedWidth() + border_width;
 
394
        break;
 
395
      }
 
396
      break;
 
397
    case Horizontal:
 
398
      switch (screen->getSlitPlacement()) {
 
399
      case TopCenter:
 
400
      case TopLeft:
 
401
      case TopRight:
 
402
        strut.top = frame.rect.top() + getExposedHeight() + border_width;
 
403
        break;
 
404
      case BottomCenter:
 
405
      case BottomLeft:
 
406
      case BottomRight:
 
407
        int pos;
 
408
        if (do_auto_hide)
 
409
          pos = frame.y_hidden;
 
410
        else
 
411
          pos = frame.rect.y();
 
412
        strut.bottom = (screen->getRect().bottom() - pos);
 
413
        break;
 
414
      case CenterLeft:
 
415
        strut.left = getExposedWidth() + border_width;
 
416
        break;
 
417
      case CenterRight:
 
418
        strut.right = getExposedWidth() + border_width;
 
419
        break;
 
420
      }
 
421
      break;
 
422
    }
 
423
  }
 
424
 
 
425
  // update area with new Strut info
 
426
  screen->updateAvailableArea();
 
427
}
 
428
 
 
429
 
369
430
void Slit::reposition(void) {
370
 
  // place the slit in the appropriate place
 
431
  int x = 0, y = 0;
 
432
 
371
433
  switch (screen->getSlitPlacement()) {
372
434
  case TopLeft:
373
 
    frame.x = 0;
374
 
    frame.y = 0;
375
 
    if (screen->getSlitDirection() == Vertical) {
376
 
      frame.x_hidden = screen->getBevelWidth() - screen->getBorderWidth()
377
 
                       - frame.width;
378
 
      frame.y_hidden = 0;
379
 
    } else {
380
 
      frame.x_hidden = 0;
381
 
      frame.y_hidden = screen->getBevelWidth() - screen->getBorderWidth()
382
 
                       - frame.height;
383
 
    }
384
 
    break;
385
 
 
386
435
  case CenterLeft:
387
 
    frame.x = 0;
388
 
    frame.y = (screen->getHeight() - frame.height) / 2;
 
436
  case BottomLeft:
 
437
    x = 0;
389
438
    frame.x_hidden = screen->getBevelWidth() - screen->getBorderWidth()
390
 
                     - frame.width;
391
 
    frame.y_hidden = frame.y;
392
 
    break;
393
 
 
394
 
  case BottomLeft:
395
 
    frame.x = 0;
396
 
    frame.y = screen->getHeight() - frame.height
397
 
      - (screen->getBorderWidth() * 2);
398
 
    if (screen->getSlitDirection() == Vertical) {
399
 
      frame.x_hidden = screen->getBevelWidth() - screen->getBorderWidth()
400
 
                       - frame.width;
401
 
      frame.y_hidden = frame.y;
402
 
    } else {
403
 
      frame.x_hidden = 0;
404
 
      frame.y_hidden = screen->getHeight() - screen->getBevelWidth()
405
 
                       - screen->getBorderWidth();
406
 
    }
 
439
      - frame.rect.width();
 
440
 
 
441
    if (screen->getSlitPlacement() == TopLeft)
 
442
      y = 0;
 
443
    else if (screen->getSlitPlacement() == CenterLeft)
 
444
      y = (screen->getHeight() - frame.rect.height()) / 2;
 
445
    else
 
446
      y = screen->getHeight() - frame.rect.height()
 
447
        - (screen->getBorderWidth() * 2);
 
448
 
407
449
    break;
408
450
 
409
451
  case TopCenter:
410
 
    frame.x = (screen->getWidth() - frame.width) / 2;
411
 
    frame.y = 0;
412
 
    frame.x_hidden = frame.x;
413
 
    frame.y_hidden = screen->getBevelWidth() - screen->getBorderWidth()
414
 
                     - frame.height;
415
 
    break;
416
 
 
417
452
  case BottomCenter:
418
 
    frame.x = (screen->getWidth() - frame.width) / 2;
419
 
    frame.y = screen->getHeight() - frame.height
420
 
      - (screen->getBorderWidth() * 2);
421
 
    frame.x_hidden = frame.x;
422
 
    frame.y_hidden = screen->getHeight() - screen->getBevelWidth()
423
 
                     - screen->getBorderWidth();
 
453
    x = (screen->getWidth() - frame.rect.width()) / 2;
 
454
    frame.x_hidden = x;
 
455
 
 
456
    if (screen->getSlitPlacement() == TopCenter)
 
457
      y = 0;
 
458
    else
 
459
      y = screen->getHeight() - frame.rect.height()
 
460
        - (screen->getBorderWidth() * 2);
 
461
 
424
462
    break;
425
463
 
426
464
  case TopRight:
427
 
    frame.x = screen->getWidth() - frame.width
428
 
      - (screen->getBorderWidth() * 2);
429
 
    frame.y = 0;
430
 
    if (screen->getSlitDirection() == Vertical) {
431
 
      frame.x_hidden = screen->getWidth() - screen->getBevelWidth()
432
 
                       - screen->getBorderWidth();
433
 
      frame.y_hidden = 0;
434
 
    } else {
435
 
      frame.x_hidden = frame.x;
436
 
      frame.y_hidden = screen->getBevelWidth() - screen->getBorderWidth()
437
 
                       - frame.height;
438
 
    }
439
 
    break;
440
 
 
441
465
  case CenterRight:
442
 
  default:
443
 
    frame.x = screen->getWidth() - frame.width
 
466
  case BottomRight:
 
467
    x = screen->getWidth() - frame.rect.width()
444
468
      - (screen->getBorderWidth() * 2);
445
 
    frame.y = (screen->getHeight() - frame.height) / 2;
446
469
    frame.x_hidden = screen->getWidth() - screen->getBevelWidth()
447
 
                     - screen->getBorderWidth();
448
 
    frame.y_hidden = frame.y;
449
 
    break;
450
 
 
451
 
  case BottomRight:
452
 
    frame.x = screen->getWidth() - frame.width
453
 
      - (screen->getBorderWidth() * 2);
454
 
    frame.y = screen->getHeight() - frame.height
455
 
      - (screen->getBorderWidth() * 2);
456
 
    if (screen->getSlitDirection() == Vertical) {
457
 
      frame.x_hidden = screen->getWidth() - screen->getBevelWidth()
458
 
                       - screen->getBorderWidth();
459
 
      frame.y_hidden = frame.y;
460
 
    } else {
461
 
      frame.x_hidden = frame.x;
462
 
      frame.y_hidden = screen->getHeight() - screen->getBevelWidth()
463
 
                       - screen->getBorderWidth();
464
 
    }
465
 
    break;
466
 
  }
467
 
 
468
 
  Toolbar *tbar = screen->getToolbar();
469
 
  int sw = frame.width + (screen->getBorderWidth() * 2),
470
 
      sh = frame.height + (screen->getBorderWidth() * 2),
471
 
      tw = tbar->getWidth() + screen->getBorderWidth(),
472
 
      th = tbar->getHeight() + screen->getBorderWidth();
473
 
 
474
 
  if (tbar->getX() < frame.x + sw && tbar->getX() + tw > frame.x &&
475
 
      tbar->getY() < frame.y + sh && tbar->getY() + th > frame.y) {
476
 
    if (frame.y < th) {
477
 
      frame.y += tbar->getExposedHeight();
478
 
      if (screen->getSlitDirection() == Vertical)
479
 
        frame.y_hidden += tbar->getExposedHeight();
480
 
      else
481
 
        frame.y_hidden = frame.y;
482
 
    } else {
483
 
      frame.y -= tbar->getExposedHeight();
484
 
      if (screen->getSlitDirection() == Vertical)
485
 
        frame.y_hidden -= tbar->getExposedHeight();
486
 
      else
487
 
        frame.y_hidden = frame.y;
488
 
    }
489
 
  }
 
470
      - screen->getBorderWidth();
 
471
 
 
472
    if (screen->getSlitPlacement() == TopRight)
 
473
      y = 0;
 
474
    else if (screen->getSlitPlacement() == CenterRight)
 
475
      y = (screen->getHeight() - frame.rect.height()) / 2;
 
476
    else
 
477
      y = screen->getHeight() - frame.rect.height()
 
478
        - (screen->getBorderWidth() * 2);
 
479
    break;
 
480
  }
 
481
 
 
482
  frame.rect.setPos(x, y);
 
483
 
 
484
  // we have to add the border to the rect as it is not accounted for
 
485
  Rect tbar_rect = screen->getToolbar()->getRect();
 
486
  tbar_rect.setSize(tbar_rect.width() + (screen->getBorderWidth() * 2),
 
487
                    tbar_rect.height() + (screen->getBorderWidth() * 2));
 
488
  Rect slit_rect = frame.rect;
 
489
  slit_rect.setSize(slit_rect.width() + (screen->getBorderWidth() * 2),
 
490
                    slit_rect.height() + (screen->getBorderWidth() * 2));
 
491
 
 
492
  if (slit_rect.intersects(tbar_rect)) {
 
493
    int delta = screen->getToolbar()->getExposedHeight() +
 
494
      screen->getBorderWidth();
 
495
    if (frame.rect.bottom() <= tbar_rect.bottom())
 
496
      delta = -delta;
 
497
 
 
498
    frame.rect.setY(frame.rect.y() + delta);
 
499
  }
 
500
 
 
501
  if (screen->getSlitPlacement() == TopCenter)
 
502
    frame.y_hidden = 0 - frame.rect.height() + screen->getBorderWidth() 
 
503
      + screen->getBevelWidth();
 
504
  else if (screen->getSlitPlacement() == BottomCenter)
 
505
    frame.y_hidden = screen->getHeight() - screen->getBorderWidth()
 
506
      - screen->getBevelWidth();
 
507
  else
 
508
    frame.y_hidden = frame.rect.y();
 
509
 
 
510
  updateStrut();
490
511
 
491
512
  if (hidden)
492
 
    XMoveResizeWindow(display, frame.window, frame.x_hidden,
493
 
                      frame.y_hidden, frame.width, frame.height);
 
513
    XMoveResizeWindow(display, frame.window,
 
514
                      frame.x_hidden, frame.y_hidden,
 
515
                      frame.rect.width(), frame.rect.height());
494
516
  else
495
 
    XMoveResizeWindow(display, frame.window, frame.x,
496
 
                      frame.y, frame.width, frame.height);
 
517
    XMoveResizeWindow(display, frame.window,
 
518
                      frame.rect.x(), frame.rect.y(),
 
519
                      frame.rect.width(), frame.rect.height());
497
520
}
498
521
 
499
522
 
500
523
void Slit::shutdown(void) {
501
 
  while (clientList->count())
502
 
    removeClient(clientList->first());
 
524
  while (! clientList.empty())
 
525
    removeClient(clientList.front());
503
526
}
504
527
 
505
528
 
506
 
void Slit::buttonPressEvent(XButtonEvent *e) {
 
529
void Slit::buttonPressEvent(const XButtonEvent *e) {
507
530
  if (e->window != frame.window) return;
508
531
 
509
532
  if (e->button == Button1 && (! on_top)) {
537
560
}
538
561
 
539
562
 
540
 
void Slit::enterNotifyEvent(XCrossingEvent *) {
 
563
void Slit::enterNotifyEvent(const XCrossingEvent *) {
541
564
  if (! do_auto_hide)
542
565
    return;
543
566
 
549
572
}
550
573
 
551
574
 
552
 
void Slit::leaveNotifyEvent(XCrossingEvent *) {
 
575
void Slit::leaveNotifyEvent(const XCrossingEvent *) {
553
576
  if (! do_auto_hide)
554
577
    return;
555
578
 
561
584
}
562
585
 
563
586
 
564
 
void Slit::configureRequestEvent(XConfigureRequestEvent *e) {
565
 
  blackbox->grab();
566
 
 
567
 
  if (blackbox->validateWindow(e->window)) {
568
 
    Bool reconf = False;
569
 
    XWindowChanges xwc;
570
 
 
571
 
    xwc.x = e->x;
572
 
    xwc.y = e->y;
573
 
    xwc.width = e->width;
574
 
    xwc.height = e->height;
575
 
    xwc.border_width = 0;
576
 
    xwc.sibling = e->above;
577
 
    xwc.stack_mode = e->detail;
578
 
 
579
 
    XConfigureWindow(display, e->window, e->value_mask, &xwc);
580
 
 
581
 
    LinkedListIterator<SlitClient> it(clientList);
582
 
    SlitClient *client = it.current();
583
 
    for (; client; it++, client = it.current())
584
 
      if (client->window == e->window)
585
 
        if (client->width != ((unsigned) e->width) ||
586
 
            client->height != ((unsigned) e->height)) {
587
 
          client->width = (unsigned) e->width;
588
 
          client->height = (unsigned) e->height;
589
 
 
590
 
          reconf = True;
591
 
 
592
 
          break;
593
 
        }
594
 
 
595
 
    if (reconf) reconfigure();
596
 
 
 
587
void Slit::configureRequestEvent(const XConfigureRequestEvent *e) {
 
588
  if (! blackbox->validateWindow(e->window))
 
589
    return;
 
590
 
 
591
  XWindowChanges xwc;
 
592
 
 
593
  xwc.x = e->x;
 
594
  xwc.y = e->y;
 
595
  xwc.width = e->width;
 
596
  xwc.height = e->height;
 
597
  xwc.border_width = 0;
 
598
  xwc.sibling = e->above;
 
599
  xwc.stack_mode = e->detail;
 
600
 
 
601
  XConfigureWindow(display, e->window, e->value_mask, &xwc);
 
602
 
 
603
  SlitClientList::iterator it = clientList.begin();
 
604
  const SlitClientList::iterator end = clientList.end();
 
605
  for (; it != end; ++it) {
 
606
    SlitClient *client = *it;
 
607
    if (client->window == e->window &&
 
608
        (static_cast<signed>(client->rect.width()) != e->width ||
 
609
         static_cast<signed>(client->rect.height()) != e->height)) {
 
610
      client->rect.setSize(e->width, e->height);
 
611
 
 
612
      reconfigure();
 
613
      return;
 
614
    }
597
615
  }
598
 
 
599
 
  blackbox->ungrab();
600
616
}
601
617
 
602
618
 
605
621
  if (hidden)
606
622
    XMoveWindow(display, frame.window, frame.x_hidden, frame.y_hidden);
607
623
  else
608
 
    XMoveWindow(display, frame.window, frame.x, frame.y);
 
624
    XMoveWindow(display, frame.window, frame.rect.x(), frame.rect.y());
 
625
}
 
626
 
 
627
 
 
628
void Slit::toggleAutoHide(void) {
 
629
  do_auto_hide = (do_auto_hide) ?  False : True;
 
630
 
 
631
  updateStrut();
 
632
 
 
633
  if (do_auto_hide == False && hidden) {
 
634
    // force the slit to be visible
 
635
    if (timer->isTiming()) timer->stop();
 
636
    timeout();
 
637
  }
 
638
}
 
639
 
 
640
 
 
641
void Slit::unmapNotifyEvent(const XUnmapEvent *e) {
 
642
  removeClient(e->window);
609
643
}
610
644
 
611
645
 
612
646
Slitmenu::Slitmenu(Slit *sl) : Basemenu(sl->screen) {
613
647
  slit = sl;
614
648
 
615
 
  setLabel(i18n->getMessage(SlitSet, SlitSlitTitle, "Slit"));
 
649
  setLabel(i18n(SlitSet, SlitSlitTitle, "Slit"));
616
650
  setInternalMenu();
617
651
 
618
652
  directionmenu = new Directionmenu(this);
619
653
  placementmenu = new Placementmenu(this);
620
654
 
621
 
  insert(i18n->getMessage(CommonSet, CommonDirectionTitle, "Direction"),
622
 
         directionmenu);
623
 
  insert(i18n->getMessage(CommonSet, CommonPlacementTitle, "Placement"),
624
 
         placementmenu);
625
 
  insert(i18n->getMessage(CommonSet, CommonAlwaysOnTop, "Always on top"), 1);
626
 
  insert(i18n->getMessage(CommonSet, CommonAutoHide, "Auto hide"), 2);
 
655
  insert(i18n(CommonSet, CommonDirectionTitle, "Direction"),
 
656
         directionmenu);
 
657
  insert(i18n(CommonSet, CommonPlacementTitle, "Placement"),
 
658
         placementmenu);
 
659
  insert(i18n(CommonSet, CommonAlwaysOnTop, "Always on top"), 1);
 
660
  insert(i18n(CommonSet, CommonAutoHide, "Auto hide"), 2);
627
661
 
628
662
  update();
629
663
 
638
672
}
639
673
 
640
674
 
641
 
void Slitmenu::itemSelected(int button, int index) {
 
675
void Slitmenu::itemSelected(int button, unsigned int index) {
642
676
  if (button != 1)
643
677
    return;
644
678
 
647
681
 
648
682
  switch (item->function()) {
649
683
  case 1: { // always on top
650
 
    Bool change = ((slit->isOnTop()) ?  False : True);
651
 
    slit->on_top = change;
652
 
    setItemSelected(2, change);
 
684
    slit->on_top = ((slit->isOnTop()) ?  False : True);
 
685
    setItemSelected(2, slit->on_top);
653
686
 
654
687
    if (slit->isOnTop()) slit->screen->raiseWindows((Window *) 0, 0);
655
688
    break;
656
689
  }
657
690
 
658
691
  case 2: { // auto hide
659
 
    Bool change = ((slit->doAutoHide()) ?  False : True);
660
 
    slit->do_auto_hide = change;
661
 
    setItemSelected(3, change);
 
692
    slit->toggleAutoHide();
 
693
    setItemSelected(3, slit->do_auto_hide);
662
694
 
663
695
    break;
664
696
  }
683
715
 
684
716
Slitmenu::Directionmenu::Directionmenu(Slitmenu *sm)
685
717
  : Basemenu(sm->slit->screen) {
686
 
  slitmenu = sm;
687
718
 
688
 
  setLabel(i18n->getMessage(SlitSet, SlitSlitDirection, "Slit Direction"));
 
719
  setLabel(i18n(SlitSet, SlitSlitDirection, "Slit Direction"));
689
720
  setInternalMenu();
690
721
 
691
 
  insert(i18n->getMessage(CommonSet, CommonDirectionHoriz, "Horizontal"),
692
 
         Slit::Horizontal);
693
 
  insert(i18n->getMessage(CommonSet, CommonDirectionVert, "Vertical"),
694
 
         Slit::Vertical);
 
722
  insert(i18n(CommonSet, CommonDirectionHoriz, "Horizontal"),
 
723
         Slit::Horizontal);
 
724
  insert(i18n(CommonSet, CommonDirectionVert, "Vertical"),
 
725
         Slit::Vertical);
695
726
 
696
727
  update();
697
728
 
698
 
  if (sm->slit->screen->getSlitDirection() == Slit::Horizontal)
 
729
  if (getScreen()->getSlitDirection() == Slit::Horizontal)
699
730
    setItemSelected(0, True);
700
731
  else
701
732
    setItemSelected(1, True);
702
733
}
703
734
 
704
735
 
705
 
void Slitmenu::Directionmenu::itemSelected(int button, int index) {
 
736
void Slitmenu::Directionmenu::itemSelected(int button, unsigned int index) {
706
737
  if (button != 1)
707
738
    return;
708
739
 
709
740
  BasemenuItem *item = find(index);
710
741
  if (! item) return;
711
742
 
712
 
  slitmenu->slit->screen->saveSlitDirection(item->function());
 
743
  getScreen()->saveSlitDirection(item->function());
713
744
 
714
745
  if (item->function() == Slit::Horizontal) {
715
746
    setItemSelected(0, True);
720
751
  }
721
752
 
722
753
  hide();
723
 
  slitmenu->slit->reconfigure();
 
754
  getScreen()->getSlit()->reconfigure();
724
755
}
725
756
 
726
757
 
727
758
Slitmenu::Placementmenu::Placementmenu(Slitmenu *sm)
728
759
  : Basemenu(sm->slit->screen) {
729
 
  slitmenu = sm;
730
760
 
731
 
  setLabel(i18n->getMessage(SlitSet, SlitSlitPlacement, "Slit Placement"));
 
761
  setLabel(i18n(SlitSet, SlitSlitPlacement, "Slit Placement"));
732
762
  setMinimumSublevels(3);
733
763
  setInternalMenu();
734
764
 
735
 
  insert(i18n->getMessage(CommonSet, CommonPlacementTopLeft, "Top Left"),
736
 
         Slit::TopLeft);
737
 
  insert(i18n->getMessage(CommonSet, CommonPlacementCenterLeft, "Center Left"),
738
 
         Slit::CenterLeft);
739
 
  insert(i18n->getMessage(CommonSet, CommonPlacementBottomLeft, "Bottom Left"),
740
 
         Slit::BottomLeft);
741
 
  insert(i18n->getMessage(CommonSet, CommonPlacementTopCenter, "Top Center"),
742
 
         Slit::TopCenter);
 
765
  insert(i18n(CommonSet, CommonPlacementTopLeft, "Top Left"),
 
766
         Slit::TopLeft);
 
767
  insert(i18n(CommonSet, CommonPlacementCenterLeft, "Center Left"),
 
768
         Slit::CenterLeft);
 
769
  insert(i18n(CommonSet, CommonPlacementBottomLeft, "Bottom Left"),
 
770
         Slit::BottomLeft);
 
771
  insert(i18n(CommonSet, CommonPlacementTopCenter, "Top Center"),
 
772
         Slit::TopCenter);
743
773
  insert("");
744
 
  insert(i18n->getMessage(CommonSet, CommonPlacementBottomCenter, 
745
 
                          "Bottom Center"),
746
 
         Slit::BottomCenter);
747
 
  insert(i18n->getMessage(CommonSet, CommonPlacementTopRight, "Top Right"),
748
 
         Slit::TopRight);
749
 
  insert(i18n->getMessage(CommonSet, CommonPlacementCenterRight,
750
 
                          "Center Right"),
751
 
         Slit::CenterRight);
752
 
  insert(i18n->getMessage(CommonSet, CommonPlacementBottomRight,
753
 
                          "Bottom Right"),
754
 
         Slit::BottomRight);
 
774
  insert(i18n(CommonSet, CommonPlacementBottomCenter, "Bottom Center"),
 
775
         Slit::BottomCenter);
 
776
  insert(i18n(CommonSet, CommonPlacementTopRight, "Top Right"),
 
777
         Slit::TopRight);
 
778
  insert(i18n(CommonSet, CommonPlacementCenterRight, "Center Right"),
 
779
         Slit::CenterRight);
 
780
  insert(i18n(CommonSet, CommonPlacementBottomRight, "Bottom Right"),
 
781
         Slit::BottomRight);
755
782
 
756
783
  update();
757
784
}
758
785
 
759
786
 
760
 
void Slitmenu::Placementmenu::itemSelected(int button, int index) {
 
787
void Slitmenu::Placementmenu::itemSelected(int button, unsigned int index) {
761
788
  if (button != 1)
762
789
    return;
763
790
 
764
791
  BasemenuItem *item = find(index);
765
792
  if (! (item && item->function())) return;
766
793
 
767
 
  slitmenu->slit->screen->saveSlitPlacement(item->function());
 
794
  getScreen()->saveSlitPlacement(item->function());
768
795
  hide();
769
 
  slitmenu->slit->reconfigure();
 
796
  getScreen()->getSlit()->reconfigure();
770
797
}
771
798
 
772
 
 
773
 
#endif // SLIT