This commit is contained in:
Nishi 2025-12-31 02:50:13 +09:00
commit d60f66249a
Signed by: nishi
GPG key ID: 27EF69B208EB9343
4 changed files with 119 additions and 8 deletions

View file

@ -11,7 +11,7 @@ static void read_config(const char* path) {
xemil_t* tmp;
if((tmp = xl_open_file(path)) == NULL || !xl_parse(tmp)) {
fprintf(stderr, "MPanel config error: file %s\n", path);
fprintf(stderr, "MilkWM config error: file %s\n", path);
if(tmp != NULL) xl_close(tmp);
} else {
if(wm_config != NULL) xl_close(wm_config);

View file

@ -32,6 +32,7 @@ int init_x(void);
void loop_x(void);
void set_focus_x(MwWidget widget);
void set_background_x(void);
void delete_x(MwWidget widget);
/* wm.c */
extern MwWidget root;

View file

@ -32,6 +32,8 @@ typedef struct wmframe {
MwWidget submenu;
MwMenu menu;
long tick;
} wmframe_t;
void loop_wm(void) {
@ -153,10 +155,18 @@ static void apply_config(MwWidget wnd) {
static void maximize(MwWidget handle, void* user, void* client) {
wmframe_t* f = ((MwWidget)user)->opaque;
MwRect rc;
int i;
set_focus_x(user);
if(f->maximized) {
for(i = 0; i < arrlen(f->menu->sub); i++) {
if(strcmp(f->menu->sub[i]->name, "Restore") == 0) {
free(f->menu->sub[i]->name);
f->menu->sub[i]->name = MwStringDuplicate("Maximize");
}
}
f->maximized = 0;
MwVaApply(handle,
@ -170,6 +180,13 @@ static void maximize(MwWidget handle, void* user, void* client) {
MwNheight, f->old_size.height,
NULL);
} else {
for(i = 0; i < arrlen(f->menu->sub); i++) {
if(strcmp(f->menu->sub[i]->name, "Maximize") == 0) {
free(f->menu->sub[i]->name);
f->menu->sub[i]->name = MwStringDuplicate("Restore");
}
}
f->maximized = 1;
f->old_point.x = MwGetInteger(user, MwNx);
@ -196,6 +213,7 @@ static void spawn_menu(MwWidget handle, void* user, void* client) {
MwWidget w = handle;
wmframe_t* f;
MwPoint p;
long t;
while(w != NULL && strcmp(MwGetName(w), "frame") != 0) w = MwGetParent(w);
@ -207,21 +225,56 @@ static void spawn_menu(MwWidget handle, void* user, void* client) {
p.x = 0;
p.y = MwGetInteger(handle, MwNheight);
MwSubMenuAppear(f->submenu, f->menu, &p, 0);
MwVaApply(f->menu_button,
MwNforceInverted, 1,
NULL);
} else {
MwDestroyWidget(f->submenu);
f->submenu = NULL;
MwVaApply(f->menu_button,
MwNforceInverted, 0,
NULL);
}
if(((t = MwTimeGetTick()) - f->tick) < MwDoubleClickTimeout) {
delete_x(w);
}
f->tick = t;
}
static void menu_menu(MwWidget handle, void* user, void* client) {
MwWidget w = handle;
wmframe_t* f;
int i;
MwMenu m = client;
while(w != NULL && strcmp(MwGetName(w), "frame") != 0) w = MwGetParent(w);
f = w->opaque;
if(strcmp(m->name, "Maximize") == 0 || strcmp(m->name, "Restore") == 0) {
for(i = 0; i < arrlen(f->left); i++) {
MwLLPixmap px = MwGetVoid(f->left[i], MwNpixmap);
if(px == f->maximize || px == f->restore) maximize(f->left[i], w, NULL);
}
for(i = 0; i < arrlen(f->right); i++) {
MwLLPixmap px = MwGetVoid(f->right[i], MwNpixmap);
if(px == f->maximize || px == f->restore) maximize(f->right[i], w, NULL);
}
} else if(strcmp(m->name, "Close") == 0) {
delete_x(w);
}
f->submenu = NULL;
MwVaApply(f->menu_button,
MwNforceInverted, 0,
NULL);
}
static void apply_button(MwWidget widget, const char* str) {
@ -269,6 +322,10 @@ static void drag_down(MwWidget handle, void* user, void* client) {
if(f->submenu != NULL) {
MwDestroyWidget(f->submenu);
f->submenu = NULL;
MwVaApply(f->menu_button,
MwNforceInverted, 0,
NULL);
}
f->dragging = 1;
@ -423,6 +480,8 @@ MwWidget wm_frame(int w, int h) {
f->iconify = MwLoadRaw(wnd, icon, 6, 6);
free(icon);
f->tick = 0;
f->left = NULL;
f->right = NULL;

View file

@ -50,6 +50,7 @@ typedef struct window {
int working;
} window_t;
static window_t* windows = NULL;
static Window* wnd = NULL;
static void* old_handler;
static int error_happened = 0;
@ -452,13 +453,23 @@ static int is_no_border(Window window) {
return 0;
}
static void bring_up(void) {
int i;
for(i = 0; i < arrlen(wnd); i++) {
XWindowAttributes xwa;
XGetWindowAttributes(xdisplay, wnd[i], &xwa);
if(xwa.override_redirect) XRaiseWindow(xdisplay, wnd[i]);
}
}
void loop_x(void) {
XEvent ev;
Window root, parent;
Window* children;
unsigned int nchildren;
int i;
Window* wnd = NULL;
begin_error();
@ -509,6 +520,8 @@ void loop_x(void) {
XRaiseWindow(xdisplay, w);
}
bring_up();
XAllowEvents(xdisplay, ReplayPointer, CurrentTime);
} else if(ev.type == MotionNotify && ev.xmotion.subwindow != None) {
Window w = None, t = ev.xmotion.window;
@ -520,7 +533,10 @@ void loop_x(void) {
}
}
if(w != None) XRaiseWindow(xdisplay, w);
if(w != None) {
XRaiseWindow(xdisplay, w);
bring_up();
}
XAllowEvents(xdisplay, ReplayPointer, CurrentTime);
} else if(ev.type == FocusIn && ev.xfocus.window != focus) {
@ -628,7 +644,11 @@ void loop_x(void) {
XMapWindow(xdisplay, ev.xmaprequest.window);
if(xwa.override_redirect) save(ev.xmaprequest.window);
if(xwa.override_redirect) {
arrput(wnd, ev.xmaprequest.window);
save(ev.xmaprequest.window);
}
continue;
}
@ -726,7 +746,16 @@ void loop_x(void) {
int i;
XWindowAttributes xwa;
if(!XGetWindowAttributes(xdisplay, ev.xmap.window, &xwa)) continue;
if(xwa.override_redirect) continue;
if(xwa.override_redirect) {
for(i = 0; i < arrlen(wnd); i++) {
if(wnd[i] == ev.xmap.window) {
break;
}
}
if(i == arrlen(wnd)) arrput(wnd, ev.xmap.window);
continue;
}
for(i = 0; i < arrlen(windows); i++) {
if(windows[i].client == ev.xmap.window) {
@ -800,7 +829,7 @@ void loop_x(void) {
set_focus(w);
}
} else if(ev.type == ClientMessage) {
if(ev.xclient.message_type == milkwm_set_focus && ev.xclient.data.l[0] == milkwm_set_focus) {
if(ev.xclient.message_type == XInternAtom(xdisplay, "WM_PROTOCOLS", False) && ev.xclient.data.l[0] == milkwm_set_focus) {
set_focus(ev.xclient.data.l[1]);
}
}
@ -819,14 +848,36 @@ void set_focus_x(MwWidget widget) {
ev.type = ClientMessage;
ev.xclient.window = nofocus;
ev.xclient.message_type = milkwm_set_focus;
ev.xclient.message_type = XInternAtom(xdisplay, "WM_PROTOCOLS", False);
ev.xclient.format = 32;
ev.xclient.data.l[0] = ev.xclient.message_type;
ev.xclient.data.l[0] = milkwm_set_focus;
ev.xclient.data.l[1] = windows[i].client;
XSendEvent(xdisplay, nofocus, False, 0, &ev);
XRaiseWindow(xdisplay, windows[i].frame->lowlevel->x11.window);
bring_up();
break;
}
}
}
void delete_x(MwWidget widget) {
int i;
for(i = 0; i < arrlen(windows); i++) {
if(windows[i].frame == widget) {
XEvent ev;
ev.type = ClientMessage;
ev.xclient.window = windows[i].client;
ev.xclient.message_type = XInternAtom(xdisplay, "WM_PROTOCOLS", False);
ev.xclient.format = 32;
ev.xclient.data.l[0] = XInternAtom(xdisplay, "WM_DELETE_WINDOW", False);
ev.xclient.data.l[1] = CurrentTime;
XSendEvent(xdisplay, windows[i].client, False, 0, &ev);
break;
}