/** Set statustext *\param str Statustext string */ static void set_statustext(int s, char *str) { int i; char atom_name[64]; if(!str) return; if(s == -1) { for(i = 0; i < screen_count(); ++i) { sprintf(atom_name, "_WMFS_STATUSTEXT_%d", i); XChangeProperty(dpy, ROOT, ATOM(atom_name), ATOM("UTF8_STRING"), 8, PropModeReplace, (uchar*)str, strlen(str)); ewmh_send_message(ROOT, ROOT, atom_name, 0, 0, 0, 0, True); } } else { sprintf(atom_name, "_WMFS_STATUSTEXT_%d", s); XChangeProperty(dpy, ROOT, ATOM(atom_name), ATOM("UTF8_STRING"), 8, PropModeReplace, (uchar*)str, strlen(str)); ewmh_send_message(ROOT, ROOT, atom_name, 0, 0, 0, 0, True); } return; }
/** Get information about wmfs *\param info Type of information in a string */ void getinfo(char *info) { if(!check_wmfs_running()) return; ewmh_send_message(ROOT, ROOT, "_WMFS_UPDATE_HINTS", 0, 0, 0, 0, True); if(!strcmp(info, "tag")) getinfo_tag(); else if(!strcmp(info, "screen")) getinfo_screen(); else if(!strcmp(info, "layout")) getinfo_layout(); else if(!strcmp(info, "mwfact")) getinfo_mwfact(); else if(!strcmp(info, "nmaster")) getinfo_nmaster(); else if(!strcmp(info, "help")) printf("Argument list for wmfs -g options:\n" " tag Show current tag number and name, and tag list.\n" " screen Show current screen and screens number.\n" " layout Show current layout name.\n" " mwfact Show mwfact of current tag.\n" " nmaster Show nmaster of current tag.\n"); else warnx("Unknow info argument '%s'\nTry 'wmfs -g help'", info); return; }
void systray_add(Window win) { Systray *s; if(!conf.systray.active) return; s = xcalloc(1, sizeof(Systray)); s->win = win; s->geo.height = infobar[conf.systray.screen].bar->geo.height; s->geo.width = TRAY_DWIDTH; setwinstate(s->win, WithdrawnState); XSelectInput(dpy, s->win, StructureNotifyMask | PropertyChangeMask| EnterWindowMask | FocusChangeMask); XReparentWindow(dpy, s->win, traywin, 0, 0); ewmh_send_message(s->win, s->win, "_XEMBED", CurrentTime, XEMBED_EMBEDDED_NOTIFY, 0, traywin, 0); /* Attach */ if(trayicons) trayicons->prev = s; s->next = trayicons; trayicons = s; return; }
void systray_state(Systray *s) { long flags; int code = 0; if(!(flags = ewmh_get_xembed_state(s->win)) || !conf.systray.active) return; if(flags & XEMBED_MAPPED) { code = XEMBED_WINDOW_ACTIVATE; XMapRaised(dpy, s->win); setwinstate(s->win, NormalState); } else { code = XEMBED_WINDOW_DEACTIVATE; XUnmapWindow(dpy, s->win); setwinstate(s->win, WithdrawnState); } ewmh_send_message(s->win, s->win, "_XEMBED", CurrentTime, code, 0, 0, 0); return; }
/** Update status script by ewmh hint */ static void update_status(void) { if(!check_wmfs_running()) return; ewmh_send_message(ROOT, ROOT, "_WMFS_UPDATE_STATUS", 0, 0, 0, 0, True); return; }
void client_update_current(Client* c) { Client* tmp; if ((head == NULL) || (c == NULL)) return; current = c; for (tmp = head; tmp; tmp = tmp->next) { if (tmp == current) { tmp->focus = True; ewmh_send_message(tmp, WM_PROTOCOLS, WM_TAKE_FOCUS); ewmh_send_message(tmp, WM_PROTOCOLS, NET_ACTIVE_WINDOW); XChangeProperty(display, root, atom[NET_ACTIVE_WINDOW], XA_WINDOW, 32, PropModeReplace, (unsigned char*)&tmp->win, 1); XRaiseWindow(display, tmp->win); } else tmp->focus = False; client_decorate(tmp); } }
static void event_mapnotify(XEvent *e) { XMapEvent *ev = &e->xmap; struct client *c; struct _systray *s; if(ev->window != ev->event && !ev->send_event) return; if((c = client_gb_win(ev->window))) client_map(c); else if((s = systray_find(ev->window))) { ewmh_set_wm_state(s->win, NormalState); ewmh_send_message(s->win, s->win, "_XEMBED", CurrentTime, XEMBED_WINDOW_ACTIVATE, 0, 0, 0); } }
/** MapRequest handle event * \param ev XMapRequestEvent pointer */ static void maprequest(XMapRequestEvent *ev) { XWindowAttributes at; Systray *s; CHECK(XGetWindowAttributes(dpy, ev->window, &at)); CHECK(!at.override_redirect); if((s = systray_find(ev->window))) { ewmh_send_message(s->win, s->win, "_XEMBED", CurrentTime, XEMBED_WINDOW_ACTIVATE, 0, 0, 0); systray_update(); } else if(!client_gb_win(ev->window)) client_manage(ev->window, &at, True); return; }
/** MapNotify handle event * \param ev XMapEvent pointer */ static void mapnotify(XMapEvent *ev) { Client *c; Systray *s; if(ev->window != ev->event && !ev->send_event) return; if((c = client_gb_win(ev->window))) setwinstate(c->win, NormalState); else if((s = systray_find(ev->window))) { setwinstate(s->win, NormalState); ewmh_send_message(s->win, s->win, "_XEMBED", CurrentTime, XEMBED_WINDOW_ACTIVATE, 0, 0, 0); } return; }
Bool systray_acquire(void) { XSetWindowAttributes wattr; if(!conf.systray.active || traywin) return False; if(XGetSelectionOwner(dpy, net_atom[net_system_tray_s]) != None) { warnx("Can't initialize system tray: owned by another process"); return False; } /* Init traywin window */ wattr.event_mask = ButtonPressMask | ExposureMask; wattr.override_redirect = True; wattr.background_pixmap = ParentRelative; wattr.background_pixel = conf.colors.bar; traywin = XCreateSimpleWindow(dpy, infobar[conf.systray.screen].bar->win, -1, -1, 1, 1, 0, 0, conf.colors.bar); XChangeWindowAttributes(dpy, traywin, CWEventMask | CWOverrideRedirect | CWBackPixel, &wattr); XSelectInput(dpy, traywin, KeyPressMask | ButtonPressMask); XMapRaised(dpy, traywin); XSetSelectionOwner(dpy, net_atom[net_system_tray_s], traywin, CurrentTime); if(XGetSelectionOwner(dpy, net_atom[net_system_tray_s]) != traywin) { systray_freeicons(); warnx("System tray: can't get systray manager"); return False; } ewmh_send_message(ROOT, ROOT, "MANAGER", CurrentTime, net_atom[net_system_tray_s], traywin, 0, 0); XSync(dpy, False); return True; }
static void event_maprequest(XEvent *e) { XMapRequestEvent *ev = &e->xmaprequest; XWindowAttributes at; struct _systray *s; /* Which windows to manage */ if(!XGetWindowAttributes(EVDPY(e), ev->window, &at) || at.override_redirect) return; if(!client_gb_win(ev->window)) client_new(ev->window, &at, false); else if((s = systray_find(ev->window))) { ewmh_send_message(s->win, s->win, "_XEMBED", CurrentTime, XEMBED_WINDOW_ACTIVATE, 0, 0, 0); systray_update(); } }
/** Execute an uicb function *\param func Function name *\param cmd Function's command *\return 0 if there is an error */ void exec_uicb_function(char *func, char *cmd) { /* Check if wmfs is running (this function is executed when wmfs is already running normally...) */ if(!check_wmfs_running()) return; XChangeProperty(dpy, ROOT, ATOM("_WMFS_FUNCTION"), ATOM("UTF8_STRING"), 8, PropModeReplace, (uchar*)func, strlen(func)); if(cmd == NULL) cmd = ""; XChangeProperty(dpy, ROOT, ATOM("_WMFS_CMD"), ATOM("UTF8_STRING"), 8, PropModeReplace, (uchar*)cmd, strlen(cmd)); ewmh_send_message(ROOT, ROOT, "_WMFS_FUNCTION", 0, 0, 0, 0, True); return; }
static void event_clientmessageevent(XEvent *e) { XClientMessageEvent *ev = &e->xclient; struct client *c; struct _systray *sy; int type = 0; while(type < net_last && W->net_atom[type] != ev->message_type) ++type; /* * Systray message * _NET_WM_SYSTRAY_TRAY_OPCODE */ if(ev->window == W->systray.win && type == net_system_tray_opcode) { if(ev->data.l[1] == XEMBED_EMBEDDED_NOTIFY) { systray_add(ev->data.l[2]); systray_update(); } else if(ev->data.l[1] == XEMBED_REQUEST_FOCUS) { if((sy = systray_find(ev->data.l[2]))) ewmh_send_message(sy->win, sy->win, "_XEMBED", XEMBED_FOCUS_IN, XEMBED_FOCUS_CURRENT, 0, 0, 0); } } else if(ev->window == W->root) { /* WMFS message */ if(ev->data.l[4]) { /* Manage _WMFS_FUNCTION && _WMFS_CMD */ if(type == wmfs_function || type == wmfs_cmd) { int d; long unsigned int len; unsigned char *ret = NULL, *ret_cmd = NULL; void (*func)(Uicb); if(XGetWindowProperty(EVDPY(e), W->root, W->net_atom[wmfs_function], 0, 65536, False, W->net_atom[utf8_string], (Atom*)&d, &d, (long unsigned int*)&d, (long unsigned int*)&d, &ret) == Success && ret && ((func = uicb_name_func((char*)ret)))) { if(XGetWindowProperty(EVDPY(e), W->root, W->net_atom[wmfs_cmd], 0, 65536, False, W->net_atom[utf8_string], (Atom*)&d, &d, &len, (long unsigned int*)&d, &ret_cmd) == Success && len && ret_cmd) { func((Uicb)ret_cmd); XFree(ret_cmd); } else func(NULL); XFree(ret); } } } if(type == net_active_window) if((sy = systray_find(ev->data.l[0]))) XSetInputFocus(W->dpy, sy->win, RevertToNone, CurrentTime); } switch(type) { /* _NET_WM_STATE */ case net_wm_state: if((c = client_gb_win(ev->window))) ewmh_manage_state(ev->data.l, c); break; /* _NET_CLOSE_WINDOW */ case net_close_window: if((c = client_gb_win(ev->window))) client_close(c); break; /* _NET_WM_DESKTOP */ case net_wm_desktop: break; } }
/* ClientMessage handle event *\param ev XClientMessageEvent pointer */ static void clientmessageevent(XClientMessageEvent *ev) { Client *c; Systray *sy; int s, i, mess_t = 0; Atom rt; int rf; ulong ir, il; uchar *ret = NULL; uchar *ret_cmd = NULL; void (*func)(uicb_t); if(ev->format != 32) return; s = screen_count(); for(i = 0; i < net_last + s; ++i) if(net_atom[i] == ev->message_type) mess_t = i; if(ev->window == ROOT) { /* Manage _NET_CURRENT_DESKTOP */ if(mess_t == net_current_desktop && ev->data.l[0] >= 0 && ev->data.l[0] < conf.ntag[selscreen]) tag_set((int)(ev->data.l[0] + 1)); /* Manage _WMFS_SET_SCREEN */ if(mess_t == wmfs_set_screen && ev->data.l[0] >= 0 && ev->data.l[0] <= s) screen_set_sel((int)(ev->data.l[0])); /* Manage _NET_ACTIVE_WINDOW */ else if(mess_t == net_active_window) { if((c = client_gb_win(ev->window))) client_focus(c); else if((sy = systray_find(ev->data.l[0]))) XSetInputFocus(dpy, sy->win, RevertToNone, CurrentTime); } } else if(ev->window == traywin) { /* Manage _NET_WM_SYSTEM_TRAY_OPCODE */ if(mess_t == net_wm_system_tray_opcode) { if(ev->data.l[1] == XEMBED_EMBEDDED_NOTIFY) { systray_add(ev->data.l[2]); systray_update(); } else if(ev->data.l[1] == XEMBED_REQUEST_FOCUS) if((sy = systray_find(ev->data.l[2]))) ewmh_send_message(sy->win, sy->win, "_XEMBED", XEMBED_FOCUS_IN, XEMBED_FOCUS_CURRENT, 0, 0, 0); } } /* Manage _NET_WM_STATE */ if(mess_t == net_wm_state) if((c = client_gb_win(ev->window))) ewmh_manage_net_wm_state(ev->data.l, c); /* Manage _NET_CLOSE_WINDOW */ if(mess_t == net_close_window) if((c = client_gb_win(ev->window))) client_kill(c); /* Manage _NET_WM_DESKTOP */ if(mess_t == net_wm_desktop) if((c = client_gb_win(ev->window)) && ev->data.l[0] != (long)0xFFFFFFFF) tag_transfert(c, ev->data.l[0]); /* Manage _WMFS_STATUSTEXT_x */ if(mess_t >= wmfs_statustext && ev->data.l[4] == True) { if(XGetWindowProperty(dpy, ROOT, net_atom[mess_t], 0, 4096, False, net_atom[utf8_string], &rt, &rf, &ir, &il, &ret) == Success) { statustext_handle(mess_t - wmfs_statustext, (char*)ret); XFree(ret); } } /* Manage _WMFS_FUNCTION && _WMFS_CMD */ if((mess_t == wmfs_function && ev->data.l[4] == True) || (mess_t == wmfs_cmd && ev->data.l[4] == True)) { XGetWindowProperty(dpy, ROOT, net_atom[wmfs_function], 0, 4096, False, net_atom[utf8_string], &rt, &rf, &ir, &il, &ret); XGetWindowProperty(dpy, ROOT, net_atom[wmfs_cmd], 0, 4096, False, net_atom[utf8_string], &rt, &rf, &ir, &il, &ret_cmd); if((func = name_to_func((char*)ret, func_list))) func((uicb_t)ret_cmd); XFree(ret_cmd); XFree(ret); } /* Manage _WMFS_UPDATE_HINTS */ if(mess_t == wmfs_update_hints) { ewmh_get_number_of_desktop(); ewmh_update_current_tag_prop(); ewmh_get_client_list(); ewmh_get_desktop_names(); ewmh_set_desktop_geometry(); screen_count(); screen_get_sel(); } if(mess_t == wmfs_update_status && estatus) spawn(conf.status_path); return; }