fix
This commit is contained in:
parent
90c96d3f4b
commit
d60f66249a
4 changed files with 119 additions and 8 deletions
|
|
@ -11,7 +11,7 @@ static void read_config(const char* path) {
|
||||||
xemil_t* tmp;
|
xemil_t* tmp;
|
||||||
|
|
||||||
if((tmp = xl_open_file(path)) == NULL || !xl_parse(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);
|
if(tmp != NULL) xl_close(tmp);
|
||||||
} else {
|
} else {
|
||||||
if(wm_config != NULL) xl_close(wm_config);
|
if(wm_config != NULL) xl_close(wm_config);
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ int init_x(void);
|
||||||
void loop_x(void);
|
void loop_x(void);
|
||||||
void set_focus_x(MwWidget widget);
|
void set_focus_x(MwWidget widget);
|
||||||
void set_background_x(void);
|
void set_background_x(void);
|
||||||
|
void delete_x(MwWidget widget);
|
||||||
|
|
||||||
/* wm.c */
|
/* wm.c */
|
||||||
extern MwWidget root;
|
extern MwWidget root;
|
||||||
|
|
|
||||||
59
milkwm/wm.c
59
milkwm/wm.c
|
|
@ -32,6 +32,8 @@ typedef struct wmframe {
|
||||||
MwWidget submenu;
|
MwWidget submenu;
|
||||||
|
|
||||||
MwMenu menu;
|
MwMenu menu;
|
||||||
|
|
||||||
|
long tick;
|
||||||
} wmframe_t;
|
} wmframe_t;
|
||||||
|
|
||||||
void loop_wm(void) {
|
void loop_wm(void) {
|
||||||
|
|
@ -153,10 +155,18 @@ static void apply_config(MwWidget wnd) {
|
||||||
static void maximize(MwWidget handle, void* user, void* client) {
|
static void maximize(MwWidget handle, void* user, void* client) {
|
||||||
wmframe_t* f = ((MwWidget)user)->opaque;
|
wmframe_t* f = ((MwWidget)user)->opaque;
|
||||||
MwRect rc;
|
MwRect rc;
|
||||||
|
int i;
|
||||||
|
|
||||||
set_focus_x(user);
|
set_focus_x(user);
|
||||||
|
|
||||||
if(f->maximized) {
|
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;
|
f->maximized = 0;
|
||||||
|
|
||||||
MwVaApply(handle,
|
MwVaApply(handle,
|
||||||
|
|
@ -170,6 +180,13 @@ static void maximize(MwWidget handle, void* user, void* client) {
|
||||||
MwNheight, f->old_size.height,
|
MwNheight, f->old_size.height,
|
||||||
NULL);
|
NULL);
|
||||||
} else {
|
} 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->maximized = 1;
|
||||||
|
|
||||||
f->old_point.x = MwGetInteger(user, MwNx);
|
f->old_point.x = MwGetInteger(user, MwNx);
|
||||||
|
|
@ -196,6 +213,7 @@ static void spawn_menu(MwWidget handle, void* user, void* client) {
|
||||||
MwWidget w = handle;
|
MwWidget w = handle;
|
||||||
wmframe_t* f;
|
wmframe_t* f;
|
||||||
MwPoint p;
|
MwPoint p;
|
||||||
|
long t;
|
||||||
|
|
||||||
while(w != NULL && strcmp(MwGetName(w), "frame") != 0) w = MwGetParent(w);
|
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.x = 0;
|
||||||
p.y = MwGetInteger(handle, MwNheight);
|
p.y = MwGetInteger(handle, MwNheight);
|
||||||
MwSubMenuAppear(f->submenu, f->menu, &p, 0);
|
MwSubMenuAppear(f->submenu, f->menu, &p, 0);
|
||||||
|
|
||||||
|
MwVaApply(f->menu_button,
|
||||||
|
MwNforceInverted, 1,
|
||||||
|
NULL);
|
||||||
} else {
|
} else {
|
||||||
MwDestroyWidget(f->submenu);
|
MwDestroyWidget(f->submenu);
|
||||||
f->submenu = NULL;
|
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) {
|
static void menu_menu(MwWidget handle, void* user, void* client) {
|
||||||
MwWidget w = handle;
|
MwWidget w = handle;
|
||||||
wmframe_t* f;
|
wmframe_t* f;
|
||||||
|
int i;
|
||||||
|
MwMenu m = client;
|
||||||
|
|
||||||
while(w != NULL && strcmp(MwGetName(w), "frame") != 0) w = MwGetParent(w);
|
while(w != NULL && strcmp(MwGetName(w), "frame") != 0) w = MwGetParent(w);
|
||||||
|
|
||||||
f = w->opaque;
|
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;
|
f->submenu = NULL;
|
||||||
|
MwVaApply(f->menu_button,
|
||||||
|
MwNforceInverted, 0,
|
||||||
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void apply_button(MwWidget widget, const char* str) {
|
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) {
|
if(f->submenu != NULL) {
|
||||||
MwDestroyWidget(f->submenu);
|
MwDestroyWidget(f->submenu);
|
||||||
f->submenu = NULL;
|
f->submenu = NULL;
|
||||||
|
|
||||||
|
MwVaApply(f->menu_button,
|
||||||
|
MwNforceInverted, 0,
|
||||||
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
f->dragging = 1;
|
f->dragging = 1;
|
||||||
|
|
@ -423,6 +480,8 @@ MwWidget wm_frame(int w, int h) {
|
||||||
f->iconify = MwLoadRaw(wnd, icon, 6, 6);
|
f->iconify = MwLoadRaw(wnd, icon, 6, 6);
|
||||||
free(icon);
|
free(icon);
|
||||||
|
|
||||||
|
f->tick = 0;
|
||||||
|
|
||||||
f->left = NULL;
|
f->left = NULL;
|
||||||
f->right = NULL;
|
f->right = NULL;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,7 @@ typedef struct window {
|
||||||
int working;
|
int working;
|
||||||
} window_t;
|
} window_t;
|
||||||
static window_t* windows = NULL;
|
static window_t* windows = NULL;
|
||||||
|
static Window* wnd = NULL;
|
||||||
|
|
||||||
static void* old_handler;
|
static void* old_handler;
|
||||||
static int error_happened = 0;
|
static int error_happened = 0;
|
||||||
|
|
@ -452,13 +453,23 @@ static int is_no_border(Window window) {
|
||||||
return 0;
|
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) {
|
void loop_x(void) {
|
||||||
XEvent ev;
|
XEvent ev;
|
||||||
Window root, parent;
|
Window root, parent;
|
||||||
Window* children;
|
Window* children;
|
||||||
unsigned int nchildren;
|
unsigned int nchildren;
|
||||||
int i;
|
int i;
|
||||||
Window* wnd = NULL;
|
|
||||||
|
|
||||||
begin_error();
|
begin_error();
|
||||||
|
|
||||||
|
|
@ -509,6 +520,8 @@ void loop_x(void) {
|
||||||
XRaiseWindow(xdisplay, w);
|
XRaiseWindow(xdisplay, w);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bring_up();
|
||||||
|
|
||||||
XAllowEvents(xdisplay, ReplayPointer, CurrentTime);
|
XAllowEvents(xdisplay, ReplayPointer, CurrentTime);
|
||||||
} else if(ev.type == MotionNotify && ev.xmotion.subwindow != None) {
|
} else if(ev.type == MotionNotify && ev.xmotion.subwindow != None) {
|
||||||
Window w = None, t = ev.xmotion.window;
|
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);
|
XAllowEvents(xdisplay, ReplayPointer, CurrentTime);
|
||||||
} else if(ev.type == FocusIn && ev.xfocus.window != focus) {
|
} else if(ev.type == FocusIn && ev.xfocus.window != focus) {
|
||||||
|
|
@ -628,7 +644,11 @@ void loop_x(void) {
|
||||||
|
|
||||||
XMapWindow(xdisplay, ev.xmaprequest.window);
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -726,7 +746,16 @@ void loop_x(void) {
|
||||||
int i;
|
int i;
|
||||||
XWindowAttributes xwa;
|
XWindowAttributes xwa;
|
||||||
if(!XGetWindowAttributes(xdisplay, ev.xmap.window, &xwa)) continue;
|
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++) {
|
for(i = 0; i < arrlen(windows); i++) {
|
||||||
if(windows[i].client == ev.xmap.window) {
|
if(windows[i].client == ev.xmap.window) {
|
||||||
|
|
@ -800,7 +829,7 @@ void loop_x(void) {
|
||||||
set_focus(w);
|
set_focus(w);
|
||||||
}
|
}
|
||||||
} else if(ev.type == ClientMessage) {
|
} 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]);
|
set_focus(ev.xclient.data.l[1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -819,14 +848,36 @@ void set_focus_x(MwWidget widget) {
|
||||||
|
|
||||||
ev.type = ClientMessage;
|
ev.type = ClientMessage;
|
||||||
ev.xclient.window = nofocus;
|
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.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;
|
ev.xclient.data.l[1] = windows[i].client;
|
||||||
|
|
||||||
XSendEvent(xdisplay, nofocus, False, 0, &ev);
|
XSendEvent(xdisplay, nofocus, False, 0, &ev);
|
||||||
|
|
||||||
XRaiseWindow(xdisplay, windows[i].frame->lowlevel->x11.window);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue