76 lines
2.0 KiB
D
76 lines
2.0 KiB
D
|
|
module patch.st_embedder;
|
||
|
|
|
||
|
|
import deimos.X11.X : Window, CurrentTime, RevertToParent;
|
||
|
|
import deimos.X11.X : PropertyChangeMask, StructureNotifyMask, EnterWindowMask;
|
||
|
|
import deimos.X11.X : CWWidth, CWHeight, ClientMessage, NoEventMask;
|
||
|
|
import deimos.X11.Xlib : XReparentWindow, XSelectInput, XMapWindow, XConfigureWindow;
|
||
|
|
import deimos.X11.Xlib : XSetInputFocus, XSendEvent, XEvent, XWindowChanges;
|
||
|
|
|
||
|
|
// Define missing constants
|
||
|
|
enum False = 0;
|
||
|
|
|
||
|
|
import patches : isPatchEnabled;
|
||
|
|
import st : xw;
|
||
|
|
|
||
|
|
// Import from st module
|
||
|
|
extern(C) extern __gshared {
|
||
|
|
struct Win {
|
||
|
|
int w, h;
|
||
|
|
}
|
||
|
|
Win win;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Import these functions from x module
|
||
|
|
import x : visibility, focus;
|
||
|
|
|
||
|
|
static if (isPatchEnabled!"ST_EMBEDDER_PATCH") {
|
||
|
|
enum {
|
||
|
|
XEMBED_EMBEDDED_NOTIFY = 0
|
||
|
|
}
|
||
|
|
|
||
|
|
static Window embed;
|
||
|
|
|
||
|
|
void createnotify(XEvent* e) {
|
||
|
|
XWindowChanges wc;
|
||
|
|
|
||
|
|
if (embed || e.xcreatewindow.override_redirect)
|
||
|
|
return;
|
||
|
|
|
||
|
|
embed = e.xcreatewindow.window;
|
||
|
|
|
||
|
|
XReparentWindow(xw.dpy, embed, xw.win, 0, 0);
|
||
|
|
XSelectInput(xw.dpy, embed, PropertyChangeMask | StructureNotifyMask | EnterWindowMask);
|
||
|
|
|
||
|
|
XMapWindow(xw.dpy, embed);
|
||
|
|
sendxembed(XEMBED_EMBEDDED_NOTIFY, 0, xw.win, 0);
|
||
|
|
|
||
|
|
wc.width = win.w;
|
||
|
|
wc.height = win.h;
|
||
|
|
XConfigureWindow(xw.dpy, embed, CWWidth | CWHeight, &wc);
|
||
|
|
|
||
|
|
XSetInputFocus(xw.dpy, embed, RevertToParent, CurrentTime);
|
||
|
|
}
|
||
|
|
|
||
|
|
void destroynotify(XEvent* e) {
|
||
|
|
visibility(e);
|
||
|
|
if (embed == e.xdestroywindow.window) {
|
||
|
|
focus(e);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void sendxembed(long msg, long detail, long d1, long d2) {
|
||
|
|
XEvent e;
|
||
|
|
e = XEvent.init;
|
||
|
|
|
||
|
|
e.xclient.window = embed;
|
||
|
|
e.xclient.type = ClientMessage;
|
||
|
|
e.xclient.message_type = xw.xembed;
|
||
|
|
e.xclient.format = 32;
|
||
|
|
e.xclient.data.l[0] = CurrentTime;
|
||
|
|
e.xclient.data.l[1] = msg;
|
||
|
|
e.xclient.data.l[2] = detail;
|
||
|
|
e.xclient.data.l[3] = d1;
|
||
|
|
e.xclient.data.l[4] = d2;
|
||
|
|
XSendEvent(xw.dpy, embed, False, NoEventMask, &e);
|
||
|
|
}
|
||
|
|
}
|