Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7bb7913bd3 | ||
|
|
1a1cbc9cc8 | ||
|
|
83a94e3eb4 |
2
Makefile
2
Makefile
@@ -9,7 +9,7 @@ ifeq ($(BUILD),debug)
|
||||
STRIP_CMD = $(info Skipping `strip` for debug builds)
|
||||
# ASAN = -lasan
|
||||
else
|
||||
CFLAGS_BUILD = -O2 -march=native -Wstringop-overflow=0
|
||||
CFLAGS_BUILD = -O2 -Wstringop-overflow=0
|
||||
GLAD_GEN = c
|
||||
STRIP_CMD = strip --strip-all glava
|
||||
endif
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
```bash
|
||||
$ git clone --recursive https://github.com/wacossusca34/glava
|
||||
$ cd glava
|
||||
$ make
|
||||
$ CFLAGS="-march=native" make
|
||||
$ sudo make install
|
||||
$ glava
|
||||
```
|
||||
|
||||
@@ -128,6 +128,8 @@ static void swap_buffers(GLFWwindow* w) {
|
||||
static Display* get_x11_display(void) { return glfwGetX11Display(); }
|
||||
static Window get_x11_window (GLFWwindow* w) { return glfwGetX11Window(w); }
|
||||
static bool should_close (GLFWwindow* w) { return glfwWindowShouldClose(w); }
|
||||
static bool should_render (GLFWwindow* w) { return true; }
|
||||
static bool bg_changed (GLFWwindow* w) { return false; }
|
||||
static void get_fbsize (GLFWwindow* w, int* d, int* h) { glfwGetFramebufferSize(w, d, h); }
|
||||
static void get_pos (GLFWwindow* w, int* x, int* y) { glfwGetWindowPos(w, x, y); }
|
||||
static double get_time (GLFWwindow* w) { return glfwGetTime(); }
|
||||
|
||||
55
glx_wcb.c
55
glx_wcb.c
@@ -175,11 +175,11 @@ struct glxwin {
|
||||
Window w;
|
||||
GLXContext context;
|
||||
double time;
|
||||
bool should_close, clickthrough;
|
||||
bool should_close, should_render, bg_changed, clickthrough;
|
||||
char override_state;
|
||||
};
|
||||
|
||||
static Atom ATOM__MOTIF_WM_HINTS, ATOM_WM_DELETE_WINDOW, ATOM_WM_PROTOCOLS, ATOM__NET_ACTIVE_WINDOW;
|
||||
static Atom ATOM__MOTIF_WM_HINTS, ATOM_WM_DELETE_WINDOW, ATOM_WM_PROTOCOLS, ATOM__NET_ACTIVE_WINDOW, ATOM__XROOTPMAP_ID;
|
||||
|
||||
static void init(void) {
|
||||
display = XOpenDisplay(NULL);
|
||||
@@ -232,6 +232,7 @@ static void init(void) {
|
||||
intern(WM_DELETE_WINDOW, true);
|
||||
intern(WM_PROTOCOLS, true);
|
||||
intern(_NET_ACTIVE_WINDOW, false);
|
||||
intern(_XROOTPMAP_ID, false);
|
||||
|
||||
#undef intern
|
||||
#undef resolve
|
||||
@@ -274,10 +275,14 @@ static void* create_and_bind(const char* name, const char* class,
|
||||
int version_major, int version_minor,
|
||||
bool clickthrough) {
|
||||
struct glxwin* w = malloc(sizeof(struct glxwin));
|
||||
w->override_state = '\0';
|
||||
w->time = 0.0D;
|
||||
w->should_close = false;
|
||||
w->clickthrough = false;
|
||||
*w = (struct glxwin) {
|
||||
.override_state = '\0',
|
||||
.time = 0.0D,
|
||||
.should_close = false,
|
||||
.should_render = true,
|
||||
.bg_changed = false,
|
||||
.clickthrough = false
|
||||
};
|
||||
|
||||
XVisualInfo* vi;
|
||||
XSetWindowAttributes attr = {};
|
||||
@@ -355,10 +360,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 | PropertyChangeMask;
|
||||
attr.event_mask = ExposureMask | KeyPressMask | StructureNotifyMask;
|
||||
attr.event_mask |= PropertyChangeMask | VisibilityChangeMask;
|
||||
attr.background_pixmap = None;
|
||||
attr.border_pixel = 0;
|
||||
|
||||
|
||||
unsigned long vmask = CWColormap | CWEventMask | CWBackPixmap | CWBorderPixel;
|
||||
if (type[0] == '!') {
|
||||
vmask |= CWOverrideRedirect;
|
||||
@@ -428,7 +434,8 @@ static void* create_and_bind(const char* name, const char* class,
|
||||
|
||||
if (glXSwapIntervalEXT) glXSwapIntervalEXT(display, drawable, swap);
|
||||
|
||||
// XSelectInput(display, DefaultRootWindow(display), VisibilityChangeMask | PropertyChangeMask);
|
||||
if (!transparent)
|
||||
XSelectInput(display, DefaultRootWindow(display), PropertyChangeMask);
|
||||
|
||||
return w;
|
||||
}
|
||||
@@ -483,8 +490,15 @@ static void set_visible(struct glxwin* w, bool visible) {
|
||||
else XUnmapWindow(display, w->w);
|
||||
}
|
||||
|
||||
static bool should_close(struct glxwin* w) {
|
||||
return w->should_close;
|
||||
static bool should_close (struct glxwin* w) { return w->should_close; }
|
||||
static bool bg_changed (struct glxwin* w) { return w->bg_changed; }
|
||||
static bool should_render(struct glxwin* w) {
|
||||
/* For nearly all window managers, windows are 'minimized' by unmapping parent windows.
|
||||
VisibilityNotify events are not sent in these instances, so we have to read window
|
||||
attributes to see if our window isn't viewable. */
|
||||
XWindowAttributes attrs;
|
||||
XGetWindowAttributes(display, w->w, &attrs);
|
||||
return w->should_render && attrs.map_state == IsViewable;
|
||||
}
|
||||
|
||||
static void swap_buffers(struct glxwin* w) {
|
||||
@@ -500,6 +514,25 @@ static void swap_buffers(struct glxwin* w) {
|
||||
w->should_close = true;
|
||||
}
|
||||
break;
|
||||
case VisibilityNotify:
|
||||
switch (ev.xvisibility.state) {
|
||||
case VisibilityFullyObscured:
|
||||
w->should_render = false;
|
||||
break;
|
||||
case VisibilityUnobscured:
|
||||
case VisibilityPartiallyObscured:
|
||||
w->should_render = true;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Invalid VisibilityNotify event state (%d)\n", ev.xvisibility.state);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case PropertyNotify:
|
||||
if (ev.xproperty.atom == ATOM__XROOTPMAP_ID) {
|
||||
w->bg_changed = true;
|
||||
}
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
12
render.c
12
render.c
@@ -724,7 +724,7 @@ struct renderer* rd_new(const char** paths, const char* entry,
|
||||
.sm_prog = 0,
|
||||
.copy_desktop = true,
|
||||
.premultiply_alpha = true,
|
||||
.check_fullscreen = true,
|
||||
.check_fullscreen = false,
|
||||
.smooth_pass = true,
|
||||
.fft_scale = 10.2F,
|
||||
.fft_cutoff = 0.3F,
|
||||
@@ -1329,7 +1329,7 @@ struct renderer* rd_new(const char** paths, const char* entry,
|
||||
overlay(&gl->overlay);
|
||||
|
||||
glClearColor(gl->clear_color.r, gl->clear_color.g, gl->clear_color.b, gl->clear_color.a);
|
||||
|
||||
|
||||
gl->wcb->set_visible(gl->w, true);
|
||||
|
||||
return r;
|
||||
@@ -1349,9 +1349,13 @@ bool rd_update(struct renderer* r, float* lb, float* rb, size_t bsz, bool modifi
|
||||
r->alive = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Stop rendering if the backend has some reason not to render (minimized, obscured) */
|
||||
if (!gl->wcb->should_render(gl->w))
|
||||
return false;
|
||||
|
||||
/* Stop rendering when fullscreen windows are focused */
|
||||
if (gl->check_fullscreen && !xwin_should_render(r))
|
||||
if (gl->check_fullscreen && !xwin_should_render(gl->wcb, gl->w))
|
||||
return false;
|
||||
|
||||
/* Force disable interpolation if the update rate is close to or higher than the frame rate */
|
||||
@@ -1418,7 +1422,7 @@ bool rd_update(struct renderer* r, float* lb, float* rb, size_t bsz, bool modifi
|
||||
}
|
||||
|
||||
/* Resize and grab new background data if needed */
|
||||
if (gl->copy_desktop && (ww != gl->lww || wh != gl->lwh || wx != gl->lwx || wy != gl->lwy)) {
|
||||
if (gl->copy_desktop && (gl->wcb->bg_changed(gl->w) || ww != gl->lww || wh != gl->lwh || wx != gl->lwx || wy != gl->lwy)) {
|
||||
gl->bg_tex = xwin_copyglbg(r, gl->bg_tex);
|
||||
}
|
||||
|
||||
|
||||
4
render.h
4
render.h
@@ -33,6 +33,8 @@ struct gl_wcb {
|
||||
int version_major, int version_minor,
|
||||
bool clickthrough);
|
||||
bool (*should_close) (void* ptr);
|
||||
bool (*should_render) (void* ptr);
|
||||
bool (*bg_changed) (void* ptr);
|
||||
void (*swap_buffers) (void* ptr);
|
||||
void (*raise) (void* ptr);
|
||||
void (*destroy) (void* ptr);
|
||||
@@ -68,6 +70,8 @@ struct gl_wcb {
|
||||
WCB_FUNC(init), \
|
||||
WCB_FUNC(create_and_bind), \
|
||||
WCB_FUNC(should_close), \
|
||||
WCB_FUNC(should_render), \
|
||||
WCB_FUNC(bg_changed), \
|
||||
WCB_FUNC(swap_buffers), \
|
||||
WCB_FUNC(raise), \
|
||||
WCB_FUNC(destroy), \
|
||||
|
||||
@@ -128,11 +128,14 @@
|
||||
simply set to zero (or lower) to disable the frame limiter. */
|
||||
#request setframerate 0
|
||||
|
||||
/* Enable/disable fullscreen checks. This looks at the currently
|
||||
focused window and halts GLava's rendering if it is
|
||||
fullscreen. This prevents rendering from interfering with
|
||||
other graphically intensive tasks. */
|
||||
#request setfullscreencheck true
|
||||
/* Suspends rendering if a fullscreen window is focused while
|
||||
GLava is still visible (ie. on another monitor). This prevents
|
||||
rendering from interfering with other graphically intensive
|
||||
tasks.
|
||||
|
||||
If GLava is minimized or completely obscured, it will not
|
||||
render regardless of this option. */
|
||||
#request setfullscreencheck false
|
||||
|
||||
/* Enable/disable printing framerate every second. 'FPS' stands
|
||||
for 'Frames Per Second', and 'UPS' stands for 'Updates Per
|
||||
|
||||
8
xwin.c
8
xwin.c
@@ -140,14 +140,14 @@ const char* xwin_detect_wm(struct gl_wcb* wcb) {
|
||||
|
||||
}
|
||||
|
||||
bool xwin_should_render(struct renderer* rd) {
|
||||
bool xwin_should_render(struct gl_wcb* wcb, void* impl) {
|
||||
bool ret = true, should_close = false;
|
||||
Display* d = rd_get_wcb(rd)->get_x11_display();
|
||||
Display* d = wcb->get_x11_display();
|
||||
if (!d) {
|
||||
d = XOpenDisplay(0);
|
||||
should_close = true;
|
||||
}
|
||||
|
||||
|
||||
Atom prop = XInternAtom(d, "_NET_ACTIVE_WINDOW", true);
|
||||
Atom fullscreen = XInternAtom(d, "_NET_WM_STATE_FULLSCREEN", true);
|
||||
|
||||
@@ -280,7 +280,7 @@ unsigned int xwin_copyglbg(struct renderer* rd, unsigned int tex) {
|
||||
Display* d = rd_get_wcb(rd)->get_x11_display();
|
||||
Drawable src = get_drawable(d, DefaultRootWindow(d));
|
||||
bool use_shm = XShmQueryExtension(d);
|
||||
|
||||
|
||||
/* Obtain section of root pixmap */
|
||||
|
||||
XShmSegmentInfo shminfo;
|
||||
|
||||
2
xwin.h
2
xwin.h
@@ -6,7 +6,7 @@
|
||||
|
||||
typedef unsigned long int Window;
|
||||
|
||||
bool xwin_should_render(struct renderer* rd);
|
||||
bool xwin_should_render(struct gl_wcb* wcb, void* impl);
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user