예제 #1
0
파일: event.c 프로젝트: n4cht/kwm
/** EnterNotify handle event
 * \param ev XCrossingEvent pointer
*/
static void
enternotify(XCrossingEvent *ev)
{
     Client *c;
     int n;

     if((ev->mode != NotifyNormal
         || ev->detail == NotifyInferior)
        && ev->window != ROOT)
          return;

     /* Don't handle EnterNotify event if it's about systray */
     if(systray_find(ev->window) || ev->window == traywin)
          return;

     if(conf.focus_fmouse)
     {
          if((c = client_gb_win(ev->window))
                    || (c = client_gb_frame(ev->window))
                    || (c = client_gb_titlebar(ev->window))
                    || (c = client_gb_button(ev->window, &n)))
               client_focus(c);
          else
               client_focus(NULL);
     }


     return;
}
예제 #2
0
파일: event.c 프로젝트: kidanger/wmfs
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);
     }
}
예제 #3
0
파일: event.c 프로젝트: kidanger/wmfs
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)
     {
          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], (Atom*)&d, &d,
                                (long unsigned int*)&d, (long unsigned int*)&d, &ret) == Success)
               if(*ret == NormalState)
                    client_remove(c);
     }
     else if((s = systray_find(ev->window)))
     {
          systray_del(s);
          systray_update();
     }
}
예제 #4
0
파일: event.c 프로젝트: n4cht/kwm
/** PropertyNotify handle event
 * \param ev XPropertyEvent pointer
*/
static void
propertynotify(XPropertyEvent *ev)
{
     Client *c;
     Systray *s;
     Window trans;
     XWMHints *h;

     if(ev->state == PropertyDelete)
          return;

     if((s = systray_find(ev->window)))
     {
          systray_state(s);
          systray_update();
     }

     if((c = client_gb_win(ev->window)))
     {
          switch(ev->atom)
          {
          case XA_WM_TRANSIENT_FOR:
               XGetTransientForHint(dpy, c->win, &trans);
               if((c->flags & TileFlag || c->flags & MaxFlag))
                    if(((c->flags & HintFlag && (client_gb_win(trans) != NULL)))
                              || (!(c->flags & HintFlag && (client_gb_win(trans) != NULL))))
                         arrange(c->screen, True);
               break;
          case XA_WM_NORMAL_HINTS:
               client_size_hints(c);
               break;
          case XA_WM_HINTS:
               if((h = XGetWMHints(dpy, c->win)) && (h->flags & XUrgencyHint) && c != sel)
               {
                    client_urgent(c, True);
                    XFree(h);
               }
               break;
          case XA_WM_NAME:
               client_get_name(c);
               break;
          default:
               if(ev->atom == net_atom[net_wm_name])
                    client_get_name(c);
               break;
          }
     }

     return;
}
예제 #5
0
파일: event.c 프로젝트: kidanger/wmfs
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();
     }
}
예제 #6
0
파일: event.c 프로젝트: kidanger/wmfs
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();
     }
}
예제 #7
0
파일: event.c 프로젝트: kidanger/wmfs
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);
     }
}
예제 #8
0
파일: event.c 프로젝트: n4cht/kwm
/** 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;
}
예제 #9
0
파일: event.c 프로젝트: n4cht/kwm
/** 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;
}
예제 #10
0
파일: event.c 프로젝트: n4cht/kwm
/** DestroyNotify handle event
 * \param ev XDestroyWindowEvent pointer
*/
static void
destroynotify(XDestroyWindowEvent *ev)
{
     Client *c;
     Systray *s;

     if((c = client_gb_win(ev->window)))
     {
          client_unmanage(c);
          XSetErrorHandler(errorhandler);
     }
     else if((s = systray_find(ev->window)))
     {
          setwinstate(s->win, WithdrawnState);
          systray_del(s);
          systray_update();
     }

     return;
}
예제 #11
0
파일: event.c 프로젝트: kidanger/wmfs
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();
     }
}
예제 #12
0
파일: event.c 프로젝트: n4cht/kwm
/** UnmapNotify handle event
 * \param ev XUnmapEvent pointer
 */
static void
unmapnotify(XUnmapEvent *ev)
{
     Client *c;
     Systray *s;

     if((c = client_gb_win(ev->window))
        && ev->send_event
        && !(c->flags & HideFlag))
     {
          client_unmanage(c);
          XSetErrorHandler(errorhandler);
     }

     if((s = systray_find(ev->window)))
     {
          systray_del(s);
          systray_update();
     }

     return;
}
예제 #13
0
파일: event.c 프로젝트: kidanger/wmfs
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;
     }
}
예제 #14
0
파일: event.c 프로젝트: n4cht/kwm
/* 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;
}