Added potential fixes for KDE
This commit is contained in:
4
Makefile
4
Makefile
@@ -4,9 +4,9 @@ obj = $(src:.c=.o)
|
||||
# Build type parameter
|
||||
|
||||
ifeq ($(BUILD),debug)
|
||||
CFLAGS_BUILD = -O0 -ggdb -Wall -fsanitize=address -fno-omit-frame-pointer -fno-optimize-sibling-calls
|
||||
CFLAGS_BUILD = -O0 -ggdb -Wall #-fsanitize=address -fno-omit-frame-pointer -fno-optimize-sibling-calls
|
||||
GLAD_GEN = c-debug
|
||||
ASAN = -lasan
|
||||
# ASAN = -lasan
|
||||
else
|
||||
CFLAGS_BUILD = -O2 -march=native
|
||||
GLAD_GEN = c
|
||||
|
||||
@@ -132,6 +132,7 @@ static void get_pos (GLFWwindow* w, int* x, int* y) { glfwGetWindowPo
|
||||
static double get_time (GLFWwindow* w) { return glfwGetTime(); }
|
||||
static void set_time (GLFWwindow* w, double time) { glfwSetTime(time); }
|
||||
static void set_swap (int i) { glfwSwapInterval(i); }
|
||||
static void raise (GLFWwindow* w) { glfwShowWindow(w); }
|
||||
|
||||
WCB_ATTACH("glfw", wcb_glfw);
|
||||
|
||||
|
||||
51
glx_wcb.c
51
glx_wcb.c
@@ -176,6 +176,8 @@ struct glxwin {
|
||||
bool should_close;
|
||||
};
|
||||
|
||||
static Atom ATOM__MOTIF_WM_HINTS, ATOM_WM_DELETE_WINDOW, ATOM_WM_PROTOCOLS, ATOM__NET_ACTIVE_WINDOW;
|
||||
|
||||
static void init(void) {
|
||||
display = XOpenDisplay(NULL);
|
||||
if (!display) {
|
||||
@@ -210,6 +212,8 @@ static void init(void) {
|
||||
}
|
||||
|
||||
#define resolve(name) do { name = (typeof(name)) resolve_f(#name); } while (0)
|
||||
#define intern(name, only_if_exists) \
|
||||
do { ATOM_##name = XInternAtom(display, #name, only_if_exists); } while (0)
|
||||
|
||||
resolve(glXChooseFBConfig);
|
||||
resolve(glXGetVisualFromFBConfig);
|
||||
@@ -219,6 +223,12 @@ static void init(void) {
|
||||
resolve(glXGetProcAddressARB);
|
||||
resolve(glXSwapBuffers);
|
||||
|
||||
intern(_MOTIF_WM_HINTS, false);
|
||||
intern(WM_DELETE_WINDOW, true);
|
||||
intern(WM_PROTOCOLS, true);
|
||||
intern(_NET_ACTIVE_WINDOW, false);
|
||||
|
||||
#undef intern
|
||||
#undef resolve
|
||||
}
|
||||
|
||||
@@ -233,9 +243,7 @@ static void apply_decorations(Window w) {
|
||||
hints.flags = 2;
|
||||
hints.decorations = 0;
|
||||
|
||||
Atom motif = XInternAtom(display, "_MOTIF_WM_HINTS", false);
|
||||
|
||||
XChangeProperty(display, w, motif, motif, 32, PropModeReplace,
|
||||
XChangeProperty(display, w, ATOM__MOTIF_WM_HINTS, ATOM__MOTIF_WM_HINTS, 32, PropModeReplace,
|
||||
(unsigned char*) &hints, sizeof(hints) / sizeof(long));
|
||||
}
|
||||
}
|
||||
@@ -311,11 +319,11 @@ static void* create_and_bind(const char* name, const char* class,
|
||||
vi = glXGetVisualFromFBConfig(display, config);
|
||||
|
||||
attr.colormap = XCreateColormap(display, DefaultRootWindow(display), vi->visual, AllocNone);
|
||||
attr.event_mask = ExposureMask | KeyPressMask | StructureNotifyMask;
|
||||
attr.event_mask = ExposureMask | KeyPressMask | StructureNotifyMask | PropertyChangeMask;
|
||||
attr.background_pixmap = None;
|
||||
attr.border_pixel = 0;
|
||||
|
||||
if (!(w->w = XCreateWindow(display, DefaultRootWindow(display),
|
||||
if (!(w->w = XCreateWindow(display, *xwin_get_desktop_layer(&wcb_glx),
|
||||
x, y, d, h, 0,
|
||||
vi->depth, InputOutput, vi->visual,
|
||||
CWColormap | CWEventMask | CWBackPixmap | CWBorderPixel,
|
||||
@@ -346,8 +354,7 @@ static void* create_and_bind(const char* name, const char* class,
|
||||
|
||||
XStoreName(display, w->w, name);
|
||||
|
||||
Atom dwin = XInternAtom(display, "WM_DELETE_WINDOW", false);
|
||||
XSetWMProtocols(display, w->w, &dwin, 1);
|
||||
XSetWMProtocols(display, w->w, &ATOM_WM_DELETE_WINDOW, 1);
|
||||
|
||||
// XReparentWindow(display, w->w, DefaultRootWindow(display), 0, 0);
|
||||
|
||||
@@ -389,9 +396,34 @@ static void* create_and_bind(const char* name, const char* class,
|
||||
|
||||
if (glXSwapIntervalEXT) glXSwapIntervalEXT(display, drawable, swap);
|
||||
|
||||
// XSelectInput(display, DefaultRootWindow(display), VisibilityChangeMask | PropertyChangeMask);
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
static void raise(struct glxwin* w) {
|
||||
XClientMessageEvent ev = {
|
||||
.type = ClientMessage,
|
||||
.serial = 0,
|
||||
.send_event = true,
|
||||
.display = display,
|
||||
.window = w->w,
|
||||
.message_type = ATOM__NET_ACTIVE_WINDOW,
|
||||
.format = 32,
|
||||
.data = { .l = {
|
||||
[0] = 1, /* source indication -- `1` when coming from an application */
|
||||
[1] = 0, /* timestamp -- `0` to (attempt to) ignore */
|
||||
[2] = w->w /* requestor's currently active window -- `0` for none */
|
||||
}
|
||||
}
|
||||
};
|
||||
/* Send the client message as defined by EWMH standards (usually works) */
|
||||
XSendEvent(display, DefaultRootWindow(display), false, StructureNotifyMask, (XEvent*) &ev);
|
||||
/* Raise the client in the X11 stacking order (sometimes works, can be blocked by the WM) */
|
||||
XRaiseWindow(display, w->w);
|
||||
XFlush(display);
|
||||
}
|
||||
|
||||
static void set_swap (int _swap) { swap = _swap; }
|
||||
static void set_floating (bool _floating) { floating = _floating; }
|
||||
static void set_decorated (bool _decorated) { decorated = _decorated; }
|
||||
@@ -420,10 +452,11 @@ static void swap_buffers(struct glxwin* w) {
|
||||
XNextEvent(display, &ev);
|
||||
switch (ev.type) {
|
||||
case ClientMessage:
|
||||
if (ev.xclient.message_type == XInternAtom(display, "WM_PROTOCOLS", 1)
|
||||
&& ev.xclient.data.l[0] == XInternAtom(display, "WM_DELETE_WINDOW", 1)) {
|
||||
if (ev.xclient.message_type == ATOM_WM_PROTOCOLS
|
||||
&& ev.xclient.data.l[0] == ATOM_WM_DELETE_WINDOW) {
|
||||
w->should_close = true;
|
||||
}
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
11
render.c
11
render.c
@@ -108,8 +108,8 @@ struct gl_data {
|
||||
int rate; /* framerate */
|
||||
double tcounter;
|
||||
int fcounter, ucounter, kcounter;
|
||||
bool print_fps, avg_window, interpolate, force_geometry, copy_desktop,
|
||||
smooth_pass, premultiply_alpha, check_fullscreen;
|
||||
bool print_fps, avg_window, interpolate, force_geometry, force_raised,
|
||||
copy_desktop, smooth_pass, premultiply_alpha, check_fullscreen;
|
||||
void** t_data;
|
||||
float gravity_step, target_spu, fr, ur, smooth_distance, smooth_ratio,
|
||||
smooth_factor, fft_scale, fft_cutoff;
|
||||
@@ -714,6 +714,7 @@ struct renderer* rd_new(const char** paths, const char* entry,
|
||||
.gravity_step = 4.2,
|
||||
.interpolate = true,
|
||||
.force_geometry = false,
|
||||
.force_raised = false,
|
||||
.smooth_factor = 0.025,
|
||||
.smooth_distance = 0.01,
|
||||
.smooth_ratio = 4,
|
||||
@@ -907,6 +908,8 @@ struct renderer* rd_new(const char** paths, const char* entry,
|
||||
r->audio_source_request = strdup((char*) args[0]); }) },
|
||||
{ .name = "setforcegeometry", .fmt = "b",
|
||||
.handler = RHANDLER(name, args, { gl->force_geometry = *(bool*) args[0]; }) },
|
||||
{ .name = "setforceraised", .fmt = "b",
|
||||
.handler = RHANDLER(name, args, { gl->force_raised = *(bool*) args[0]; }) },
|
||||
{ .name = "setxwintype", .fmt = "s",
|
||||
.handler = RHANDLER(name, args, { xwintype = strdup((char*) args[0]); }) },
|
||||
{ .name = "setshaderversion", .fmt = "i",
|
||||
@@ -1633,6 +1636,10 @@ bool rd_update(struct renderer* r, float* lb, float* rb, size_t bsz, bool modifi
|
||||
gl->geometry[0], gl->geometry[1],
|
||||
gl->geometry[2], gl->geometry[3]);
|
||||
}
|
||||
|
||||
if (gl->force_raised) {
|
||||
gl->wcb->raise(gl->w);
|
||||
}
|
||||
}
|
||||
|
||||
/* Restore interpolation settings */
|
||||
|
||||
2
render.h
2
render.h
@@ -32,6 +32,7 @@ struct gl_wcb {
|
||||
int version_major, int version_minor);
|
||||
bool (*should_close) (void* ptr);
|
||||
void (*swap_buffers) (void* ptr);
|
||||
void (*raise) (void* ptr);
|
||||
void (*get_pos) (void* ptr, int* x, int* y);
|
||||
void (*get_fbsize) (void* ptr, int* w, int* h);
|
||||
void (*set_geometry) (void* ptr, int x, int y, int w, int h);
|
||||
@@ -63,6 +64,7 @@ struct gl_wcb {
|
||||
WCB_FUNC(create_and_bind), \
|
||||
WCB_FUNC(should_close), \
|
||||
WCB_FUNC(swap_buffers), \
|
||||
WCB_FUNC(raise), \
|
||||
WCB_FUNC(set_swap), \
|
||||
WCB_FUNC(get_pos), \
|
||||
WCB_FUNC(get_fbsize), \
|
||||
|
||||
@@ -26,6 +26,10 @@
|
||||
embedding in the desktop. */
|
||||
#request setforcegeometry false
|
||||
|
||||
/* Force window to be raised (focused in some WMs), useful for
|
||||
WMs that have their own stacking order for desktop windows. */
|
||||
#request setforceraised false
|
||||
|
||||
/* Set window background opacity mode. Possible values are:
|
||||
|
||||
"native" - True transparency provided by the compositor. Can
|
||||
|
||||
31
xwin.c
31
xwin.c
@@ -25,11 +25,12 @@
|
||||
#include "render.h"
|
||||
#include "xwin.h"
|
||||
|
||||
static Window find_desktop(struct renderer* r) {
|
||||
Window* xwin_get_desktop_layer(struct gl_wcb* wcb) {
|
||||
static Window desktop;
|
||||
static bool searched = false;
|
||||
if (!searched) {
|
||||
Display* d = rd_get_wcb(r)->get_x11_display();
|
||||
Display* d = wcb->get_x11_display();
|
||||
Atom class = XInternAtom(d, "WM_CLASS", false);
|
||||
desktop = DefaultRootWindow(d);
|
||||
Window _ignored, * children;
|
||||
unsigned int nret;
|
||||
@@ -41,18 +42,36 @@ static Window find_desktop(struct renderer* r) {
|
||||
if (name) {
|
||||
/* Mutter-based window managers */
|
||||
if (!strcmp(name, "mutter guard window")) {
|
||||
printf("Using mutter guard window instead of root window\n");
|
||||
// desktop = children[t];
|
||||
printf("Reparenting to mutter guard window instead of root window\n");
|
||||
desktop = children[t];
|
||||
t = nret; /* break after */
|
||||
}
|
||||
XFree(name);
|
||||
}
|
||||
unsigned long bytes;
|
||||
XTextProperty text = {};
|
||||
char** list;
|
||||
int list_sz;
|
||||
/* Get WM_CLASS property */
|
||||
if (Success == XGetWindowProperty(d, children[t], class, 0, 512, false, AnyPropertyType,
|
||||
&text.encoding, &text.format, &text.nitems, &bytes,
|
||||
&text.value)) {
|
||||
/* decode string array */
|
||||
if (Success == XmbTextPropertyToTextList(d, &text, &list, &list_sz)) {
|
||||
if (list_sz >= 1 && !strcmp(list[0], "plasmashell")) {
|
||||
desktop = children[t];
|
||||
t = nret;
|
||||
}
|
||||
XFreeStringList(list);
|
||||
}
|
||||
XFree(text.value);
|
||||
}
|
||||
}
|
||||
XFree(children);
|
||||
}
|
||||
searched = true;
|
||||
}
|
||||
return desktop;
|
||||
return &desktop;
|
||||
}
|
||||
|
||||
void xwin_wait_for_wm(void) {
|
||||
@@ -219,7 +238,7 @@ unsigned int xwin_copyglbg(struct renderer* rd, unsigned int tex) {
|
||||
rd_get_wcb(rd)->get_pos(rd_get_impl_window(rd), &x, &y);
|
||||
XColor c;
|
||||
Display* d = rd_get_wcb(rd)->get_x11_display();
|
||||
Drawable src = get_drawable(d, find_desktop(rd));
|
||||
Drawable src = get_drawable(d, DefaultRootWindow(d));
|
||||
bool use_shm = XShmQueryExtension(d);
|
||||
|
||||
/* Obtain section of root pixmap */
|
||||
|
||||
8
xwin.h
8
xwin.h
@@ -1,9 +1,17 @@
|
||||
|
||||
#define XWIN_ALL_DESKTOPS 0xFFFFFFFF
|
||||
|
||||
#ifndef XWIN_H
|
||||
#define XWIN_H
|
||||
|
||||
typedef unsigned long int Window;
|
||||
|
||||
bool xwin_should_render(struct renderer* rd);
|
||||
void xwin_wait_for_wm(void);
|
||||
bool xwin_settype(struct gl_wcb* wcb, void* impl, const char* type);
|
||||
void xwin_setdesktop(struct gl_wcb* wcb, void* impl, unsigned long desktop);
|
||||
void xwin_addstate(struct gl_wcb* wcb, void* impl, const char* state);
|
||||
unsigned int xwin_copyglbg(struct renderer* rd, unsigned int texture);
|
||||
Window* xwin_get_desktop_layer(struct gl_wcb* wcb);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user