spmenu/libs/x11/client.c

148 lines
4 KiB
C
Raw Normal View History

2023-05-14 00:21:16 +02:00
/* See LICENSE file for copyright and license details. */
2023-05-23 22:14:24 +02:00
void hexconv(const char *hex, unsigned short *r, unsigned short *g, unsigned short *b) {
unsigned int col;
2023-03-31 12:42:15 +02:00
sscanf(hex, "#%06X", &col);
2023-05-21 23:40:19 +02:00
*r = (col >> 16) & 0xFF;
*g = (col >> 8) & 0xFF;
*b = col & 0xFF;
2023-03-08 17:20:32 +01:00
}
void create_window_x11(int x, int y, int w, int h) {
XSetWindowAttributes swa;
swa.override_redirect = managed ? False : True;
2023-05-08 23:00:45 +02:00
swa.background_pixel = 0;
2023-06-23 03:38:21 +02:00
swa.colormap = x11.cmap;
2023-05-08 23:00:45 +02:00
swa.event_mask =
2023-03-31 12:42:15 +02:00
ExposureMask | // mapping the drawing
KeyPressMask | // keypresses
VisibilityChangeMask | // whether or not client is visible
ButtonPressMask | // see buttonpress in libs/mouse.c for usage
PointerMotionMask; // we need pointer for selecting entries using the mouse
2023-03-12 21:03:35 +01:00
// create client
win = XCreateWindow(dpy, root, x, y, w, h, borderwidth,
2023-06-23 03:38:21 +02:00
x11.depth, InputOutput, x11.visual,
2023-05-08 23:00:45 +02:00
CWOverrideRedirect|CWBackPixel|CWBorderPixel|CWColormap|CWEventMask, &swa);
2023-03-12 21:03:35 +01:00
return;
}
void set_window_x11(void) {
XColor col;
XClassHint ch = { class, class };
unsigned short r;
unsigned short g;
unsigned short b;
hexconv(col_border, &r, &g, &b);
col.red = r << 8;
col.green = g << 8;
col.blue = b << 8;
2023-06-23 03:38:21 +02:00
if (!XAllocColor(dpy, x11.cmap, &col)) {
die("spmenu: failed to allocate xcolor");
}
2023-03-31 12:42:15 +02:00
// set border and class
XSetWindowBorder(dpy, win, col.pixel);
2023-05-08 23:00:45 +02:00
XSetClassHint(dpy, win, &ch);
return;
}
void set_prop_x11(void) {
2023-05-21 23:40:19 +02:00
// set properties indicating what spmenu handles
clip = XInternAtom(dpy, "CLIPBOARD", False);
utf8 = XInternAtom(dpy, "UTF8_STRING", False);
types = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False);
// set dock property
if (dockproperty) {
dock = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DOCK", False);
XChangeProperty(dpy, win, types, XA_ATOM, 32, PropModeReplace, (unsigned char *) &dock, 1); // set dock property
}
}
2023-03-13 22:45:04 +01:00
void resizeclient_x11(void) {
2023-04-17 18:58:34 +02:00
int x, y;
struct item *item;
2023-05-21 23:52:28 +02:00
int ic = 0; // item count
// walk through all items
for (item = items; item && item->text; item++)
2023-05-21 23:52:28 +02:00
ic++;
2023-03-13 22:45:04 +01:00
2023-08-17 14:56:37 +02:00
lines = MAX(MIN(ic, MAX(lines, 0)), minlines);
2023-08-07 06:37:38 +02:00
#if IMAGE
2023-06-23 03:38:21 +02:00
img.setlines = lines;
2023-03-13 22:45:04 +01:00
2023-03-31 12:42:15 +02:00
// resize client to image height
if (image) resizetoimageheight(img.imageheight);
2023-05-08 23:00:45 +02:00
#endif
2023-03-13 22:45:04 +01:00
2023-06-11 16:46:36 +02:00
get_mh();
2023-03-13 22:45:04 +01:00
if (hideprompt && hideinput && hidemode && hidematchcount && hidecaps) {
2023-06-23 03:38:21 +02:00
sp.mh -= sp.bh;
}
if (menuposition == 2) { // centered
2023-07-14 01:54:48 +02:00
sp.mw = MIN(MAX(max_textw() + sp.promptw, centerwidth), mo.output_width);
x = (mo.output_width - sp.mw) / 2 + xpos;
y = (mo.output_height - sp.mh) / 2 - ypos;
} else { // top or bottom
x = xpos;
y = menuposition ? (-ypos) : (mo.output_height - sp.mh - ypos);
sp.mw = (menuwidth > 0 ? menuwidth : mo.output_width);
2023-05-08 23:00:45 +02:00
}
2023-04-17 18:58:34 +02:00
2023-06-23 03:38:21 +02:00
XMoveResizeWindow(dpy, win, x + sp.sp, y + sp.vp, sp.mw - 2 * sp.sp - borderwidth * 2, sp.mh);
draw_resize(draw, sp.mw - 2 * sp.sp - borderwidth * 2, sp.mh);
2023-03-13 22:45:04 +01:00
}
void xinitvisual(void) {
XVisualInfo *infos;
XRenderPictFormat *fmt;
int nitems;
int i;
// visual properties
XVisualInfo tpl = {
2023-06-23 03:38:21 +02:00
.screen = x11.screen,
.depth = 32,
.class = TrueColor
};
long masks = VisualScreenMask | VisualDepthMask | VisualClassMask;
infos = XGetVisualInfo(dpy, masks, &tpl, &nitems);
2023-06-23 03:38:21 +02:00
x11.visual = NULL;
// create colormap
for(i = 0; i < nitems; i ++) {
fmt = XRenderFindVisualFormat(dpy, infos[i].visual);
if (fmt->type == PictTypeDirect && fmt->direct.alphaMask) {
2023-06-23 03:38:21 +02:00
x11.visual = infos[i].visual;
x11.depth = infos[i].depth;
x11.cmap = XCreateColormap(dpy, root, x11.visual, AllocNone);
x11.useargb = 1;
break;
}
}
XFree(infos);
// no alpha, reset to default
2023-06-23 03:38:21 +02:00
if (!x11.visual || !alpha) {
x11.visual = DefaultVisual(dpy, x11.screen);
x11.depth = DefaultDepth(dpy, x11.screen);
x11.cmap = DefaultColormap(dpy, x11.screen);
}
}