all repos — openbox @ bdc491ccfe71ce29a5a1ea813da4b1c66e2fa330

openbox fork - make it a bit more like ryudo

src/rootwindow.cc (raw)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-

#ifdef HAVE_CONFIG_H
# include "../config.h"
#endif

#include "rootwindow.hh"
#include "openbox.hh"
#include "screen.hh"
#include "otk/display.hh"

namespace ob {

OBRootWindow::OBRootWindow(int screen)
  : _info(otk::OBDisplay::screenInfo(screen))
{
  updateDesktopNames();

  Openbox::instance->registerHandler(_info->getRootWindow(), this);
}


OBRootWindow::~OBRootWindow()
{
}


void OBRootWindow::updateDesktopNames()
{
  const int numWorkspaces = 1; // XXX: change this to the number of workspaces!

  const otk::OBProperty *property = Openbox::instance->property();

  unsigned long num = (unsigned) -1;
  
  if (!property->get(_info->getRootWindow(),
                     otk::OBProperty::net_desktop_names,
                     otk::OBProperty::utf8, &num, &_names))
    _names.clear();
  for (int i = 0; i < numWorkspaces; ++i)
    if (i <= static_cast<int>(_names.size()))
      _names.push_back("Unnamed workspace");
}


void OBRootWindow::propertyHandler(const XPropertyEvent &e)
{
  otk::OtkEventHandler::propertyHandler(e);

  const otk::OBProperty *property = Openbox::instance->property();

  // compress changes to a single property into a single change
  XEvent ce;
  while (XCheckTypedEvent(otk::OBDisplay::display, e.type, &ce)) {
    // XXX: it would be nice to compress ALL changes to a property, not just
    //      changes in a row without other props between.
    if (ce.xproperty.atom != e.atom) {
      XPutBackEvent(otk::OBDisplay::display, &ce);
      break;
    }
  }

  if (e.atom == property->atom(otk::OBProperty::net_desktop_names)) 
    updateDesktopNames();
}


void OBRootWindow::clientMessageHandler(const XClientMessageEvent &e)
{
  otk::OtkEventHandler::clientMessageHandler(e);

  if (e.format != 32) return;

  //const otk::OBProperty *property = Openbox::instance->property();
  
  // XXX: so many client messages to handle here!
}


void OBRootWindow::setDesktopName(int i, const std::string &name)
{
  const int numWorkspaces = 1; // XXX: change this to the number of workspaces!
  assert(i >= 0);
  assert(i < numWorkspaces); 

  const otk::OBProperty *property = Openbox::instance->property();
  
  otk::OBProperty::StringVect newnames = _names;
  newnames[i] = name;
  property->set(_info->getRootWindow(), otk::OBProperty::net_desktop_names,
                otk::OBProperty::utf8, newnames);
}


void OBRootWindow::mapRequestHandler(const XMapRequestEvent &e)
{
#ifdef    DEBUG
  printf("MapRequest for 0x%lx\n", e.window);
#endif // DEBUG

  OBClient *client = Openbox::instance->findClient(e.window);

  printf("Client: %lx\n", client);
  
  if (client) {
    printf("found client\n");
    // XXX: uniconify and/or unshade the window
  } else {
    Openbox::instance->screen(_info->getScreenNumber())->
      manageWindow(e.window);
  }
}


#include <stdio.h>
void OBRootWindow::configureRequestHandler(const XConfigureRequestEvent &e)
{
  OtkEventHandler::configureRequestHandler(e);

  // when configure requests come to the root window, just pass them on
  XWindowChanges xwc;

  xwc.x = e.x;
  xwc.y = e.y;
  xwc.width = e.width;
  xwc.height = e.height;
  xwc.border_width = e.border_width;
  xwc.sibling = e.above;
  xwc.stack_mode = e.detail;

  XConfigureWindow(otk::OBDisplay::display, e.window,
                   e.value_mask, &xwc);
}


}