123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335 |
- /*
- * wmfs2 by Martin Duquesnoy <xorg62@gmail.com> { for(i = 2011; i < 2111; ++i) ©(i); }
- * For license, see COPYING.
- */
- #include "ewmh.h"
- #include "util.h"
- #include "screen.h"
- #include "client.h"
- /* Taken From standards.freedesktop.org */
- #define _NET_WM_STATE_REMOVE 0 /* remove/unset property */
- #define _NET_WM_STATE_ADD 1 /* add/set property */
- #define _NET_WM_STATE_TOGGLE 2 /* toggle property */
- void
- ewmh_init(void)
- {
- int b = 1;
- W->net_atom = xcalloc(net_last, sizeof(Atom));
- /* EWMH hints */
- W->net_atom[wm_state] = ATOM("WM_STATE");
- W->net_atom[wm_class] = ATOM("WM_CLASS");
- W->net_atom[wm_name] = ATOM("WM_NAME");
- W->net_atom[net_supported] = ATOM("_NET_SUPPORTED");
- W->net_atom[net_client_list] = ATOM("_NET_CLIENT_LIST");
- W->net_atom[net_frame_extents] = ATOM("_NET_FRAME_EXTENTS");
- W->net_atom[net_number_of_desktops] = ATOM("_NET_NUMBER_OF_DESKTOPS");
- W->net_atom[net_current_desktop] = ATOM("_NET_CURRENT_DESKTOP");
- W->net_atom[net_desktop_names] = ATOM("_NET_DESKTOP_NAMES");
- W->net_atom[net_desktop_geometry] = ATOM("_NET_DESKTOP_GEOMETRY");
- W->net_atom[net_active_window] = ATOM("_NET_ACTIVE_WINDOW");
- W->net_atom[net_close_window] = ATOM("_NET_CLOSE_WINDOW");
- W->net_atom[net_wm_name] = ATOM("_NET_WM_NAME");
- W->net_atom[net_wm_pid] = ATOM("_NET_WM_PID");
- W->net_atom[net_wm_desktop] = ATOM("_NET_WM_DESKTOP");
- W->net_atom[net_showing_desktop] = ATOM("_NET_SHOWING_DESKTOP");
- W->net_atom[net_wm_icon_name] = ATOM("_NET_WM_ICON_NAME");
- W->net_atom[net_wm_window_type] = ATOM("_NET_WM_WINDOW_TYPE");
- W->net_atom[net_supporting_wm_check] = ATOM("_NET_SUPPORTING_WM_CHECK");
- W->net_atom[net_wm_window_opacity] = ATOM("_NET_WM_WINDOW_OPACITY");
- W->net_atom[net_wm_window_type_normal] = ATOM("_NET_WM_WINDOW_TYPE_NORMAL");
- W->net_atom[net_wm_window_type_desktop] = ATOM("_NET_WM_WINDOW_TYPE_DESKTOP");
- W->net_atom[net_wm_window_type_dock] = ATOM("_NET_WM_WINDOW_TYPE_DOCK");
- W->net_atom[net_wm_window_type_splash] = ATOM("_NET_WM_WINDOW_TYPE_SPLASH");
- W->net_atom[net_wm_window_type_dialog] = ATOM("_NET_WM_WINDOW_TYPE_DIALOG");
- W->net_atom[net_wm_icon] = ATOM("_NET_WM_ICON");
- W->net_atom[net_wm_state] = ATOM("_NET_WM_STATE");
- W->net_atom[net_wm_state_fullscreen] = ATOM("_NET_WM_STATE_FULLSCREEN");
- W->net_atom[net_wm_state_sticky] = ATOM("_NET_WM_STATE_STICKY");
- W->net_atom[net_wm_state_demands_attention] = ATOM("_NET_WM_STATE_DEMANDS_ATTENTION");
- W->net_atom[net_wm_state_hidden] = ATOM("_NET_WM_STATE_HIDDEN");
- W->net_atom[net_system_tray_s] = ATOM("_NET_SYSTEM_TRAY_S0");
- W->net_atom[net_system_tray_opcode] = ATOM("_NET_SYSTEM_TRAY_OPCODE");
- W->net_atom[net_system_tray_message_data] = ATOM("_NET_SYSTEM_TRAY_MESSAGE_DATA");
- W->net_atom[net_system_tray_visual] = ATOM("_NET_SYSTEM_TRAY_VISUAL");
- W->net_atom[net_system_tray_orientation] = ATOM("_NET_SYSTEM_TRAY_ORIENTATION");
- W->net_atom[xembed] = ATOM("_XEMBED");
- W->net_atom[xembedinfo] = ATOM("_XEMBED_INFO");
- W->net_atom[manager] = ATOM("MANAGER");
- W->net_atom[utf8_string] = ATOM("UTF8_STRING");
- /* WMFS hints */
- W->net_atom[wmfs_running] = ATOM("_WMFS_RUNNING");
- W->net_atom[wmfs_focus] = ATOM("_WMFS_FOCUS");
- W->net_atom[wmfs_update_hints] = ATOM("_WMFS_UPDATE_HINTS");
- W->net_atom[wmfs_set_screen] = ATOM("_WMFS_SET_SCREEN");
- W->net_atom[wmfs_screen_count] = ATOM("_WMFS_SCREEN_COUNT");
- W->net_atom[wmfs_current_tag] = ATOM("_WMFS_CURRENT_TAG");
- W->net_atom[wmfs_tag_list] = ATOM("_WMFS_TAG_LIST");
- W->net_atom[wmfs_current_screen] = ATOM("_WMFS_CURRENT_SCREEN");
- W->net_atom[wmfs_current_layout] = ATOM("_WMFS_CURRENT_LAYOUT");
- W->net_atom[wmfs_function] = ATOM("_WMFS_FUNCTION");
- W->net_atom[wmfs_cmd] = ATOM("_WMFS_CMD");
- XChangeProperty(W->dpy, W->root, W->net_atom[net_supported], XA_ATOM, 32,
- PropModeReplace, (unsigned char*)W->net_atom, net_last);
- XChangeProperty(W->dpy, W->root, W->net_atom[wmfs_running], XA_CARDINAL, 32,
- PropModeReplace, (unsigned char*)&b, 1);
- /* Set _NET_SUPPORTING_WM_CHECK */
- XChangeProperty(W->dpy, W->root, W->net_atom[net_supporting_wm_check], XA_WINDOW, 32,
- PropModeReplace, (unsigned char*)&W->root, 1);
- XChangeProperty(W->dpy, W->root, ATOM("WM_CLASS"), XA_STRING, 8,
- PropModeReplace, (unsigned char*)&"wmfs", 4);
- XChangeProperty(W->dpy, W->root, W->net_atom[net_wm_name], W->net_atom[utf8_string], 8,
- PropModeReplace, (unsigned char*)&"wmfs2", 5);
- /*
- * Set _NET_WM_PID
- XChangeProperty(W->dpy, W->root, W->net_atom[net_wm_pid], XA_CARDINAL, 32,
- PropModeReplace, (unsigned char*)&pid, 1);
- * Set _NET_SHOWING_DESKTOP
- XChangeProperty(W->dpy, W->root, W->net_atom[net_showing_desktop], XA_CARDINAL, 32,
- PropModeReplace, (unsigned char*)&showing_desk, 1);
- */
- }
- void
- ewmh_set_wm_state(Window w, int state)
- {
- unsigned char d[] = { state, None };
- XChangeProperty(W->dpy, w, W->net_atom[wm_state],
- W->net_atom[wm_state], 32, PropModeReplace, d, 2);
- }
- /*
- * _NET_CLIENT_LIST
- */
- void
- ewmh_get_client_list(void)
- {
- Window *list;
- struct client *c;
- int win_n = 0;
- SLIST_FOREACH(c, &W->h.client, next)
- ++win_n;
- list = xcalloc(win_n, sizeof(Window));
- win_n = 0;
- SLIST_FOREACH(c, &W->h.client, next)
- list[win_n++] = c->win;
- XChangeProperty(W->dpy, W->root, W->net_atom[net_client_list], XA_WINDOW, 32,
- PropModeReplace, (unsigned char *)list, win_n);
- XFree(list);
- }
- /*
- * Get xembed state
- */
- long
- ewmh_get_xembed_state(Window win)
- {
- Atom rf;
- int f;
- long ret = 0;
- unsigned long n, il;
- unsigned char *data = NULL;
- if(XGetWindowProperty(W->dpy, win, W->net_atom[xembedinfo], 0L, 2, False,
- W->net_atom[xembedinfo], &rf, &f, &n, &il, &data) != Success)
- return 0;
- if(rf == W->net_atom[xembedinfo] && n == 2)
- ret = (long)data[1];
- if(n && data)
- XFree(data);
- return ret;
- }
- void
- ewmh_update_wmfs_props(void)
- {
- struct screen *s;
- int i, ns = 0;
- long *cts = NULL;
- SLIST_FOREACH(s, &W->h.screen, next)
- ++ns;
- cts = xcalloc(ns, sizeof(long));
- for(i = 0; i < ns; ++i)
- {
- s = screen_gb_id(i);
- cts[i] = (s->seltag ? s->seltag->id : 0);
- }
- XChangeProperty(W->dpy, W->root, W->net_atom[wmfs_current_tag], XA_CARDINAL, 32,
- PropModeReplace, (unsigned char*)cts, ns);
- if(W->client)
- XChangeProperty(W->dpy, W->root, W->net_atom[wmfs_focus], XA_WINDOW, 32,
- PropModeReplace, (unsigned char*)&W->client->win, 1);
- free(cts);
- }
- void
- ewmh_manage_state(long data[], struct client *c)
- {
- /* _NET_WM_STATE_FULLSCREEN */
- if(data[1] == (long)W->net_atom[net_wm_state_fullscreen]
- || data[2] == (long)W->net_atom[net_wm_state_fullscreen])
- {
- if(data[0] == _NET_WM_STATE_ADD
- || (data[0] == _NET_WM_STATE_TOGGLE && !(c->flags & CLIENT_FULLSCREEN)))
- {
- c->flags |= CLIENT_FULLSCREEN;
- XChangeProperty(W->dpy, c->win, W->net_atom[net_wm_state], XA_ATOM, 32, PropModeReplace,
- (unsigned char*)&W->net_atom[net_wm_state_fullscreen], 1);
- XReparentWindow(W->dpy, c->win, W->root, c->screen->geo.x, c->screen->geo.y);
- XResizeWindow(W->dpy, c->win, c->screen->geo.w, c->screen->geo.h);
- if(c->tag)
- client_focus(c);
- XRaiseWindow(W->dpy, c->win);
- }
- else
- {
- c->flags &= ~CLIENT_FULLSCREEN;
- XChangeProperty(W->dpy, c->win, W->net_atom[net_wm_state], XA_ATOM, 32, PropModeReplace,
- (unsigned char*)0, 0);
- XReparentWindow(W->dpy, c->win, c->frame, c->wgeo.x, c->wgeo.y);
- if(c->flags & CLIENT_FREE)
- client_moveresize(c, &c->geo);
- else
- layout_fix_hole(c);
- }
- }
- }
- void
- ewmh_manage_state_sticky(struct client *c)
- {
- Atom *atom, rf;
- int f;
- unsigned long n, il, i;
- unsigned char *data = NULL;
- if(XGetWindowProperty(W->dpy, c->win, W->net_atom[net_wm_state], 0L, 0x7FFFFFFFL, false,
- XA_ATOM, &rf, &f, &n, &il, &data) == Success && n)
- {
- atom = (Atom*)data;
- for(i = 0; i < n; ++i)
- {
- /* manage _NET_WM_STATE_STICKY */
- if(atom[i] == W->net_atom[net_wm_state_sticky])
- {
- c->flags |= CLIENT_STICKY;
- c->flags |= CLIENT_FREE;
- client_place_at_mouse(c);
- break;
- }
- }
- XFree(data);
- }
- }
- void
- ewmh_manage_window_type(struct client *c)
- {
- Atom *atom, rf;
- int f;
- unsigned long n, il, i;
- unsigned char *data = NULL;
- long ldata[5] = { _NET_WM_STATE_ADD };
- if(XGetWindowProperty(W->dpy, c->win, W->net_atom[net_wm_window_type], 0L, 0x7FFFFFFFL,
- False, XA_ATOM, &rf, &f, &n, &il, &data) == Success && n)
- {
- atom = (Atom*)data;
- for(i = 0; i < n; ++i)
- {
- /* MANAGE _NET_WM_WINDOW_TYPE_DIALOG */
- if(atom[i] == W->net_atom[net_wm_window_type_dialog])
- c->flags |= CLIENT_FREE;
- }
- XFree(data);
- }
- /* _NET_WM_STATE at window mangement */
- if(XGetWindowProperty(W->dpy, c->win, W->net_atom[net_wm_state], 0L, 0x7FFFFFFFL, false,
- XA_ATOM, &rf, &f, &n, &il, &data) == Success && n)
- {
- atom = (Atom*)data;
- for(i = 0; i < n; ++i)
- {
- ldata[1] = atom[i];
- ewmh_manage_state(ldata, c);
- }
- XFree(data);
- }
- }
- bool
- ewmh_manage_window_type_desktop(Window win)
- {
- Atom *atom, rf;
- int f;
- unsigned long n, il, i;
- unsigned char *data = NULL;
- bool is_desktop = false;
- if(XGetWindowProperty(W->dpy, win, W->net_atom[net_wm_window_type], 0L, 0x7FFFFFFF,
- False, XA_ATOM, &rf, &f, &n, &il, &data) == Success && n)
- {
- atom = (Atom*)data;
- for(i = 0; i < n; ++i)
- {
- /* If it is a _NET_WM_WINDOW_TYPE_DESKTOP window */
- if(atom[i] == W->net_atom[net_wm_window_type_desktop])
- {
- /* map it, but don't manage it */
- XMapWindow(W->dpy, win);
- XMapSubwindows(W->dpy, win);
- is_desktop = true;
- break;
- }
- }
- XFree(data);
- }
- return is_desktop;
- }
|