Now pekwm is able to replace metacity in recent gnome releases and take over
as the window manager, it still doesn't know how to give the session up when
exiting though.
| src/ManagerWindows.cc | |
| 116 | @@ -116,14 +116,25 @@ |
| 116 | string session_name("WM_S" + Util::to_string<int>(DefaultScreen(_dpy))); |
| 117 | Atom session_atom = XInternAtom(_dpy, session_name.c_str(), false); |
| 118 | Window session_owner = XGetSelectionOwner(_dpy, session_atom); |
| 119 | |
| 120 | |
| 121 | if (session_owner && session_owner != _window) { |
| 122 | if (! replace) { |
| 123 | cerr << " *** WARNING: window manager already running." << endl; |
| 124 | return false; |
| 125 | } |
| 126 | |
| 127 | // FIXME: Validate session owner |
| 128 | XSync(_dpy, false); |
| 129 | setXErrorsIgnore(true); |
| 130 | uint errors_before = xerrors_count; |
| 131 | |
| 132 | // Select event to get notified when current owner dies. |
| 133 | XSelectInput(_dpy, session_owner, StructureNotifyMask); |
| 134 | |
| 135 | XSync(_dpy, false); |
| 136 | setXErrorsIgnore(false); |
| 137 | if (errors_before != xerrors_count) { |
| 138 | session_owner = None; |
| 139 | } |
| 140 | } |
| 141 | |
| 142 | Time timestamp = getTime(); |
| ... | |
| 177 | @@ -166,6 +177,8 @@ |
| 177 | sleep(1); |
| 178 | } |
| 179 | |
| 180 | cerr << " *** INFO: previous window manager did not exit. " << endl; |
| 181 | |
| 182 | return false; |
| 183 | } |
| 184 | |
| ... | |
| 194 | @@ -181,13 +194,14 @@ |
| 194 | |
| 195 | event.xclient.type = ClientMessage; |
| 196 | event.xclient.message_type = Atoms::getAtom(MANAGER); |
| 197 | event.xclient.display = _dpy; |
| 198 | event.xclient.window = root; |
| 199 | event.xclient.format = 32; |
| 200 | event.xclient.data.l[0] = timestamp; |
| 201 | event.xclient.data.l[1] = session_atom; |
| 202 | event.xclient.data.l[2] = _window; |
| 203 | event.xclient.data.l[3] = 0; |
| 191 | |
| 205 | |
| 206 | XSendEvent(_dpy, root, false, SubstructureNotifyMask, &event); |
| 207 | } |
| 208 | |
| ... | |
| 219 | @@ -205,9 +219,21 @@ |
| 219 | _gm.width = PScreen::instance()->getWidth(); |
| 220 | _gm.height = PScreen::instance()->getHeight(); |
| 221 | |
| 222 | |
| 223 | XSync(_dpy, false); |
| 224 | setXErrorsIgnore(true); |
| 225 | uint errors_before = xerrors_count; |
| 226 | |
| 227 | // Select window events |
| 228 | XSelectInput(dpy, _window, RootWO::EVENT_MASK); |
| 229 | |
| 230 | XSync(_dpy, false); |
| 231 | setXErrorsIgnore(false); |
| 232 | if (errors_before != xerrors_count) { |
| 233 | cerr << "pekwm: root window unavailable, can't start!" << endl; |
| 234 | exit(1); |
| 235 | } |
| 236 | |
| 237 | // Set hits on the hint window, these are not updated so they are |
| 238 | // set in the constructor. |
| 239 | AtomUtil::setLong(_window, Atoms::getAtom(NET_WM_PID), static_cast<long>(getpid())); |
| ... | |
| src/WindowManager.cc | |
| 143 | @@ -143,27 +143,6 @@ |
| 143 | break; |
| 144 | } |
| 145 | } |
| 146 | |
| 147 | /** |
| 148 | * XError handler, prints error. |
| 149 | */ |
| 150 | static int |
| 151 | handleXError(Display *dpy, XErrorEvent *e) |
| 152 | { |
| 153 | if ((e->error_code == BadAccess) && |
| 154 | (e->resourceid == (RootWindow(dpy, DefaultScreen(dpy))))) { |
| 155 | cerr << "pekwm: root window unavailable, can't start!" << endl; |
| 156 | exit(1); |
| 157 | #ifdef DEBUG |
| 158 | } else { |
| 159 | char error_buf[256]; |
| 160 | XGetErrorText(dpy, e->error_code, error_buf, 256); |
| 161 | |
| 162 | cerr << "XError: " << error_buf << " id: " << e->resourceid << endl; |
| 163 | #endif // DEBUG |
| 164 | } |
| 165 | return 0; |
| 166 | } |
| 167 | |
| 168 | } // extern "C" |
| 169 | |
| ... | |
| 364 | @@ -385,7 +364,6 @@ |
| 364 | << getenv("DISPLAY") << endl; |
| 365 | exit(1); |
| 366 | } |
| 388 | XSetErrorHandler(handleXError); |
| 368 | |
| 369 | // Setup screen, init atoms and claim the display. |
| 370 | _screen = new PScreen(dpy, _config->isHonourRandr()); |
| ... | |
| src/PScreen.cc | |
| 30 | @@ -30,6 +30,12 @@ |
| 30 | #endif // HAVE_XRANDR |
| 31 | #include <X11/keysym.h> // For XK_ entries |
| 32 | #include <sys/select.h> |
| 33 | |
| 34 | #ifdef DEBUG |
| 35 | bool xerrors_ignore = false; |
| 36 | #endif // DEBUG |
| 37 | |
| 38 | unsigned int xerrors_count = 0; |
| 39 | } |
| 40 | |
| 41 | #include "PScreen.hh" |
| ... | |
| 58 | @@ -52,6 +58,30 @@ |
| 58 | |
| 59 | PScreen* PScreen::_instance = 0; |
| 60 | |
| 61 | |
| 62 | extern "C" { |
| 63 | /** |
| 64 | * XError handler, prints error. |
| 65 | */ |
| 66 | static int |
| 67 | handleXError(Display *dpy, XErrorEvent *ev) |
| 68 | { |
| 69 | ++xerrors_count; |
| 70 | |
| 71 | #ifdef DEBUG |
| 72 | if (xerrors_ignore) { |
| 73 | return 0; |
| 74 | } |
| 75 | |
| 76 | char error_buf[256]; |
| 77 | XGetErrorText(dpy, ev->error_code, error_buf, 256); |
| 78 | cerr << "XError: " << error_buf << " id: " << ev->resourceid << endl; |
| 79 | #endif // DEBUG |
| 80 | |
| 81 | return 0; |
| 82 | } |
| 83 | } |
| 84 | |
| 85 | //! @brief PScreen::Visual constructor. |
| 86 | //! @param x_visual X Visual to wrap. |
| 87 | PScreen::PVisual::PVisual(Visual *x_visual) : _x_visual(x_visual), |
| ... | |
| 132 | @@ -102,6 +132,8 @@ |
| 132 | } |
| 133 | _instance = this; |
| 134 | |
| 135 | XSetErrorHandler(handleXError); |
| 136 | |
| 137 | XGrabServer(_dpy); |
| 138 | |
| 139 | _fd = ConnectionNumber(dpy); |
| ... | |
| src/PScreen.hh | |
| 21 | @@ -21,6 +21,16 @@ |
| 21 | #ifdef HAVE_XINERAMA |
| 22 | #include <X11/extensions/Xinerama.h> |
| 23 | #endif // HAVE_XINERAMA |
| 24 | |
| 25 | extern bool xerrors_ignore; /**< If true, ignore X errors. */ |
| 26 | extern unsigned int xerrors_count; /**< Number of X errors occured. */ |
| 27 | |
| 28 | #ifdef DEBUG |
| 29 | #define setXErrorsIgnore(X) xerrors_ignore = (X) |
| 30 | #else // ! DEBUG |
| 31 | #define setXErrorsIgnore(X) |
| 32 | #endif // DEBUG |
| 33 | |
| 34 | } |
| 35 | |
| 36 | #include <vector> |
| ... | |
| src/main.cc | |
| 92 | @@ -92,6 +92,8 @@ |
| 92 | setenv("DISPLAY", argv[++i], 1); |
| 93 | } else if ((strcmp("--config", argv[i]) == 0) && ((i + 1) < argc)) { |
| 94 | config_file = argv[++i]; |
| 95 | } else if (strcmp("--replace", argv[i]) == 0) { |
| 96 | replace = true; |
| 97 | } else if (strcmp("--version", argv[i]) == 0) { |
| 98 | Info::printVersion(); |
| 99 | exit(0); |
| ... | |
| 103 | @@ -101,8 +103,6 @@ |
| 103 | } else if (strcmp("--help", argv[i]) || ! strcmp("-h", argv[i]) == 0) { |
| 104 | Info::printUsage(); |
| 105 | exit(0); |
| 104 | } else if (strcmp("--replace", argv[i]) == 0) { |
| 105 | replace = true; |
| 108 | } |
| 109 | } |
| 110 | |
| ... | |