src/frame.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 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*- #ifdef HAVE_CONFIG_H # include "../config.h" #endif #include "frame.hh" #include "client.hh" #include "otk/display.hh" namespace ob { OBFrame::OBFrame(const OBClient *client, const otk::Style *style) : _client(client), _screen(otk::OBDisplay::screenInfo(client->screen())) { assert(client); assert(style); _style = 0; loadStyle(style); _window = createFrame(); assert(_window); grabClient(); } OBFrame::~OBFrame() { releaseClient(false); } void OBFrame::loadStyle(const otk::Style *style) { assert(style); // if a style was previously set, then 'replace' is true, cause we're // replacing a style // NOTE: if this is false, then DO NOT DO SHIT WITH _window, it doesnt exist bool replace = (_style); if (replace) { // XXX: do shit here whatever } _style = style; // XXX: load shit like this from the style! _size.left = _size.top = _size.bottom = _size.right = 2; if (replace) { resize(); XSetWindowBorderWidth(otk::OBDisplay::display, _window, _style->getBorderWidth()); XMoveWindow(otk::OBDisplay::display, _client->window(), _size.left, _size.top); // XXX: make everything redraw } } void OBFrame::resize() { XResizeWindow(otk::OBDisplay::display, _window, _size.left + _size.right + _client->area().width(), _size.top + _size.bottom + _client->area().height()); // XXX: more is gunna have to happen here } void OBFrame::shape() { // XXX: if shaped, shape the frame to the client.. } void OBFrame::grabClient() { XGrabServer(otk::OBDisplay::display); // select the event mask on the frame XSelectInput(otk::OBDisplay::display, _window, SubstructureRedirectMask); // reparent the client to the frame XSelectInput(otk::OBDisplay::display, _client->window(), OBClient::event_mask & ~StructureNotifyMask); XReparentWindow(otk::OBDisplay::display, _client->window(), _window, _size.left, _size.top); XSelectInput(otk::OBDisplay::display, _client->window(), OBClient::event_mask); // raise the client above the frame XRaiseWindow(otk::OBDisplay::display, _client->window()); // map the client so it maps when the frame does XMapWindow(otk::OBDisplay::display, _client->window()); XUngrabServer(otk::OBDisplay::display); resize(); shape(); } void OBFrame::releaseClient(bool remap) { // check if the app has already reparented its window to the root window XEvent ev; if (XCheckTypedWindowEvent(otk::OBDisplay::display, _client->window(), ReparentNotify, &ev)) { remap = true; // XXX: why do we remap the window if they already // reparented to root? } else { // according to the ICCCM - if the client doesn't reparent to // root, then we have to do it for them XReparentWindow(otk::OBDisplay::display, _client->window(), _screen->getRootWindow(), _client->area().x(), _client->area().y()); } // if we want to remap the window, do so now if (remap) XMapWindow(otk::OBDisplay::display, _client->window()); } Window OBFrame::createFrame() { XSetWindowAttributes attrib_create; unsigned long create_mask = CWBackPixmap | CWBorderPixel | CWColormap | CWOverrideRedirect | CWEventMask; attrib_create.background_pixmap = None; attrib_create.colormap = _screen->getColormap(); attrib_create.override_redirect = True; attrib_create.event_mask = EnterWindowMask | LeaveWindowMask | ButtonPress; /* We catch button presses because other wise they get passed down to the root window, which will then cause root menus to show when you click the window's frame. */ return XCreateWindow(otk::OBDisplay::display, _screen->getRootWindow(), 0, 0, 1, 1, _style->getBorderWidth(), _screen->getDepth(), InputOutput, _screen->getVisual(), create_mask, &attrib_create); } } |