123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439 |
- /*
- * wmfs2 by Martin Duquesnoy <xorg62@gmail.com> { for(i = 2011; i < 2111; ++i) ©(i); }
- * For license, see COPYING.
- */
- #include "event.h"
- #include "ewmh.h"
- #include "config.h"
- #include "util.h"
- #include "wmfs.h"
- #include "client.h"
- #include "barwin.h"
- #include "screen.h"
- #include "systray.h"
- #include "infobar.h"
- #define EVDPY(e) (e)->xany.display
- #define MOUSE_DO_BIND(m) \
- if(m->button == ev->button) \
- if(!m->use_area || (m->use_area && INAREA(ev->x, ev->y, m->area))) \
- if(m->func) \
- m->func(m->cmd);
- static void
- event_buttonpress(XEvent *e)
- {
- XButtonEvent *ev = &e->xbutton;
- struct mousebind *m;
- struct barwin *b;
- struct client *c;
- screen_update_sel();
- status_flush_surface();
- SLIST_FOREACH(b, &W->h.barwin, next)
- if(b->win == ev->window)
- {
- W->last_clicked_barwin = b;
- SLIST_FOREACH(m, &b->mousebinds, next)
- MOUSE_DO_BIND(m);
- SLIST_FOREACH(m, &b->statusmousebinds, next)
- MOUSE_DO_BIND(m);
- break;
- }
- if((c = client_gb_win(ev->window)) && c != W->client
- && ev->button == 1 && W->cfocus & CFOCUS_CLICK)
- client_focus(c);
- }
- static void
- event_enternotify(XEvent *e)
- {
- XCrossingEvent *ev = &e->xcrossing;
- struct client *c;
- if((ev->mode != NotifyNormal
- || ev->detail == NotifyInferior)
- && ev->window != W->root)
- return;
- if(ev->window == W->systray.win || systray_find(ev->window))
- return;
- if((c = client_gb_win(ev->window))
- || (c = client_gb_frame(ev->window)))
- {
- if(c->flags & CLIENT_IGNORE_ENTER)
- c->flags ^= CLIENT_IGNORE_ENTER;
- else if(c->tag->flags & TAG_IGNORE_ENTER)
- c->tag->flags ^= TAG_IGNORE_ENTER;
- else if(c != W->client && !(c->flags & CLIENT_TABBED)
- && W->cfocus & CFOCUS_ENTER)
- client_focus(c);
- }
- }
- 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)
- {
- Atom rt;
- int d;
- long unsigned int len, il;
- 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], &rt, &d,
- &len, &il, &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], &rt, &d,
- &len, &il, &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;
- }
- }
- static void
- event_configureevent(XEvent *e)
- {
- XConfigureRequestEvent *ev = &e->xconfigurerequest;
- XWindowChanges wc;
- struct client *c;
- if((c = client_gb_win(ev->window)))
- {
- if(c->flags & CLIENT_FREE)
- {
- if(ev->value_mask & CWX)
- c->geo.x = ev->x;
- if(ev->value_mask & CWY)
- c->geo.y = ev->y - c->tbarw - c->border - c->border;
- if(ev->value_mask & CWWidth)
- c->geo.w = ev->width + c->border + c->border;
- if(ev->value_mask & CWHeight)
- c->geo.h = ev->height + c->tbarw + c->border;
- client_moveresize(c, &c->geo);
- }
- else
- {
- if(ev->value_mask & CWWidth)
- _fac_resize(c, Right, ev->width - c->wgeo.w);
- if(ev->value_mask & CWHeight)
- _fac_resize(c, Bottom, ev->height - c->wgeo.h);
- client_apply_tgeo(c->tag);
- }
- }
- else
- {
- wc.x = ev->x;
- wc.y = ev->y;
- wc.width = ev->width;
- wc.height = ev->height;
- wc.border_width = ev->border_width;
- wc.sibling = ev->above;
- wc.stack_mode = ev->detail;
- XConfigureWindow(EVDPY(e), ev->window, ev->value_mask, &wc);
- }
- }
- static void
- event_destroynotify(XEvent *e)
- {
- XDestroyWindowEvent *ev = &e->xdestroywindow;
- struct client *c;
- struct _systray *s;
- if((c = client_gb_win(ev->window)))
- client_remove(c);
- else if((s = systray_find(ev->window)))
- {
- ewmh_set_wm_state(s->win, WithdrawnState);
- systray_del(s);
- systray_update();
- }
- }
- static void
- event_focusin(XEvent *e)
- {
- if(W->client
- && e->xfocus.window != W->client->win
- && e->xfocus.window != W->client->frame)
- client_focus(W->client);
- }
- 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
- || ewmh_manage_window_type_desktop(ev->window)
- || ewmh_manage_state_sticky(ev->window))
- 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();
- }
- }
- static void
- event_mappingnotify(XEvent *e)
- {
- XMappingEvent *ev = &e->xmapping;
- XRefreshKeyboardMapping(ev);
- if(ev->request == MappingKeyboard)
- wmfs_grab_keys();
- }
- static void
- event_propertynotify(XEvent *e)
- {
- XPropertyEvent *ev = &e->xproperty;
- XWMHints *h;
- struct client *c;
- struct _systray *s;
- if(ev->state == PropertyDelete)
- return;
- if((c = client_gb_win(ev->window)))
- {
- switch(ev->atom)
- {
- case XA_WM_TRANSIENT_FOR:
- break;
- case XA_WM_NORMAL_HINTS:
- client_get_sizeh(c);
- break;
- case XA_WM_HINTS:
- if((h = XGetWMHints(EVDPY(e), c->win))
- && (h->flags & XUrgencyHint)
- && c->tag != W->screen->seltag)
- {
- c->tag->flags |= TAG_URGENT;
- infobar_elem_screen_update(c->screen, ElemTag);
- XFree(h);
- }
- break;
- default:
- if(ev->atom == XA_WM_NAME || ev->atom == W->net_atom[net_wm_name])
- client_get_name(c);
- break;
- }
- }
- else if((s = systray_find(ev->window)))
- {
- systray_state(s);
- systray_update();
- }
- }
- static void
- event_unmapnotify(XEvent *e)
- {
- XUnmapEvent *ev = &e->xunmap;
- struct client *c;
- struct _systray *s;
- if((c = client_gb_win(ev->window))
- && ev->send_event
- && ev->event == W->root)
- {
- Atom rt;
- unsigned long n, il;
- int d;
- unsigned char *ret = NULL;
- if(XGetWindowProperty(EVDPY(e), c->win, W->net_atom[wm_state], 0, 2,
- False, W->net_atom[wm_state], &rt, &d,
- &n, &il, &ret) == Success)
- if(*ret == NormalState)
- client_remove(c);
- }
- else if((s = systray_find(ev->window)))
- {
- systray_del(s);
- systray_update();
- }
- }
- static void
- event_keypress(XEvent *e)
- {
- XKeyPressedEvent *ev = &e->xkey;
- KeySym keysym = XkbKeycodeToKeysym(EVDPY(e), (KeyCode)ev->keycode, 0, 0);
- struct keybind *k;
- screen_update_sel();
- status_flush_surface();
- SLIST_FOREACH(k, &W->h.keybind, next)
- if(k->keysym == keysym && KEYPRESS_MASK(k->mod) == KEYPRESS_MASK(ev->state))
- if(k->func)
- k->func(k->cmd);
- }
- static void
- event_expose(XEvent *e)
- {
- XExposeEvent *ev = &e->xexpose;
- struct barwin *b;
- SLIST_FOREACH(b, &W->h.barwin, next)
- if(b->win == ev->window)
- {
- barwin_refresh(b);
- return;
- }
- }
- 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);
- }
- }
- static void
- event_selectionclearevent(XEvent *ev)
- {
- /* Getting selection if lost it */
- if(ev->xselectionclear.window == W->systray.win)
- systray_acquire();
- systray_update();
- }
- static void
- event_dummy(XEvent *e)
- {
- /* printf("%d\n", e->type);*/
- (void)e;
- }
- void
- event_init(void)
- {
- int i = MAX_EV;
- while(i--)
- event_handle[i] = event_dummy;
- event_handle[ButtonPress] = event_buttonpress;
- event_handle[ClientMessage] = event_clientmessageevent;
- event_handle[ConfigureRequest] = event_configureevent;
- event_handle[DestroyNotify] = event_destroynotify;
- event_handle[EnterNotify] = event_enternotify;
- event_handle[Expose] = event_expose;
- event_handle[FocusIn] = event_focusin;
- event_handle[KeyPress] = event_keypress;
- event_handle[MapNotify] = event_mapnotify;
- event_handle[MapRequest] = event_maprequest;
- event_handle[MappingNotify] = event_mappingnotify;
- event_handle[PropertyNotify] = event_propertynotify;
- /*event_handle[ReparentNotify] = event_reparentnotify;*/
- event_handle[SelectionClear] = event_selectionclearevent;
- event_handle[UnmapNotify] = event_unmapnotify;
- }
|