This commit is contained in:
Nishi 2025-12-12 17:13:05 +09:00
commit 66ce4a97f3
Signed by: nishi
GPG key ID: 27EF69B208EB9343
5 changed files with 102 additions and 40 deletions

View file

@ -4,7 +4,7 @@
#include <security/pam_appl.h> #include <security/pam_appl.h>
#include <stb_ds.h> #include <stb_ds.h>
MwWidget root; MwWidget root = NULL;
MwWidget window, sesscombo, usercombo, passentry, reason; MwWidget window, sesscombo, usercombo, passentry, reason;
typedef struct session { typedef struct session {

View file

@ -50,6 +50,14 @@ static int wm_detect(Display* disp, XErrorEvent* ev) {
} }
static void* x11_thread_routine(void* arg) { static void* x11_thread_routine(void* arg) {
while(1) {
pthread_mutex_lock(&xmutex);
if(root != NULL) {
pthread_mutex_unlock(&xmutex);
break;
}
pthread_mutex_unlock(&xmutex);
}
loop_x(); loop_x();
XCloseDisplay(xdisplay); XCloseDisplay(xdisplay);
return NULL; return NULL;

View file

@ -32,6 +32,8 @@ void loop_x(void);
void set_focus_x(MwWidget widget); void set_focus_x(MwWidget widget);
/* wm.c */ /* wm.c */
extern MwWidget root;
void loop_wm(void); void loop_wm(void);
MwWidget wm_frame(int w, int h); MwWidget wm_frame(int w, int h);
void wm_destroy(MwWidget widget); void wm_destroy(MwWidget widget);

View file

@ -3,7 +3,7 @@
#include <stb_ds.h> #include <stb_ds.h>
static MwWidget root; MwWidget root = NULL;
typedef struct wmframe { typedef struct wmframe {
MwWidget inside; MwWidget inside;

View file

@ -15,6 +15,7 @@ static Atom milkwm_set_focus;
typedef struct window { typedef struct window {
MwWidget frame; MwWidget frame;
Window client; Window client;
int working;
} window_t; } window_t;
static window_t* windows = NULL; static window_t* windows = NULL;
@ -36,13 +37,21 @@ static void end_error(void) {
} }
static void* x11_thread_routine(void* arg) { static void* x11_thread_routine(void* arg) {
while(1) {
pthread_mutex_lock(&xmutex);
if(root != NULL) {
pthread_mutex_unlock(&xmutex);
break;
}
pthread_mutex_unlock(&xmutex);
}
loop_x(); loop_x();
XCloseDisplay(xdisplay); XCloseDisplay(xdisplay);
return NULL; return NULL;
} }
static Window focus = None, nofocus; static Window focus = None, nofocus;
static void set_focus(Window w) { static void set_focus(Window w) {
int i; int i;
for(i = 0; i < arrlen(windows); i++) { for(i = 0; i < arrlen(windows); i++) {
@ -78,7 +87,7 @@ int init_x(void) {
xdisplay = XOpenDisplay(NULL); xdisplay = XOpenDisplay(NULL);
begin_error(); begin_error();
XSelectInput(xdisplay, DefaultRootWindow(xdisplay), SubstructureRedirectMask); XSelectInput(xdisplay, DefaultRootWindow(xdisplay), SubstructureRedirectMask | SubstructureNotifyMask);
end_error(); end_error();
if(error_happened) return 1; if(error_happened) return 1;
@ -258,6 +267,20 @@ void loop_x(void) {
XConfigureWindow(xdisplay, windows[i].frame->lowlevel->x11.window, CWWidth | CWHeight, &xwc); XConfigureWindow(xdisplay, windows[i].frame->lowlevel->x11.window, CWWidth | CWHeight, &xwc);
} }
break;
}
}
} else if(ev.type == CreateNotify) {
XWindowAttributes xwa;
XGetWindowAttributes(xdisplay, DefaultRootWindow(xdisplay), &xwa);
XMoveWindow(xdisplay, ev.xcreatewindow.window, rand() % (xwa.width - wm_entire_width(ev.xcreatewindow.width)), rand() % (xwa.height - wm_entire_height(ev.xcreatewindow.height)));
} else if(ev.type == DestroyNotify) {
for(i = 0; i < arrlen(windows); i++) {
if(windows[i].client == ev.xdestroywindow.window) {
wm_destroy(windows[i].frame);
arrdel(windows, i);
break; break;
} }
} }
@ -287,29 +310,33 @@ void loop_x(void) {
} }
XMoveWindow(xdisplay, ev.xmaprequest.window, xwa.x, xwa.y); XMoveWindow(xdisplay, ev.xmaprequest.window, xwa.x, xwa.y);
XMapWindow(xdisplay, ev.xmaprequest.window); XMapWindow(xdisplay, ev.xmaprequest.window);
do {
XFlush(xdisplay);
XGetWindowAttributes(xdisplay, ev.xmaprequest.window, &xwa);
} while(xwa.map_state != IsViewable);
if(!XReparentWindow(xdisplay, windows[i].client, wm_get_inside(windows[i].frame)->lowlevel->x11.window, wm_content_x(), wm_content_y())) { if(!XReparentWindow(xdisplay, windows[i].client, wm_get_inside(windows[i].frame)->lowlevel->x11.window, wm_content_x(), wm_content_y())) {
wm_destroy(windows[i].frame); wm_destroy(windows[i].frame);
arrdel(windows, i); arrdel(windows, i);
continue; continue;
} }
if(!XMapWindow(xdisplay, windows[i].client)) { XMapWindow(xdisplay, windows[i].client);
wm_destroy(windows[i].frame);
arrdel(windows, i);
continue;
}
XFlush(xdisplay);
continue; continue;
} }
w.frame = wm_frame(xwa.width, xwa.height); w.frame = wm_frame(xwa.width, xwa.height);
w.client = ev.xmaprequest.window; w.client = ev.xmaprequest.window;
w.working = 1;
save(w.client); save(w.client);
if(ret) {
wm_destroy(w.frame);
} else {
arrput(windows, w); arrput(windows, w);
set_name(w.client); set_name(w.client);
}
} else if(ev.type == PropertyNotify) { } else if(ev.type == PropertyNotify) {
int i; int i;
for(i = 0; i < arrlen(windows); i++) { for(i = 0; i < arrlen(windows); i++) {
@ -324,11 +351,29 @@ void loop_x(void) {
} }
} else if(ev.type == MapNotify) { } else if(ev.type == MapNotify) {
int i; int i;
if(ev.xmap.override_redirect) continue;
for(i = 0; i < arrlen(windows); i++) { for(i = 0; i < arrlen(windows); i++) {
if(windows[i].client == ev.xmap.window) { if(windows[i].client == ev.xmap.window) {
if(windows[i].frame == NULL) printf("wtf?\n");
set_focus(windows[i].client); set_focus(windows[i].client);
windows[i].working = 0;
break;
} else if(windows[i].frame->lowlevel->x11.window == ev.xmap.window || nofocus == ev.xmap.window)
break; break;
} }
if(i == arrlen(windows)) {
window_t w;
XWindowAttributes xwa;
XGetWindowAttributes(xdisplay, ev.xmap.window, &xwa);
w.frame = wm_frame(xwa.width, xwa.height);
w.client = ev.xmap.window;
w.working = 1;
save(w.client);
arrput(windows, w);
} }
} else if(ev.type == UnmapNotify) { } else if(ev.type == UnmapNotify) {
int i; int i;
@ -336,15 +381,22 @@ void loop_x(void) {
for(i = 0; i < arrlen(windows); i++) { for(i = 0; i < arrlen(windows); i++) {
if(windows[i].client == ev.xunmap.window) { if(windows[i].client == ev.xunmap.window) {
XWindowAttributes xwa; XWindowAttributes xwa;
int x, y;
if(XGetWindowAttributes(xdisplay, windows[i].client, &xwa)) { if(XGetWindowAttributes(xdisplay, windows[i].client, &xwa)) {
if(xwa.map_state == IsViewable) { if(xwa.map_state == IsViewable) {
nvm = 1; nvm = 1;
break; break;
} }
} else if(windows[i].working) {
nvm = 1;
break;
} }
x = xwa.x;
y = xwa.y;
if(XGetWindowAttributes(xdisplay, windows[i].frame->lowlevel->x11.window, &xwa)) { if(XGetWindowAttributes(xdisplay, windows[i].frame->lowlevel->x11.window, &xwa)) {
XReparentWindow(xdisplay, windows[i].client, DefaultRootWindow(xdisplay), xwa.x, xwa.y); XReparentWindow(xdisplay, windows[i].client, DefaultRootWindow(xdisplay), xwa.x + x, xwa.y + y);
} }
wm_destroy(windows[i].frame); wm_destroy(windows[i].frame);