Beispiel #1
0
Datei: event.c Projekt: 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;
}
Beispiel #2
0
Datei: ewmh.c Projekt: n4cht/kwm
/** Manage _NET_WM_STATE_* ewmh
 */
void
ewmh_manage_net_wm_state(long data_l[], Client *c)
{
     /* Manage _NET_WM_STATE_FULLSCREEN */
     if(data_l[1] == (long)net_atom[net_wm_state_fullscreen])
     {
          if(data_l[0] == _NET_WM_STATE_ADD && !(c->flags & FSSFlag))
          {
               c->screen = screen_get_with_geo(c->geo.x, c->geo.y);
               c->flags &= ~UnmapFlag;
               XMapWindow(dpy, c->win);
               XReparentWindow(dpy, c->win, ROOT, spgeo[c->screen].x, spgeo[c->screen].y);
               XResizeWindow(dpy, c->win,
                             spgeo[c->screen].width,
                             spgeo[c->screen].height);
               XChangeProperty(dpy, c->win, net_atom[net_wm_state], XA_ATOM, 32,
                               PropModeReplace, (uchar *)&net_atom[net_wm_state_fullscreen], 1);

               c->tmp_geo = c->geo;

               if(c->flags & FreeFlag)
                    c->ogeo = c->geo;

               c->flags |= (FSSFlag | MaxFlag);

               client_raise(c);
               client_focus(c);
               XUnmapWindow(dpy, c->frame);
          }
          else if(data_l[0] == _NET_WM_STATE_REMOVE && (c->flags & FSSFlag))
          {
               XChangeProperty(dpy, c->win, net_atom[net_wm_state], XA_ATOM, 32, PropModeReplace, (uchar *)0, 0);
               c->flags &= ~(FSSFlag | MaxFlag);
               client_map(c);
               XReparentWindow(dpy, c->win, c->frame, BORDH, TBARH);
               client_moveresize(c, c->tmp_geo, False);
          }
     }
     /* Manage _NET_WM_STATE_STICKY */
     else if(data_l[1] == (long)net_atom[net_wm_state_sticky])
     {
          /* == client_ignore_tag */
          c->tag = MAXTAG + 1;
          arrange(c->screen, True);
     }
     /* Manage _NET_WM_STATE_DEMANDS_ATTENTION */
     else if(data_l[1] == (long)net_atom[net_wm_state_demands_attention])
     {
          if(data_l[0] == _NET_WM_STATE_ADD)
               client_urgent(c, True);
          if(data_l[0] == _NET_WM_STATE_REMOVE)
               if(c == sel)
                    client_focus(NULL);
     }

     return;
}
Beispiel #3
0
/** Go to the current urgent tag
  *\param cmd uicb_t type unused
  */
void
uicb_tag_urgent(uicb_t cmd)
{
     Client *c;
     Bool b = False;

     (void)cmd;

     /* Check if there is a urgent client */
     for(c = clients; c; c = c->next)
          if(c->flags & UrgentFlag)
          {
               b = True;
               break;
          }

     if(!b)
          return;

    screen_set_sel(c->screen);
    tag_set(c->tag);
    client_focus(c);

    return;
}
Beispiel #4
0
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);
}
Beispiel #5
0
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);
     }
}
Beispiel #6
0
void client_remove(struct WM_t *W, struct wmclient *C)
{
    int idx = get_client_index(W, C->win), i;

    if (W->clients[idx] != C)
    {
        msg("client_remove: somehow get_client_index failed! :o\n");
        return;
    }

    W->clients[idx] = NULL;
    /* Update all the focus numbers, i.e. decrease (bring forward) all the windows
       with bigger focus numbers. */
    for (i = idx; i < W->nclients; i++)
        W->clients[i] = W->clients[i + 1];
    W->nclients--;

    msg("Removing client \'%s\'\n", C->name);
    free(C->name);
    free(C);

    msg("About to print\n");
    print_clients(W);
    msg("Printed, about to focus\n");

    client_focus(W, W->clients[0]);
    msg("Focused\n");
}
Beispiel #7
0
void
tag_screen(struct screen *s, struct tag *t)
{
     struct client *c;

     /* Return to the previous tag */
     if(t == s->seltag && TAILQ_NEXT(TAILQ_FIRST(&s->tags), next))
          t = t->prev;

     if(!t)
          t = TAILQ_FIRST(&s->tags);

     /* Move clients which ignore tags */
     SLIST_FOREACH(c, &W->h.client, next)
          if (c->flags & CLIENT_IGNORE_TAG)
               tag_client(t, c);

     t->prev = s->seltag;
     s->seltag = t;

     clients_arrange_map();

     /* Update focus */
     if(!SLIST_EMPTY(&t->clients) && !(W->flags & WMFS_SCAN))
          client_focus( client_tab_next(t->sel));

     t->flags &= ~TAG_URGENT;

     infobar_elem_screen_update(s, ElemTag);

     ewmh_update_wmfs_props();
}
Beispiel #8
0
/** Toggle abovefc option
  *\param cmd uicb_t type
  */
void
uicb_toggle_abovefc(uicb_t cmd)
{
     Client *c;
     (void)cmd;

     screen_get_sel();

     if(!(tags[selscreen][seltag[selscreen]].abovefc = !tags[selscreen][seltag[selscreen]].abovefc))
     {
          for(c = clients; c; c = c->next)
               if(c->flags & AboveFlag
                         && c->screen == selscreen
                         && c->tag == (uint)seltag[selscreen])
               {
                    c->flags &= ~AboveFlag;
                    break;
               }

          tags[selscreen][seltag[selscreen]].layout.func(selscreen);
     }

     client_focus(sel);

     return;
}
Beispiel #9
0
void
area_focus(Area *a) {
	Frame *f;
	View *v;
	Area *old_a;

	v = a->view;
	f = a->sel;
	old_a = v->sel;

	if(!a->floating && view_fullscreen_p(v, a->screen))
		return;

	v->sel = a;
	if(!a->floating) {
		v->selcol = area_idx(a);
		v->selscreen = a->screen;
	}
	if(a != old_a)
		v->oldsel = nil;

	if(old_a && a->floating != old_a->floating) {
		v->revert = old_a;
		if(v->floating->max)
			view_update(v);
	}

	if(v == selview) {
		move_focus(old_a->sel, f);
		client_focus(f ? f->client : nil);

		if(a != old_a)
			event("AreaFocus %a\n", a);
	}
}
Beispiel #10
0
Datei: event.c Projekt: n4cht/kwm
/** FocusChange handle event
 * \param ev XFocusChangeEvent pointer
 * \return
*/
static void
focusin(XFocusChangeEvent *ev)
{
     if(sel && ev->window != sel->win)
          client_focus(sel);

     return;
}
Beispiel #11
0
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);
}
Beispiel #12
0
void
area_focus(Area *a) {
	Frame *f;
	View *v;
	Area *old_a;

	v = a->view;
	f = a->sel;
	old_a = v->sel;

	if(!a->floating && view_fullscreen_p(v, a->screen))
		return;

	v->sel = a;
	if(!a->floating) {
		v->selcol = area_idx(a);
		v->selscreen = a->screen;
	}
	if(a != old_a)
		v->oldsel = nil;

	if((old_a) && (a->floating != old_a->floating)) {
		v->revert = old_a;
		if(v->floating->max)
			view_update(v);
	}

	if(v != selview)
		return;

	move_focus(old_a->sel, f);

	if(f)
		client_focus(f->client);
	else
		client_focus(nil);

	if(a != old_a) {
		event("AreaFocus %a\n", a);
		/* Deprecated */
		if(a->floating)
			event("FocusFloating\n");
		else
			event("ColumnFocus %d\n", area_idx(a));
	}
}
Beispiel #13
0
/* Set t to NULL to untag c from c->tag */
void
tag_client(struct tag *t, struct client *c)
{
     /* Remove client from its previous tag */
     if(c->tag && !(c->flags & CLIENT_RULED))
     {
          if(c->tag == t)
               return;

          if(!(c->flags & (CLIENT_IGNORE_LAYOUT | CLIENT_FREE)))
               layout_split_arrange_closed(c);

          if(!(c->flags & CLIENT_REMOVEALL))
          {
               SLIST_REMOVE(&c->tag->clients, c, client, tnext);

               if(c->tag->sel == c || W->client == c)
                    client_focus( client_tab_next( client_next(c)));
          }
     }

     c->flags &= ~CLIENT_RULED;

     /* Client remove */
     if(!t)
     {
          infobar_elem_screen_update(c->screen, ElemTag);
          return;
     }

     c->prevtag = c->tag;
     c->tag = t;
     c->screen = t->screen;

     client_update_props(c, CPROP_LOC);

     SLIST_INSERT_HEAD(&t->clients, c, tnext);

     infobar_elem_screen_update(c->screen, ElemTag);

     if(c->flags & CLIENT_TABMASTER && c->prevtag)
     {
          struct client *cc;

          SLIST_FOREACH(cc, &c->prevtag->clients, tnext)
               if(cc->tabmaster == c)
               {
                    cc->flags |= CLIENT_IGNORE_LAYOUT;
                    tag_client(t, cc);
               }
     }

     layout_client(c);

     if(t != c->screen->seltag || c->flags & CLIENT_TABBED)
          client_unmap(c);
}
Beispiel #14
0
void client_send_to_monitor(Client *c, Monitor *m) {
	if(c->mon == m)
		return;
	client_unfocus(c, true);
	client_detach(c);
	client_detach_stack(c);
	c->mon = m;
	c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */
	client_attach(c);
	client_attach_stack(c);
	client_focus(NULL);
	arrange(NULL);
}
Beispiel #15
0
Datei: event.c Projekt: n4cht/kwm
/** XMotionNotify handle event
 * \param ev XMotionEvent pointer
 */
static void
motionnotify(XMotionEvent *ev)
{
     Client *c;

     if(!conf.focus_fmouse || !conf.focus_fmov)
          return;

     if((c = client_gb_win(ev->subwindow)))
          if(c != sel)
               client_focus(c);

     return;
}
Beispiel #16
0
/** Set the selected screen
 *\param screen Number of the wanted selected screen
*/
void
screen_set_sel(int screen)
{
     if(screen < 0 || screen > screen_count() - 1)
          screen = 0;

     if(selscreen != screen)
          prevselscreen = selscreen;

     client_focus(NULL);
     XWarpPointer(dpy, None, ROOT, 0, 0, 0, 0,
                  sgeo[screen].x + sgeo[screen].width / 2,
                  sgeo[screen].y + sgeo[screen].height / 2);

     selscreen = screen;

     return;
}
Beispiel #17
0
/* Register a client, steal its border, grap events, etc */
void client_register(struct WM_t *W, Window xwindow_id)
{
    struct wmclient *C = malloc(sizeof(*C));

    XFetchName(W->XDisplay, xwindow_id, &(C->name));
    if (!(C->name))
        C->name = strdup("<notitle>");
    msg("Registering \'%s\':\n", C->name);

    C->win = xwindow_id;

    decide_new_window_size_pos(W, C);

    /* Unless it's a window found at startup, move it
     * to the current head/screen */
    if (!registering_existing_windows)
    {
        C->x += curr_head_x(W);
        C->y += curr_head_y(W);
    }


    C->fullscreen = 0;

    XMapWindow(W->XDisplay, C->win);

    set_size_pos_border(W, C);

    client_select_events(W, C);

    get_pid(W, C);

    W->clients[W->nclients++] = C;

    client_focus(W, C);

    XFlush(W->XDisplay);

    print_clients(W);
}
Beispiel #18
0
void client_unmanage(Client *c, bool destroyed) {
	Monitor *m = c->mon;

	/* The server grab construct avoids race conditions. */
	client_detach(c);
	client_detach_stack(c);
	printf("unmanage %i, %i\n", destroyed, c->win);
	if(!destroyed) {
		uint32_t values[] = { c->oldbw };
		xcb_grab_server(conn);
		xcb_configure_window_checked(conn, c->win, 
			XCB_CONFIG_WINDOW_BORDER_WIDTH, values);
		xcb_ungrab_button_checked(conn, XCB_BUTTON_INDEX_ANY, c->win, 
			XCB_GRAB_ANY);
		client_set_state(c, XCB_ICCCM_WM_STATE_WITHDRAWN);
		xcb_flush(conn);
		xcb_ungrab_server(conn);
	}
	free(c);
	client_focus(NULL);
	arrange(m);
}
Beispiel #19
0
Datei: ewmh.c Projekt: Engil/wmfs
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);
          }
     }

}
Beispiel #20
0
/** Move a client in tile grid with the mouse
 *\param c Client double pointer
 */
static void
mouse_move_tile_client(Client **c)
{
     Client *sc;
     Window w;
     int d;

     if(!((*c)->flags & TileFlag) && !((*c)->flags & LMaxFlag))
          return;

     XQueryPointer(dpy, ROOT, &w, &w, &d, &d, &d, &d, (uint*)&d);

     if(((sc = client_gb_win(w)) || (sc = client_gb_frame(w)) || (sc = client_gb_titlebar(w)))
        && (*c)->win != sc->win && !((*c)->flags & HideFlag) && !(sc->flags & HideFlag))
     {
          client_swap(sc, *c);
          client_focus(sc);
          swap_ptr((void**)c, (void**)&sc);
     }

     return;

}
Beispiel #21
0
void handle_event(XEvent *ev) {
	client *c = owner(ev->xany.window);
	#ifdef DEBUG_EVENTS
	if(ev->type != Expose && ev->type != MotionNotify && !(ev->type == ConfigureNotify && ev->xconfigure.window != root)) /* this makes the output slightly more manageable */
		printf(NAME ": handle_event(): got %s\n\twindow: 0x%X (%s)\n", event_name(ev), (unsigned int) ev->xany.window, c ? c->name : ((ev->xany.window == root) ? "root" : "unknown"));
	#endif
	if((evh && evh(ev)) || button_handle_event(ev) || ewmh_handle_event(ev) || screens_handle_event(ev)) {
		#ifdef DEBUG_EVENTS
		if(ev->type != Expose && ev->type != MotionNotify && (ev->type != ConfigureNotify && ev->xconfigure.window != root))
			printf(NAME ": handle_event(): external event handler claimed last event\n");
		#endif
		return;
	}
	if(c) {
		if(!has_child(c->parent, c->window) && ev->type != DestroyNotify && ev->type != UnmapNotify)
			return;
		switch(ev->type) {
			case UnmapNotify:
				if(c->window == ev->xunmap.window) {
					#ifdef DEBUG_EVENTS
					printf(NAME ": handle_event(): handling UnmapNotify event\n\twindow: 0x%X (%s)\n", (unsigned int) c->window, c->name);
					#endif
					if(has_child(c->parent, c->window)) {
						client_deparent(c);
						set_wm_state(c->window, WithdrawnState);
					}
					client_remove(c);
					ewmh_update_clist();
				}
				return;
			case PropertyNotify:
				if(ev->xproperty.atom == XA_WM_NAME) {
					#ifdef DEBUG_EVENTS
					printf(NAME ": handle_event(): handling PropertyNotify event\n\twindow: 0x%X (%s)\n\tproperty: XA_WM_NAME\n", (unsigned int) c->window, c->name);
					#endif
					if(c->name != no_title)
						XFree(c->name);
					#ifdef USE_XFT
					if(xftfont)
						XftDrawDestroy(c->title_draw);
					#endif
					XFreePixmap(dpy, c->title_pixmap);
					XFetchName(dpy, c->window, &c->name);
					client_update_name(c);
					XClearWindow(dpy, c->title);
					if(evh == wlist_handle_event) {
						XClearWindow(dpy, c->wlist_item);
						wlist_item_draw(c);
					}
				}
				if(ev->xproperty.atom == XA_WM_NORMAL_HINTS) {
					#ifdef DEBUG_EVENTS
					printf(NAME ": handle_event(): handling PropertyNotify event\n\twindow: 0x%X (%s)\n\tproperty: XA_WM_NORMAL_HINTS\n", (unsigned int) c->window, c->name);
					#endif
					get_normal_hints(c);
				}
				return;
			case ClientMessage:
				if(ev->xclient.message_type == xa_wm_change_state && ev->xclient.data.l[0] == IconicState) {
					#ifdef DEBUG_EVENTS
					printf(NAME ": handling ClientMessage event\n\twindow: 0x%X (%s)\n", (unsigned int) c->window, c->name);
					#endif
					client_iconify(c);
					return;
				}
				break; /* we might later need this event */
			case EnterNotify:
				if(c != current && !(c->flags & CLICK_FOCUS) && !click_focus && ev->xcrossing.mode != NotifyGrab && ev->xcrossing.mode != NotifyUngrab && ev->xcrossing.detail != NotifyInferior && (ev->xcrossing.window == c->parent || ev->xcrossing.window == c->wlist_item) && ev->xcrossing.send_event == False) {
					#ifdef DEBUG_EVENTS
					printf(NAME ": handle_event(): handling EnterNotify event\n\twindow: 0x%X (%s)\n", (unsigned int) c->window, c->name);
					#endif
					client_focus(c, true);
				}
				return;
			case Expose:
				if(ev->xexpose.count == 0 && evh == wlist_handle_event && c && ev->xexpose.window == c->wlist_item)
					wlist_item_draw(c);
				return;
			case ButtonPress:
				#ifdef DEBUG_EVENTS
				printf(NAME ": handle_event(): handling ButtonPress event\n\twindow: 0x%X (%s)\n", (unsigned int) c->window, c->name);
				#endif
				if(c != current)
					client_focus(c, true);
				XAllowEvents(dpy, ReplayPointer, CurrentTime);
				if(ev->xbutton.window != c->window) {
					if(lastclick + doubleclick_time > ev->xbutton.time && lastbutton == ev->xbutton.button && lastclick_client == c) {
						client_action(c, buttonaction(ev->xbutton.button, true), ev);
						lastclick = 0;
						lastclick_client = NULL;
						lastbutton = None;
						return;
					}
					lastclick = ev->xbutton.time;
					lastclick_client = c;
					lastbutton = ev->xbutton.button;
					client_action(c, buttonaction(ev->xbutton.button, false), ev);
				} else if(click_raise)
					client_raise(c);
				return;
			case FocusIn: /* we ignore pointer events, these happen if the input focus is on the root window */
				if(allow_focus_stealing && c != current && ev->xfocus.mode != NotifyGrab && ev->xfocus.mode != NotifyUngrab && ev->xfocus.detail != NotifyPointer) {
					#ifdef DEBUG_EVENTS
					printf(NAME ": handle_event(): handling FocusIn event\n\twindow: 0x%X (%s)\n", (unsigned int) c->window, c->name);
					#endif
					client_focus(c, false);
				}
				return;
			case FocusOut:
				if(c == current && ev->xfocus.mode != NotifyGrab && ev->xfocus.mode != NotifyUngrab && ev->xfocus.detail != NotifyInferior) {
					#ifdef DEBUG_EVENTS
					printf(NAME ": handle_event(): handling FocusOut event\n\twindow: 0x%X (%s)\n", (unsigned int) c->window, c->name);
					#endif
					if(allow_focus_stealing && ev->xfocus.detail != NotifyAncestor) {
						#ifdef DEBUG_EVENTS
						printf("\tfocus lost\n");
						#endif
						client_focus(NULL, false); /* we do this so windows that aren't managed can take focus */
					} else {
						#ifdef DEBUG_EVENTS
						printf("\tre-focussing this window\n");
						#endif
						take_focus(c);
					}
				}
				return;
			#ifdef USE_SHAPE
			default:
				if(ev->type == shape_event) {
					#ifdef DEBUG_EVENTS
					printf(NAME ": handle_event(): handling ShapeNotify event\n\twindow 0x%X (%s)\n", (unsigned int) c->window, c->name);
					#endif
					set_shape(c);
					return;
				}
			#endif
		}
	}
	switch(ev->type) {
		case MapRequest:
			c = owner(ev->xmaprequest.window);
			#ifdef DEBUG_EVENTS
			printf(NAME ": handle_event(): handling MapRequest event\n\twindow: 0x%X (%s)\n", (unsigned int) ev->xmaprequest.window, c ? c->name : "unknown");
			#endif
			if(c) {
				if(c->flags & ICONIC && has_child(c->parent, c->window)) {
					client_restore(c);
					if(focus_new)
						client_focus(c, true);
				}
			} else if(has_child(root, ev->xmaprequest.window))
				client_add(ev->xmaprequest.window, false);
			return;
		case DestroyNotify:
			c = owner(ev->xdestroywindow.window);
			if(c)
				if(c->window == ev->xdestroywindow.window) {
					#ifdef DEBUG_EVENTS
					printf(NAME ": handle_event(): handling DestroyNotify event\n\twindow 0x%X (%s)\n", (unsigned int) c->window, c->name);
					#endif
					client_remove(c);
				}
			return;
		case ConfigureRequest:
			c = owner(ev->xconfigurerequest.window);
			#ifdef DEBUG_EVENTS
			printf(NAME ": handle_event(): handling ConfigureRequest event\n\twindow 0x%X (%s)\n", (unsigned int) ev->xconfigurerequest.window, c ? c->name : "unknown");
			#endif
			if(correct_center)
				screens_correct_center(&ev->xconfigurerequest.x, &ev->xconfigurerequest.y, &ev->xconfigurerequest.width, &ev->xconfigurerequest.height);
			if(c) {
				if(!has_child(c->parent, c->window))
					return;
				if(ev->xconfigurerequest.value_mask & CWX)
					c->x = ev->xconfigurerequest.x - gxo(c, false);
				if(ev->xconfigurerequest.value_mask & CWY)
					c->y = ev->xconfigurerequest.y - gyo(c, false);
				if(ev->xconfigurerequest.value_mask & CWWidth)
					c->width = ev->xconfigurerequest.width;
				if(ev->xconfigurerequest.value_mask & CWHeight)
					c->height = ev->xconfigurerequest.height;
				client_update(c);
				#ifdef DEBUG
				printf(NAME ": handle_event(): reconfigured client 0x%X (%s) to %ix%i+%i+%i\n", (unsigned int) c->window, c->name, c->width, c->height, c->x, c->y);
				#endif
			} else if(has_child(root, ev->xconfigurerequest.window)) {
				XWindowChanges wc;
				wc.sibling = ev->xconfigurerequest.above;
				wc.stack_mode = ev->xconfigurerequest.detail;
				wc.x = ev->xconfigurerequest.x;
				wc.y = ev->xconfigurerequest.y;
				wc.width = ev->xconfigurerequest.width;
				wc.height = ev->xconfigurerequest.height;
				XConfigureWindow(dpy, ev->xconfigurerequest.window, ev->xconfigurerequest.value_mask, &wc);
			}
			return;
		case MapNotify:
			if(correct_center_unmanaged && ev->xany.window == root && !owner(ev->xmap.window)) {
				#ifdef DEBUG_EVENTS
				printf(NAME ": handle_event(): handling MapNotify event\n\twindow 0x%X (unknown)\n", (unsigned int) ev->xmap.window);
				#endif
				window_correct_center(ev->xmap.window);
			}
			return;
		case MappingNotify:
			if(ev->xmapping.request != MappingPointer) {
				#ifdef DEBUG_EVENTS
				printf(NAME ": handle_event(): handling MappingNotify event\n");
				#endif
				keys_ungrab();
				XRefreshKeyboardMapping(&ev->xmapping);
				keys_update();
			}
			return;
		case KeyPress:
			#ifdef DEBUG_EVENTS
			printf(NAME ": handle_event(): handling KeyPress event\n");
			#endif
			client_action(current, keyaction(ev), ev);
			return;
		case ButtonPress:
			if(ev->xbutton.window != root)
				return;
			#ifdef DEBUG_EVENTS
			printf(NAME ": handle_event(): handling ButtonPress event\n");
			#endif
			if(lastclick + doubleclick_time > ev->xbutton.time && lastbutton == ev->xbutton.button && lastclick_client == NULL) {
				client_action(current, root_buttonaction(ev->xbutton.button, true), ev);
				lastclick = 0;
				lastclick_client = NULL;
				lastbutton = None;
				return;
			}
			lastclick = ev->xbutton.time;
			lastclick_client = NULL;
			lastbutton = ev->xbutton.button;
			client_action(current, root_buttonaction(ev->xbutton.button, false), ev);
			return;
		case ClientMessage:
			if(ev->xclient.message_type == xa_internal_message) {
				if(((Atom) ev->xclient.data.l[0]) == xa_quit) {
					#ifdef DEBUG
					printf(NAME ": handle_event(): quit message received\n");
					#endif
					exit(0);
				}
				if(((Atom) ev->xclient.data.l[0]) == xa_reinit) {
					#ifdef DEBUG
					printf(NAME ": handle_event(): reinitialize message received\n");
					#endif
					cfg_reinitialize();
				}
			}
	}
}
Beispiel #22
0
Datei: ewmh.c Projekt: n4cht/kwm
/** Manage the client hints
 *\param c Client pointer
*/
void
ewmh_manage_window_type(Client *c)
{
     Atom *atom, rf;
     int f;
     ulong n, il, i;
     uchar *data = NULL;
     long ldata[5] = { 0 };

     if(XGetWindowProperty(dpy, c->win, 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_DOCK & _NET_WM_WINDOW_TYPE_SPLASH */
               if(atom[i] == net_atom[net_wm_window_type_dock]
                  || atom[i] == net_atom[net_wm_window_type_splash])
               {
                    /* Unmap frame, decoration.. */
                    client_unmap(c);

                    /* Map only window */
                    XMapWindow(dpy, c->win);

                    /* Reparent it to ROOT win */
                    XReparentWindow(dpy, c->win, ROOT, c->geo.x, c->geo.y);
                    XRaiseWindow(dpy, c->win);

                    c->flags |= DockFlag;
               }
               /* MANAGE _NET_WM_WINDOW_TYPE_DIALOG */
               else if(atom[i] == net_atom[net_wm_window_type_dialog])
               {
                    c->flags |= FreeFlag;
                    c->flags &= ~(TileFlag | MaxFlag | LMaxFlag);
                    client_moveresize(c, c->ogeo, True);
                    client_focus(c);
                    tags[selscreen][seltag[selscreen]].layout.func(selscreen);
               }
          }
          XFree(data);
     }

     /* Get NET_WM_STATE set without sending client message event */
     if(XGetWindowProperty(dpy, c->win, 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[0] = _NET_WM_STATE_ADD;
               ldata[1] = atom[i];
               ewmh_manage_net_wm_state(ldata, c);
          }
          XFree(data);
     }

     return;
}
Beispiel #23
0
Datei: event.c Projekt: 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;
}
Beispiel #24
0
Datei: event.c Projekt: n4cht/kwm
/** ButtonPress handle event
 * \param ev XButtonEvent pointer
*/
static void
buttonpress(XButtonEvent *ev)
{
     Client *c;
     int i, j, n;

     screen_get_sel();

     /* If the mouse is on a not selected client and you click on it. */
     if(((c = client_gb_win(ev->window)) || (c = client_gb_titlebar(ev->window))) && c != sel
        && (ev->button == Button1 || ev->button == Button2 || ev->button == Button3))
     {
          client_focus(c);
          client_raise(c);

          return;
     }

     /* Titlebar */
     if((c = client_gb_titlebar(ev->window)) && c == sel)
          for(i = 0; i < conf.titlebar.nmouse; ++i)
                if(ev->button == conf.titlebar.mouse[i].button)
                    if(conf.titlebar.mouse[i].func)
                         conf.titlebar.mouse[i].func(conf.titlebar.mouse[i].cmd);

     /* Titlebar buttons */
     if((c = client_gb_button(ev->window, &n)))
          for(i = 0; i < conf.titlebar.button[n].nmouse; ++i)
               if(ev->button == conf.titlebar.button[n].mouse[i].button)
                    if(conf.titlebar.button[n].mouse[i].func)
                    {
                         client_focus(c);
                         conf.titlebar.button[n].mouse[i].func(conf.titlebar.button[n].mouse[i].cmd);
                    }

     /* Frame Resize Area */
     if((c = client_gb_resize(ev->window)))
          mouse_resize(c);

     /* Client */
     if((c = client_gb_win(ev->window)) && c == sel)
          for(i = 0; i < conf.client.nmouse; ++i)
               if(ev->button == conf.client.mouse[i].button)
                    if(conf.client.mouse[i].func)
                         conf.client.mouse[i].func(conf.client.mouse[i].cmd);

     /* Root */
     if(ev->window == ROOT)
          for(i = 0; i < conf.root.nmouse; ++i)
               if(conf.root.mouse[i].tag == seltag[conf.root.mouse[i].screen]
                  || conf.root.mouse[i].tag < 0)
                    if(ev->button == conf.root.mouse[i].button)
                         if(conf.root.mouse[i].func)
                              conf.root.mouse[i].func(conf.root.mouse[i].cmd);

     /* Infobars */
     for(i = 0; i < screen_count(); ++i)
          if(ev->window == infobar[i].bar->win)
               for(j = 0; j < conf.bars.nmouse; ++j)
                    if(conf.bars.mouse[j].screen == i
                       || conf.bars.mouse[j].screen < 0)
                         if(conf.bars.mouse[j].tag == seltag[i]
                            || conf.bars.mouse[j].tag < 0)
                              if(ev->button == conf.bars.mouse[j].button)
                                   if(conf.bars.mouse[j].func)
                                        conf.bars.mouse[j].func(conf.bars.mouse[j].cmd);

     /* Selbar */
     if(conf.bars.selbar && ev->window == infobar[selscreen].selbar->win)
          for(i = 0; i < conf.selbar.nmouse; ++i)
               if(conf.selbar.mouse[i].tag == seltag[conf.selbar.mouse[i].screen]
                  || conf.selbar.mouse[i].tag < 0)
                    if(ev->button == conf.selbar.mouse[i].button)
                         if(conf.selbar.mouse[i].func)
                              conf.selbar.mouse[i].func(conf.selbar.mouse[i].cmd);

     /* Tags */
     for(i = 1; i < conf.ntag[selscreen] + 1; ++i)
          if(ev->window == infobar[selscreen].tags[i]->win)
          {
               for(j = 0; j < tags[selscreen][i].nmouse; ++j)
                    if(ev->button == tags[selscreen][i].mouse[j].button)
                         if(tags[selscreen][i].mouse[j].func)
                              tags[selscreen][i].mouse[j].func(tags[selscreen][i].mouse[j].cmd);

               /* Mouse button action on tag */
               if(ev->button == conf.mouse_tag_action[TagSel])
                    tag_set(i);
               else if(ev->button == conf.mouse_tag_action[TagTransfert])
                    tag_transfert(sel, i);
               else if(ev->button == conf.mouse_tag_action[TagAdd])
                    tag_additional(selscreen, seltag[selscreen], i);
               else if(ev->button == conf.mouse_tag_action[TagNext])
                    tag_set(seltag[selscreen] + 1);
               else if(ev->button == conf.mouse_tag_action[TagPrev])
                    tag_set(seltag[selscreen] - 1);
          }

     /* Layout button */
     if(ev->window == infobar[selscreen].layout_button->win && conf.nlayout > 1)
     {
          if(conf.layout_system && (ev->button == Button1 || ev->button == Button3)) /* True -> menu */
          {
               menulayout.y = spgeo[selscreen].y + infobar[selscreen].layout_button->geo.y + INFOBARH;
               menulayout.x = infobar[selscreen].layout_button->geo.x + (sgeo[selscreen].x - BORDH);

               if(infobar[selscreen].geo.y != spgeo[selscreen].y)
                    menulayout.y = infobar[selscreen].geo.y - (INFOBARH * menulayout.nitem) - SHADH;

               uicb_menu("menulayout");
          }
          else
          {
               switch(ev->button)
               {
               case Button1: case Button4: layoutswitch(True);  break;
               case Button3: case Button5: layoutswitch(False); break;
               }
          }
     }

     return;
}
Beispiel #25
0
/* Set the tag
 * \param tag The tag number
*/
void
tag_set(int tag)
{
     Client *c;
     Bool al = False;
     int i;

     if(tag < 0 || tag > MAXTAG)
          return;

     screen_get_sel();

     if(seltag[selscreen] != tag)
          prevseltag[selscreen] = seltag[selscreen];
     else if(tag == seltag[selscreen] && tag != prevseltag[selscreen] && conf.tag_auto_prev)
          tag = seltag[selscreen] = prevseltag[selscreen];
     else
          seltag[selscreen] = tag;

     if(conf.tag_round)
     {
          if(tag <= 0)
               seltag[selscreen] = conf.ntag[selscreen];
          else if(tag > conf.ntag[selscreen])
               seltag[selscreen] = 1;
          else
               seltag[selscreen] = tag;
     }
     else
     {
          if(!tag || tag > conf.ntag[selscreen])
               return;

          seltag[selscreen] = tag;
     }

     ewmh_update_current_tag_prop();

     /* Arrange infobar position */
     if(tags[selscreen][prevseltag[selscreen]].barpos != tags[selscreen][seltag[selscreen]].barpos
               || prevseltag[selscreen] == seltag[selscreen])
          infobar_set_position(tags[selscreen][seltag[selscreen]].barpos);

     /* Check if a layout update is needed with additional tags */
     if(tags[selscreen][seltag[selscreen]].tagad)
          al = True;
     else if(tags[selscreen][seltag[selscreen]].request_update)
     {
          al = True;
          tags[selscreen][seltag[selscreen]].request_update = False;
     }

     for(i = 1; i < conf.ntag[selscreen] + 1; ++i)
          if(tags[selscreen][i].tagad & TagFlag(seltag[selscreen]))
          {
               al = True;
               break;
          }

     /* Check for ignore_tag clients */
     for(c = clients; c; c = c->next)
          if(c->tag == MAXTAG + 1 && c->screen == selscreen)
          {
               al = True;
               break;
          }

     arrange(selscreen, al);

     if(tags[selscreen][tag].request_update)
     {
          tags[selscreen][seltag[selscreen]].layout.func(selscreen);
          tags[selscreen][tag].request_update = False;
     }

     /* To focus selected client of the via focusontag option */
     for(c = clients; c; c = c->next)
          if(c->focusontag == tag && c->screen == selscreen)
               break;

     /* No focusontag option found on any client, try to find the first of the tag */
     if(!c)
          for(c = clients; c; c = c->next)
               if(c->tag == (uint)seltag[selscreen] && c->screen == selscreen)
                    break;

     client_focus((c) ? c : NULL);

     return;
}
Beispiel #26
0
bool ewmh_handle_event(XEvent *ev) {
	client *c;
	int i, j, xo, yo;
	long extents[4];
	Atom rt;
	int rf;
	unsigned long nir, bar;
	switch(ev->type) {
		case ClientMessage:
			c = owner(ev->xclient.window);
			if(ev->xclient.message_type == ewmh_atoms[NET_WM_MOVERESIZE]) {
				if(c) {
					#ifdef DEBUG_EVENTS
					printf(NAME ": ewmh_handle_event(): handling ClientMessage event\n\tatom: _NET_WM_MOVERESIZE\n");
					#endif
					if(ev->xclient.data.l[2] == NET_WM_MOVERESIZE_MOVE || ev->xclient.data.l[2] == NET_WM_MOVERESIZE_MOVE_KEYBOARD) {
						client_focus(c, true);
						xo = client_width_total_intern(c) / 2;
						yo = client_height_total_intern(c) / 2;
						XWarpPointer(dpy, None, c->parent, 0, 0, 0, 0, xo, yo);
						drag_start(A_MOVE, AnyButton, client_x(c) + xo, client_y(c) + yo);
					}
					if(ev->xclient.data.l[2] == NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT || ev->xclient.data.l[2] == NET_WM_MOVERESIZE_SIZE_KEYBOARD) {
						client_focus(c, true);
						drag_start(A_RESIZE, AnyButton, ev->xclient.data.l[0], ev->xclient.data.l[1]);
					}
				}
				return true;
			}
			if(ev->xclient.message_type == ewmh_atoms[NET_CLOSE_WINDOW]) {
				if(c) {
					#ifdef DEBUG_EVENTS
					printf(NAME ": ewmh_handle_event(): handling ClientMessage event\n\tatom: _NET_CLOSE_WINDOW\n");
					#endif
					delete_window(c);
				}
				return true;
			}
			if(ev->xclient.message_type == ewmh_atoms[NET_ACTIVE_WINDOW]) {
				if(c) {
					#ifdef DEBUG_EVENTS
					printf(NAME ": ewmh_handle_event(): handling ClientMessage event\n\tatom: _NET_ACTIVE_WINDOW\n");
					#endif
					if(c->flags & ICONIC)
						client_restore(c);
					else {
						if(c->desktop != desktop && c->desktop != STICKY)
							desktop_goto(c->desktop);
						client_raise(c);
					}
					if(evh != wlist_handle_event)
						client_focus(c, true);
				}
				return true;
			}
			if(ev->xclient.message_type == ewmh_atoms[NET_RESTACK_WINDOW]) {
				if(c && ev->xclient.data.l[1] == None) {
					#ifdef DEBUG_EVENTS
					printf(NAME ": ewmh_handle_event(): handling ClientMessage event\n\tatom: _NET_RESTACK_WINDOW\n");
					#endif
					client_raise(c);
				}
				/* schould also add code for handling this when a sibling window is passed */
				/* but we schould find/create a way to test this first */
				return true;
			}
			if(ev->xclient.message_type == ewmh_atoms[NET_WM_STATE]) {
				if(c) {
					#ifdef DEBUG_EVENTS
					printf(NAME ": ewmh_handle_event(): handling ClientMessage event\n\tatom: _NET_WM_STATE\n");
					#endif
					j = 0;
					for(i = 1; i < 3; i++) {
						if(((Atom) ev->xclient.data.l[i]) == ewmh_atoms[NET_WM_STATE_MAXIMIZED_HORZ])
							j |= MAXIMIZED_L | MAXIMIZED_R;
						if(((Atom) ev->xclient.data.l[i]) == ewmh_atoms[NET_WM_STATE_MAXIMIZED_VERT])
							j |= MAXIMIZED_T | MAXIMIZED_B;
					}
					if(j)
						client_toggle_state(c, j);
					if(((Atom) ev->xclient.data.l[1]) == ewmh_atoms[NET_WM_STATE_FULLSCREEN] && (ev->xclient.data.l[0] == NET_WM_STATE_TOGGLE || (ev->xclient.data.l[0] == NET_WM_STATE_ADD && !(c->flags & FULLSCREEN)) || (ev->xclient.data.l[0] == NET_WM_STATE_REMOVE && (c->flags & FULLSCREEN))))
						client_fullscreen(c);
					if(((Atom) ev->xclient.data.l[1]) == ewmh_atoms[NET_WM_STATE_ABOVE]) {
						if(((Atom) ev->xclient.data.l[0]) == ewmh_atoms[NET_WM_STATE_ADD])
							client_set_layer(c, TOP);
						if(((Atom) ev->xclient.data.l[0]) == ewmh_atoms[NET_WM_STATE_REMOVE] && c->layer == TOP)
							client_set_layer(c, NORMAL);
						if(((Atom) ev->xclient.data.l[0]) == ewmh_atoms[NET_WM_STATE_TOGGLE])
							client_set_layer(c, (c->layer == TOP) ? NORMAL : TOP);
					}
					if(((Atom) ev->xclient.data.l[1]) == ewmh_atoms[NET_WM_STATE_BELOW]) {
						if(((Atom) ev->xclient.data.l[0]) == ewmh_atoms[NET_WM_STATE_ADD])
							client_set_layer(c, BOTTOM);
						if(((Atom) ev->xclient.data.l[0]) == ewmh_atoms[NET_WM_STATE_REMOVE] && c->layer == BOTTOM)
							client_set_layer(c, NORMAL);
						if(((Atom) ev->xclient.data.l[0]) == ewmh_atoms[NET_WM_STATE_TOGGLE])
							client_set_layer(c, (c->layer == BOTTOM) ? NORMAL : BOTTOM);
					}
					return true;
				}
			}
			if(ev->xclient.message_type == ewmh_atoms[NET_CURRENT_DESKTOP]) {
				#ifdef DEBUG_EVENTS
				printf(NAME ": ewmh_handle_event(): handling ClientMessage event\n\tatom: _NET_CURRENT_DESKTOP\n");
				#endif
				desktop_goto(ev->xclient.data.l[0]);
				return true;
			}
			if(ev->xclient.message_type == ewmh_atoms[NET_WM_DESKTOP]) {
				if(c && ev->xclient.data.l[0] >= STICKY) {
					#ifdef DEBUG_EVENTS
					printf(NAME ": ewmh_handle_event(): handling ClientMessage event\n\tatom: _NET_WM_DESKTOP\n");
					#endif
					client_to_desktop(c, (ev->xclient.data.l[0] <= dc) ? ev->xclient.data.l[0] : dc - 1);
				}
				return true;
			}
			if(ev->xclient.message_type == ewmh_atoms[NET_REQUEST_FRAME_EXTENTS]) {
				#ifdef DEBUG_EVENTS
				printf(NAME ": ewmh_handle_event(): handling ClientMessage event\n\tatom: _NET_REQUEST_FRAME_EXTENTS\n");
				#endif
				extents[0] = border_width;
				extents[1] = border_width;
				extents[2] = border_width + title_height;
				extents[3] = border_width;
				XChangeProperty(dpy, ev->xclient.window, ewmh_atoms[NET_FRAME_EXTENTS], XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &extents, 4);	
				return true;
			}
			if(ev->xclient.message_type == ewmh_atoms[NET_SHOWING_DESKTOP]) {
				#ifdef DEBUG_EVENTS
				printf(NAME ": ewmh_handle_event(): handling ClientMessage event\n\tatom: _NET_SHOWING_DESKTOP\n");
				#endif
				client_iconify_all();
				return true;
			}
			break;
		case PropertyNotify:
			if(ev->xproperty.atom == ewmh_atoms[NET_WM_STRUT_PARTIAL] || ev->xproperty.atom == ewmh_atoms[NET_WM_STRUT]) {
				#ifdef DEBUG_EVENTS
				printf(NAME ": ewmh_handle_event(): handling PropertyNotify event (_NET_WM_STRUT or _NET_WM_STRUT_PARTIAL changed)\n");
				#endif
				ewmh_update_strut();
				return true;
			}
			c = owner(ev->xproperty.window);
			if(c && ev->xproperty.atom == ewmh_atoms[NET_WM_NAME]) {
				if(XGetWindowProperty(dpy, c->window, ewmh_atoms[NET_WM_NAME], 0, 1024, False, xa_utf8_string, &rt, &rf, &nir, &bar, (unsigned char **) &c->ewmh_name) != Success)
					c->ewmh_name = NULL;
				else client_update_name(c);
				return true;
			}
			break;
		}
	return false;
}