icon works
This commit is contained in:
parent
992a035e4e
commit
16e1bd9c89
5 changed files with 141 additions and 10 deletions
|
|
@ -49,6 +49,8 @@ int wm_content_width(int entire);
|
||||||
int wm_content_height(int entire);
|
int wm_content_height(int entire);
|
||||||
int wm_content_x(void);
|
int wm_content_x(void);
|
||||||
int wm_content_y(void);
|
int wm_content_y(void);
|
||||||
|
int wm_set_icon_by_name(MwWidget widget, const char* cat, const char* name);
|
||||||
|
void wm_set_icon(MwWidget widget, unsigned char* data, int width, int height);
|
||||||
|
|
||||||
/* config.c */
|
/* config.c */
|
||||||
extern xemil_t* wm_config;
|
extern xemil_t* wm_config;
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
<Button>
|
<Button>
|
||||||
<Left>
|
<Left>
|
||||||
<!-- Ordered from left to right -->
|
<!-- Ordered from left to right -->
|
||||||
<Close />
|
<Menu />
|
||||||
</Left>
|
</Left>
|
||||||
<Right>
|
<Right>
|
||||||
<!-- Ordered from right to left -->
|
<!-- Ordered from right to left -->
|
||||||
|
|
|
||||||
56
milkwm/wm.c
56
milkwm/wm.c
|
|
@ -14,6 +14,8 @@ typedef struct wmframe {
|
||||||
MwWidget* left;
|
MwWidget* left;
|
||||||
MwWidget* right;
|
MwWidget* right;
|
||||||
|
|
||||||
|
MwWidget menu_button;
|
||||||
|
|
||||||
MwLLPixmap maximize;
|
MwLLPixmap maximize;
|
||||||
MwLLPixmap restore;
|
MwLLPixmap restore;
|
||||||
MwLLPixmap iconify;
|
MwLLPixmap iconify;
|
||||||
|
|
@ -200,6 +202,8 @@ static void apply_button(MwWidget widget, const char* str) {
|
||||||
MwAddUserHandler(widget, MwNactivateHandler, maximize, w);
|
MwAddUserHandler(widget, MwNactivateHandler, maximize, w);
|
||||||
} else if(strcmp(str, "Iconify") == 0) {
|
} else if(strcmp(str, "Iconify") == 0) {
|
||||||
px = f->iconify;
|
px = f->iconify;
|
||||||
|
} else if(strcmp(str, "Menu") == 0) {
|
||||||
|
f->menu_button = widget;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(px != NULL) {
|
if(px != NULL) {
|
||||||
|
|
@ -321,6 +325,8 @@ MwWidget wm_frame(int w, int h) {
|
||||||
f->maximized = 0;
|
f->maximized = 0;
|
||||||
f->dragging = 0;
|
f->dragging = 0;
|
||||||
|
|
||||||
|
f->menu_button = NULL;
|
||||||
|
|
||||||
icon = malloc(10 * 6 * 4);
|
icon = malloc(10 * 6 * 4);
|
||||||
|
|
||||||
memset(icon, 0, 10 * 6 * 4);
|
memset(icon, 0, 10 * 6 * 4);
|
||||||
|
|
@ -414,6 +420,8 @@ MwWidget wm_frame(int w, int h) {
|
||||||
|
|
||||||
pthread_mutex_unlock(&xmutex);
|
pthread_mutex_unlock(&xmutex);
|
||||||
|
|
||||||
|
wm_set_icon_by_name(wnd, NULL, "unknown");
|
||||||
|
|
||||||
return wnd;
|
return wnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -443,6 +451,54 @@ void wm_set_name(MwWidget widget, const char* name) {
|
||||||
pthread_mutex_unlock(&xmutex);
|
pthread_mutex_unlock(&xmutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int wm_set_icon_by_name(MwWidget widget, const char* cat, const char* name) {
|
||||||
|
wmframe_t* f = widget->opaque;
|
||||||
|
MwLLPixmap px = NULL;
|
||||||
|
int st = 0;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&xmutex);
|
||||||
|
if(f->menu_button != NULL) {
|
||||||
|
char* p;
|
||||||
|
|
||||||
|
if((px = MwGetVoid(f->menu_button, MwNpixmap)) != NULL) {
|
||||||
|
MwLLDestroyPixmap(px);
|
||||||
|
px = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((p = MDEIconLookUp(cat == NULL ? "Applications" : cat, name, 16)) != NULL) {
|
||||||
|
px = MwLoadImage(f->menu_button, p);
|
||||||
|
|
||||||
|
free(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
MwSetVoid(f->menu_button, MwNpixmap, px);
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&xmutex);
|
||||||
|
|
||||||
|
if(px != NULL) st = 1;
|
||||||
|
|
||||||
|
return st;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wm_set_icon(MwWidget widget, unsigned char* data, int width, int height) {
|
||||||
|
wmframe_t* f = widget->opaque;
|
||||||
|
MwLLPixmap px = NULL;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&xmutex);
|
||||||
|
if(f->menu_button != NULL) {
|
||||||
|
if((px = MwGetVoid(f->menu_button, MwNpixmap)) != NULL) {
|
||||||
|
MwLLDestroyPixmap(px);
|
||||||
|
px = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
px = MwLoadRaw(f->menu_button, data, width, height);
|
||||||
|
|
||||||
|
MwSetVoid(f->menu_button, MwNpixmap, px);
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&xmutex);
|
||||||
|
}
|
||||||
|
|
||||||
static char tmp_bg[64];
|
static char tmp_bg[64];
|
||||||
|
|
||||||
MwLLPixmap lookup_col(MwWidget widget, const char* bgfg, const char* type, const char** bg) {
|
MwLLPixmap lookup_col(MwWidget widget, const char* bgfg, const char* type, const char** bg) {
|
||||||
|
|
|
||||||
|
|
@ -333,18 +333,88 @@ static int parent_eq(Window wnd, Window might_be_parent) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_name(Window wnd) {
|
static void set_stuff(Window wnd) {
|
||||||
Atom type;
|
Atom type;
|
||||||
int format;
|
int format;
|
||||||
unsigned long nitem, after;
|
unsigned long nitem, after;
|
||||||
unsigned char* buf = NULL;
|
unsigned char* buf = NULL;
|
||||||
Atom atom = XInternAtom(xdisplay, "WM_NAME", False);
|
Atom atom_name = XInternAtom(xdisplay, "WM_NAME", False);
|
||||||
Atom utf8 = XInternAtom(xdisplay, "UTF8_STRING", False);
|
Atom atom_icon = XInternAtom(xdisplay, "_NET_WM_ICON", False);
|
||||||
|
Atom utf8 = XInternAtom(xdisplay, "UTF8_STRING", False);
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for(i = 0; i < arrlen(windows); i++) {
|
for(i = 0; i < arrlen(windows); i++) {
|
||||||
if(windows[i].client == wnd) {
|
if(windows[i].client == wnd) {
|
||||||
if(XGetWindowProperty(xdisplay, wnd, atom, 0, 1024, False, AnyPropertyType, &type, &format, &nitem, &after, &buf) == Success && buf != NULL) {
|
XClassHint* ch = XAllocClassHint();
|
||||||
|
int def = 1;
|
||||||
|
int l = 0;
|
||||||
|
int wid = 2048, hei = 2048;
|
||||||
|
unsigned char* data = NULL;
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
l += 2;
|
||||||
|
if(def && XGetWindowProperty(xdisplay, wnd, atom_icon, l - 2, 2, False, XA_CARDINAL, &type, &format, &nitem, &after, &buf) == Success && buf != NULL) {
|
||||||
|
if(nitem == 2) {
|
||||||
|
long* b = (long*)buf;
|
||||||
|
int w = b[0], h = b[1];
|
||||||
|
|
||||||
|
l += w * h;
|
||||||
|
|
||||||
|
XFree(buf);
|
||||||
|
|
||||||
|
if(w <= 1024 && h <= 1024) {
|
||||||
|
if(w == 16 || h == 16 || w < wid || h < hei) {
|
||||||
|
if(data != NULL) free(data);
|
||||||
|
data = malloc(4 * w * h);
|
||||||
|
|
||||||
|
if(XGetWindowProperty(xdisplay, wnd, atom_icon, l - w * h, w * h, False, XA_CARDINAL, &type, &format, &nitem, &after, &buf) == Success && buf != NULL) {
|
||||||
|
if(nitem == w * h) {
|
||||||
|
int i;
|
||||||
|
b = (long*)buf;
|
||||||
|
for(i = 0; i < w * h; i++) {
|
||||||
|
data[4 * i + 0] = (b[i] >> 16) & 0xff;
|
||||||
|
data[4 * i + 1] = (b[i] >> 8) & 0xff;
|
||||||
|
data[4 * i + 2] = (b[i] >> 0) & 0xff;
|
||||||
|
data[4 * i + 3] = (b[i] >> 24) & 0xff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
XFree(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
wid = w;
|
||||||
|
hei = h;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
XFree(buf);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(def && data != NULL) {
|
||||||
|
wm_set_icon(windows[i].frame, data, wid, hei);
|
||||||
|
|
||||||
|
free(data);
|
||||||
|
|
||||||
|
def = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(def && XGetClassHint(xdisplay, wnd, ch)) {
|
||||||
|
if(wm_set_icon_by_name(windows[i].frame, NULL, ch->res_name)) def = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
XFree(ch);
|
||||||
|
|
||||||
|
if(def) {
|
||||||
|
wm_set_icon_by_name(windows[i].frame, NULL, "unknown");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(XGetWindowProperty(xdisplay, wnd, atom_name, 0, 1024, False, AnyPropertyType, &type, &format, &nitem, &after, &buf) == Success && buf != NULL) {
|
||||||
if(type == XA_STRING || type == utf8) wm_set_name(windows[i].frame, buf);
|
if(type == XA_STRING || type == utf8) wm_set_name(windows[i].frame, buf);
|
||||||
XFree(buf);
|
XFree(buf);
|
||||||
}
|
}
|
||||||
|
|
@ -409,7 +479,7 @@ void loop_x(void) {
|
||||||
|
|
||||||
arrput(windows, w);
|
arrput(windows, w);
|
||||||
|
|
||||||
set_name(w.client);
|
set_stuff(w.client);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
XFree(children);
|
XFree(children);
|
||||||
|
|
@ -617,7 +687,7 @@ void loop_x(void) {
|
||||||
} else {
|
} else {
|
||||||
arrput(windows, w);
|
arrput(windows, w);
|
||||||
|
|
||||||
set_name(w.client);
|
set_stuff(w.client);
|
||||||
}
|
}
|
||||||
|
|
||||||
XGetWindowAttributes(xdisplay, DefaultRootWindow(xdisplay), &xwar);
|
XGetWindowAttributes(xdisplay, DefaultRootWindow(xdisplay), &xwar);
|
||||||
|
|
@ -635,8 +705,8 @@ void loop_x(void) {
|
||||||
}
|
}
|
||||||
if(arrlen(windows) == i) continue;
|
if(arrlen(windows) == i) continue;
|
||||||
|
|
||||||
if(ev.xproperty.atom == XInternAtom(xdisplay, "WM_NAME", False)) {
|
if(ev.xproperty.atom == XInternAtom(xdisplay, "WM_NAME", False) || ev.xproperty.atom == XInternAtom(xdisplay, "WM_CLASS", False) || ev.xproperty.atom == XInternAtom(xdisplay, "_NET_WM_ICON", False)) {
|
||||||
set_name(windows[i].client);
|
set_stuff(windows[i].client);
|
||||||
}
|
}
|
||||||
} else if(ev.type == MapNotify) {
|
} else if(ev.type == MapNotify) {
|
||||||
int i;
|
int i;
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,9 @@
|
||||||
<Launcher ID="2">
|
<Launcher ID="2">
|
||||||
<Execute Icon="firefox">firefox</Execute>
|
<Execute Icon="firefox">firefox</Execute>
|
||||||
<Execute Icon="terminal">uxterm</Execute>
|
<Execute Icon="terminal">uxterm</Execute>
|
||||||
|
<Execute Icon="gimp">gimp</Execute>
|
||||||
|
<Execute Icon="unknown">xmms</Execute>
|
||||||
|
<Execute Icon="mbiff">mbiff</Execute>
|
||||||
</Launcher>
|
</Launcher>
|
||||||
|
|
||||||
<Separator ID="3" />
|
<Separator ID="3" />
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue