]> icculus.org git repositories - dana/openbox.git/blob - src/frame.cc
WINDOWS GET FRAMES FRAME SHOW UP THEY WORK HUZZAH SOON THEYLL BE LIKE OLD TIMES!
[dana/openbox.git] / src / frame.cc
1 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
2
3 #ifdef HAVE_CONFIG_H
4 # include "../config.h"
5 #endif
6
7 #include "frame.hh"
8 #include "client.hh"
9 #include "otk/display.hh"
10
11 namespace ob {
12
13 OBFrame::OBFrame(const OBClient *client, const otk::Style *style)
14   : _client(client),
15     _screen(otk::OBDisplay::screenInfo(client->screen()))
16 {
17   assert(client);
18   assert(style);
19   
20   _style = 0;
21   loadStyle(style);
22
23   _window = createFrame();
24   assert(_window);
25
26   grabClient();
27 }
28
29
30 OBFrame::~OBFrame()
31 {
32   releaseClient(false);
33 }
34
35
36 void OBFrame::loadStyle(const otk::Style *style)
37 {
38   assert(style);
39
40   // if a style was previously set, then 'replace' is true, cause we're
41   // replacing a style
42   // NOTE: if this is false, then DO NOT DO SHIT WITH _window, it doesnt exist
43   bool replace = (_style);
44
45   if (replace) {
46     // XXX: do shit here whatever
47   }
48   
49   _style = style;
50
51   // XXX: load shit like this from the style!
52   _size.left = _size.top = _size.bottom = _size.right = 2;
53
54   if (replace) {
55     XSetWindowBorderWidth(otk::OBDisplay::display, _window,
56                           _style->getBorderWidth());
57
58     // XXX: make everything redraw
59   }
60 }
61
62
63 void OBFrame::resize()
64 {
65   XResizeWindow(otk::OBDisplay::display, _window,
66                 _size.left + _size.right + _client->area().width(),
67                 _size.top + _size.bottom + _client->area().height());
68   // XXX: more is gunna have to happen here
69 }
70
71
72 void OBFrame::shape()
73 {
74   // XXX: if shaped, shape the frame to the client..
75 }
76
77
78 void OBFrame::grabClient()
79 {
80   
81   XGrabServer(otk::OBDisplay::display);
82
83   // select the event mask on the frame
84   XSelectInput(otk::OBDisplay::display, _window, SubstructureRedirectMask);
85
86   // reparent the client to the frame
87   XSelectInput(otk::OBDisplay::display, _client->window(),
88                OBClient::event_mask & ~StructureNotifyMask);
89   XReparentWindow(otk::OBDisplay::display, _client->window(), _window, 0, 0);
90   XSelectInput(otk::OBDisplay::display, _client->window(),
91                OBClient::event_mask);
92
93   // raise the client above the frame
94   XRaiseWindow(otk::OBDisplay::display, _client->window());
95   // map the client so it maps when the frame does
96   XMapWindow(otk::OBDisplay::display, _client->window());
97   
98   XUngrabServer(otk::OBDisplay::display);
99
100   resize();
101   shape();
102 }
103
104
105 void OBFrame::releaseClient(bool remap)
106 {
107   // check if the app has already reparented its window to the root window
108   XEvent ev;
109   if (XCheckTypedWindowEvent(otk::OBDisplay::display, _client->window(),
110                              ReparentNotify, &ev)) {
111     remap = true; // XXX: why do we remap the window if they already
112                   // reparented to root?
113   } else {
114     // according to the ICCCM - if the client doesn't reparent to
115     // root, then we have to do it for them
116     XReparentWindow(otk::OBDisplay::display, _client->window(),
117                     _screen->getRootWindow(),
118                     _client->area().x(), _client->area().y());
119   }
120
121   // if we want to remap the window, do so now
122   if (remap)
123     XMapWindow(otk::OBDisplay::display, _client->window());
124 }
125
126
127 Window OBFrame::createFrame()
128 {
129   XSetWindowAttributes attrib_create;
130   unsigned long create_mask = CWBackPixmap | CWBorderPixel | CWColormap |
131                               CWOverrideRedirect | CWEventMask;
132
133   attrib_create.background_pixmap = None;
134   attrib_create.colormap = _screen->getColormap();
135   attrib_create.override_redirect = True;
136   attrib_create.event_mask = EnterWindowMask | LeaveWindowMask | ButtonPress;
137   /*
138     We catch button presses because other wise they get passed down to the
139     root window, which will then cause root menus to show when you click the
140     window's frame.
141   */
142
143   return XCreateWindow(otk::OBDisplay::display, _screen->getRootWindow(),
144                        0, 0, 1, 1, _style->getBorderWidth(),
145                        _screen->getDepth(), InputOutput, _screen->getVisual(),
146                        create_mask, &attrib_create);
147 }
148
149 }