예제 #1
0
파일: layout.c 프로젝트: wavebeem/wmfs
/** Toggle the selected client to free
 * \param cmd uicb_t type unused
*/
void
uicb_togglefree(uicb_t cmd)
{
     (void)cmd;

     if(!sel || sel->screen != screen_get_sel() || (sel->flags & FSSFlag))
          return;

     sel->flags ^= FreeFlag;

     if((sel->flags & FreeFlag))
     {
          sel->flags &= ~(TileFlag | MaxFlag | LMaxFlag);
          client_moveresize(sel, sel->free_geo, True);
          client_raise(sel);
     }
     else
     {
          sel->free_geo = sel->geo;
          sel->ogeo = sel->geo;
     }

     client_update_attributes(sel);

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

     return;
}
예제 #2
0
void
mousefunc_client_resize(void *ctx, union arg *arg, enum xev xev)
{
	struct client_ctx	*cc = ctx;
	XEvent			 ev;
	Time			 ltime = 0;
	struct screen_ctx	*sc = cc->sc;

	if (cc->flags & CLIENT_FREEZE)
		return;

	client_raise(cc);
	client_ptrsave(cc);

	xu_ptr_setpos(cc->win, cc->geom.w, cc->geom.h);

	if (XGrabPointer(X_Dpy, cc->win, False, MOUSEMASK,
	    GrabModeAsync, GrabModeAsync, None, Conf.cursor[CF_RESIZE],
	    CurrentTime) != GrabSuccess)
		return;

	menu_windraw(sc, cc->win, "%4d x %-4d", cc->dim.w, cc->dim.h);

	for (;;) {
		XWindowEvent(X_Dpy, cc->win, MOUSEMASK, &ev);

		switch (ev.type) {
		case MotionNotify:
			/* not more than 60 times / second */
			if ((ev.xmotion.time - ltime) <= (1000 / 60))
				continue;
			ltime = ev.xmotion.time;

			cc->geom.w = ev.xmotion.x;
			cc->geom.h = ev.xmotion.y;
			client_applysizehints(cc);
			client_resize(cc, 1);
			menu_windraw(sc, cc->win,
			    "%4d x %-4d", cc->dim.w, cc->dim.h);
			break;
		case ButtonRelease:
			client_resize(cc, 1);
			XUnmapWindow(X_Dpy, sc->menu.win);
			XReparentWindow(X_Dpy, sc->menu.win, sc->rootwin, 0, 0);
			XUngrabPointer(X_Dpy, CurrentTime);

			/* Make sure the pointer stays within the window. */
			if (cc->ptr.x > cc->geom.w)
				cc->ptr.x = cc->geom.w - cc->bwidth;
			if (cc->ptr.y > cc->geom.h)
				cc->ptr.y = cc->geom.h - cc->bwidth;
			client_ptrwarp(cc);
			return;
		}
	}
	/* NOTREACHED */
}
예제 #3
0
파일: ewmh.c 프로젝트: 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;
}
예제 #4
0
파일: main.c 프로젝트: xiaq/hlwm
int raise_command(int argc, char** argv, GString* output) {
    Window win;
    HSClient* client = NULL;
    win = string_to_client((argc > 1) ? argv[1] : "", &client);
    if (client) {
        client_raise(client);
    } else {
        XRaiseWindow(g_display, win);
    }
    return 0;
}
예제 #5
0
void
mousefunc_client_resize(struct client_ctx *cc, union arg *arg)
{
    XEvent			 ev;
    Time			 ltime = 0;
    struct screen_ctx	*sc = cc->sc;
    int			 x = cc->geom.x, y = cc->geom.y;

    if (cc->flags & CLIENT_FREEZE)
        return;

    client_raise(cc);
    client_ptrsave(cc);

    if (xu_ptr_grab(cc->win, MOUSEMASK, Conf.cursor[CF_RESIZE]) < 0)
        return;

    xu_ptr_setpos(cc->win, cc->geom.w, cc->geom.h);
    mousefunc_sweep_draw(cc);

    for (;;) {
        XMaskEvent(X_Dpy, MOUSEMASK, &ev);

        switch (ev.type) {
        case MotionNotify:
            mousefunc_sweep_calc(cc, x, y,
                                 ev.xmotion.x_root, ev.xmotion.y_root);

            /* don't resize more than 60 times / second */
            if ((ev.xmotion.time - ltime) > (1000 / 60)) {
                ltime = ev.xmotion.time;
                client_resize(cc, 1);
                mousefunc_sweep_draw(cc);
            }
            break;
        case ButtonRelease:
            if (ltime)
                client_resize(cc, 1);
            XUnmapWindow(X_Dpy, sc->menuwin);
            XReparentWindow(X_Dpy, sc->menuwin, sc->rootwin, 0, 0);
            xu_ptr_ungrab();

            /* Make sure the pointer stays within the window. */
            if (cc->ptr.x > cc->geom.w)
                cc->ptr.x = cc->geom.w - cc->bwidth;
            if (cc->ptr.y > cc->geom.h)
                cc->ptr.y = cc->geom.h - cc->bwidth;
            client_ptrwarp(cc);
            return;
        }
    }
    /* NOTREACHED */
}
예제 #6
0
파일: event.c 프로젝트: 8ware/awesome
/** The map request event handler.
 * \param ev The event.
 */
static void
event_handle_maprequest(xcb_map_request_event_t *ev)
{
    client_t *c;
    xcb_get_window_attributes_cookie_t wa_c;
    xcb_get_window_attributes_reply_t *wa_r;
    xcb_get_geometry_cookie_t geom_c;
    xcb_get_geometry_reply_t *geom_r;

    wa_c = xcb_get_window_attributes_unchecked(globalconf.connection, ev->window);

    if(!(wa_r = xcb_get_window_attributes_reply(globalconf.connection, wa_c, NULL)))
        return;

    if(wa_r->override_redirect)
        goto bailout;

    if(xembed_getbywin(&globalconf.embedded, ev->window))
    {
        xcb_map_window(globalconf.connection, ev->window);
        xembed_window_activate(globalconf.connection, ev->window);
    }
    else if((c = client_getbywin(ev->window)))
    {
        /* Check that it may be visible, but not asked to be hidden */
        if(client_on_selected_tags(c) && !c->hidden)
        {
            lua_State *L = globalconf_get_lua_State();
            luaA_object_push(L, c);
            client_set_minimized(L, -1, false);
            lua_pop(L, 1);
            /* it will be raised, so just update ourself */
            client_raise(c);
        }
    }
    else
    {
        geom_c = xcb_get_geometry_unchecked(globalconf.connection, ev->window);

        if(!(geom_r = xcb_get_geometry_reply(globalconf.connection, geom_c, NULL)))
        {
            goto bailout;
        }

        client_manage(ev->window, geom_r, wa_r);

        p_delete(&geom_r);
    }

bailout:
    p_delete(&wa_r);
}
예제 #7
0
void
mousefunc_client_move(struct client_ctx *cc, union arg *arg)
{
    XEvent			 ev;
    Time			 ltime = 0;
    struct screen_ctx	*sc = cc->sc;
    struct geom		 xine;
    int			 px, py;

    client_raise(cc);

    if (cc->flags & CLIENT_FREEZE)
        return;

    if (xu_ptr_grab(cc->win, MOUSEMASK, Conf.cursor[CF_MOVE]) < 0)
        return;

    xu_ptr_getpos(cc->win, &px, &py);

    for (;;) {
        XMaskEvent(X_Dpy, MOUSEMASK, &ev);

        switch (ev.type) {
        case MotionNotify:
            cc->geom.x = ev.xmotion.x_root - px - cc->bwidth;
            cc->geom.y = ev.xmotion.y_root - py - cc->bwidth;

            xine = screen_find_xinerama(sc,
                                        cc->geom.x + cc->geom.w / 2,
                                        cc->geom.y + cc->geom.h / 2, CWM_GAP);
            cc->geom.x += client_snapcalc(cc->geom.x,
                                          cc->geom.x + cc->geom.w + (cc->bwidth * 2),
                                          xine.x, xine.x + xine.w, sc->snapdist);
            cc->geom.y += client_snapcalc(cc->geom.y,
                                          cc->geom.y + cc->geom.h + (cc->bwidth * 2),
                                          xine.y, xine.y + xine.h, sc->snapdist);

            /* don't move more than 60 times / second */
            if ((ev.xmotion.time - ltime) > (1000 / 60)) {
                ltime = ev.xmotion.time;
                client_move(cc);
            }
            break;
        case ButtonRelease:
            if (ltime)
                client_move(cc);
            xu_ptr_ungrab();
            return;
        }
    }
    /* NOTREACHED */
}
예제 #8
0
파일: main.c 프로젝트: xiaq/hlwm
void buttonpress(XEvent* event) {
    XButtonEvent* be = &(event->xbutton);
    HSDebug("name is: ButtonPress on sub %lx, win %lx\n", be->subwindow, be->window);
    if (mouse_binding_find(be->state, be->button)) {
        mouse_start_drag(event);
    } else {
        focus_window(be->window, false, true);
        if (*g_raise_on_click) {
            HSClient* client = get_client_from_window(be->window);
            if (client) {
                client_raise(client);
            }
        }
    }
    XAllowEvents(g_display, ReplayPointer, be->time);
}
예제 #9
0
파일: screen.c 프로젝트: yugecin/evilwm
void sweep(Client *c) {
    XEvent ev;
    int old_cx = c->x;
    int old_cy = c->y;

    if (!grab_pointer(c->screen->root, MouseMask, resize_curs)) return;

    client_raise(c);
#ifdef INFOBANNER_MOVERESIZE
    create_info_window(c);
#endif
    XGrabServer(dpy);
    draw_outline(c);

    setmouse(c->window, c->width, c->height);
    for (;;) {
        XMaskEvent(dpy, MouseMask, &ev);
        switch (ev.type) {
        case MotionNotify:
            if (ev.xmotion.root != c->screen->root)
                break;
            draw_outline(c); /* clear */
            XUngrabServer(dpy);
            recalculate_sweep(c, old_cx, old_cy, ev.xmotion.x, ev.xmotion.y, ev.xmotion.state & altmask);
#ifdef INFOBANNER_MOVERESIZE
            update_info_window(c);
#endif
            XSync(dpy, False);
            XGrabServer(dpy);
            draw_outline(c);
            break;
        case ButtonRelease:
            draw_outline(c); /* clear */
            XUngrabServer(dpy);
#ifdef INFOBANNER_MOVERESIZE
            remove_info_window();
#endif
            XUngrabPointer(dpy, CurrentTime);
            moveresize(c);
            /* In case maximise state has changed: */
            ewmh_set_net_wm_state(c);
            return;
        default:
            break;
        }
    }
}
예제 #10
0
파일: clientlist.c 프로젝트: xiaq/hlwm
void window_focus(Window window) {
    HSClient* client = get_client_from_window(window);
    assert(client != NULL);
    // set keyboard focus
    if (!client->neverfocus) {
        XSetInputFocus(g_display, window, RevertToPointerRoot, CurrentTime);
    }
    else client_sendevent(client, g_wmatom[WMTakeFocus]);

    if (window != lastfocus) {
        /* FIXME: this is a workaround because window_focus always is called
         * twice.  see BUGS for more information
         *
         * only emit the hook if the focus *really* changes */
        // unfocus last one
        window_unfocus(lastfocus);
        hsobject_link(g_client_object, &client->object, "focus");
        ewmh_update_active_window(window);
        tag_update_each_focus_layer();
        char* title = client ? client->title->str : "?";
        char winid_str[STRING_BUF_SIZE];
        snprintf(winid_str, STRING_BUF_SIZE, "0x%x", (unsigned int)window);
        hook_emit_list("focus_changed", winid_str, title, NULL);
    }

    // change window-colors
    HSDebug("window_focus ACTIVE\n");
    window_update_border(window, g_window_border_active_color);

    lastfocus = window;
    /* do some specials for the max layout */
    bool is_max_layout = frame_focused_window(g_cur_frame) == window
                         && g_cur_frame->content.clients.layout == LAYOUT_MAX
                         && get_current_monitor()->tag->floating == false;
    if (*g_raise_on_focus || is_max_layout) {
        client_raise(client);
    }
    tag_update_focus_layer(get_current_monitor()->tag);
    grab_client_buttons(get_client_from_window(window), true);
    client_set_urgent(client, false);
}
예제 #11
0
파일: screen.c 프로젝트: meinhimmel/evilwm
void sweep(Client *c) {
	XEvent ev;
	int old_cx = client_to_Xcoord(c,x);
	int old_cy = client_to_Xcoord(c,y);

	if (!grab_pointer(c->screen->root, MouseMask, resize_curs)) return;

	client_raise(c);
	annotate_create(c, &annotate_sweep_ctx);

	setmouse(c->window, c->width, c->height);
	for (;;) {
		XMaskEvent(dpy, MouseMask, &ev);
		switch (ev.type) {
			case MotionNotify:
				if (ev.xmotion.root != c->screen->root)
					break;
				annotate_preupdate(c, &annotate_sweep_ctx);
				/* perform recalculate_sweep in Xcoordinates, then convert
				 * back relative to the current phy */
				recalculate_sweep(c, old_cx, old_cy, ev.xmotion.x, ev.xmotion.y, ev.xmotion.state & altmask);
				c->nx -= c->phy->xoff;
				c->ny -= c->phy->yoff;
				client_calc_cog(c);
				client_calc_phy(c);
				annotate_update(c, &annotate_sweep_ctx);
				break;
			case ButtonRelease:
				annotate_remove(c, &annotate_sweep_ctx);
				client_calc_phy(c);
				XUngrabPointer(dpy, CurrentTime);
				moveresizeraise(c);
				/* In case maximise state has changed: */
				ewmh_set_net_wm_state(c);
				return;
			default: break;
		}
	}
}
예제 #12
0
void
mousefunc_client_move(void *ctx, union arg *arg, enum xev xev)
{
	struct client_ctx	*cc = ctx;
	XEvent			 ev;
	Time			 ltime = 0;
	struct screen_ctx	*sc = cc->sc;
	struct geom		 area;
	int			 px, py;

	client_raise(cc);

	if (cc->flags & CLIENT_FREEZE)
		return;

	xu_ptr_getpos(cc->win, &px, &py);
	if (px < 0) 
		px = 0;
	else if (px > cc->geom.w)
		px = cc->geom.w;
	if (py < 0)
		py = 0;
	else if (py > cc->geom.h)
		py = cc->geom.h;

	xu_ptr_setpos(cc->win, px, py);

	if (XGrabPointer(X_Dpy, cc->win, False, MOUSEMASK,
	    GrabModeAsync, GrabModeAsync, None, Conf.cursor[CF_MOVE],
	    CurrentTime) != GrabSuccess)
		return;

	menu_windraw(sc, cc->win, "%4d, %-4d", cc->geom.x, cc->geom.y);

	for (;;) {
		XWindowEvent(X_Dpy, cc->win, MOUSEMASK, &ev);

		switch (ev.type) {
		case MotionNotify:
			/* not more than 60 times / second */
			if ((ev.xmotion.time - ltime) <= (1000 / 60))
				continue;
			ltime = ev.xmotion.time;

			cc->geom.x = ev.xmotion.x_root - px - cc->bwidth;
			cc->geom.y = ev.xmotion.y_root - py - cc->bwidth;

			area = screen_area(sc,
			    cc->geom.x + cc->geom.w / 2,
			    cc->geom.y + cc->geom.h / 2, CWM_GAP);
			cc->geom.x += client_snapcalc(cc->geom.x,
			    cc->geom.x + cc->geom.w + (cc->bwidth * 2),
			    area.x, area.x + area.w, sc->snapdist);
			cc->geom.y += client_snapcalc(cc->geom.y,
			    cc->geom.y + cc->geom.h + (cc->bwidth * 2),
			    area.y, area.y + area.h, sc->snapdist);
			client_move(cc);
			menu_windraw(sc, cc->win,
			    "%4d, %-4d", cc->geom.x, cc->geom.y);
			break;
		case ButtonRelease:
			client_move(cc);
			XUnmapWindow(X_Dpy, sc->menu.win);
			XReparentWindow(X_Dpy, sc->menu.win, sc->rootwin, 0, 0);
			XUngrabPointer(X_Dpy, CurrentTime);
			return;
		}
	}
	/* NOTREACHED */
}
예제 #13
0
파일: ewmh.c 프로젝트: segin/matwm2
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;
}
예제 #14
0
파일: event.c 프로젝트: 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;
}
예제 #15
0
파일: magnifier.c 프로젝트: kanru/awesome
void
layout_magnifier(int screen)
{
    int n = 0;
    client_t *c, *focus;
    tag_t **curtags = tags_get_current(screen);
    area_t geometry, area = screen_area_get(screen,
                                            &globalconf.screens[screen].wiboxes,
                                            &globalconf.screens[screen].padding,
                                            true);

    focus = globalconf.screens[screen].client_focus;

    /* Find parent of this window, if it has one. */
    if (!IS_TILED(focus, screen) && focus && focus->transient_for)
        do {
            focus = focus->transient_for;
        } while (focus->transient_for != NULL);

    /* If focused window is not tiled, take the first one which is tiled. */
    if(!IS_TILED(focus, screen))
        for(focus = globalconf.clients; focus && !IS_TILED(focus, screen); focus = focus->next);

    /* No windows is tiled, nothing to do. */
    if(!focus)
        goto bailout;

    for(c = client_list_prev_cycle(&globalconf.clients, focus);
        c && c != focus;
        c = client_list_prev_cycle(&globalconf.clients, c))
        if(IS_TILED(c, screen) && c != focus)
            n++;

    if(n)
    {
        geometry.width = area.width * sqrt(curtags[0]->mwfact);
        geometry.height = area.height *  sqrt(curtags[0]->mwfact);
        geometry.x = area.x + (area.width - geometry.width) / 2;
        geometry.y = area.y + (area.height - geometry.height) / 2;
    }
    else
    {
       /* No other clients. */
        geometry = area;
        geometry.width -= 2 * focus->border;
        geometry.height -= 2 * focus->border;
    }
    client_resize(focus, geometry, focus->honorsizehints);
    client_raise(focus);

    /* bailout when there is only one window */
    if (!n)
	goto bailout;

    geometry.x = area.x;
    geometry.y = area.y;
    geometry.height = area.height / n;
    geometry.width = area.width;

    for(c = client_list_prev_cycle(&globalconf.clients, focus);
        c && c != focus;
        c = client_list_prev_cycle(&globalconf.clients, c))
        if(IS_TILED(c, screen) && c != focus)
        {
            geometry.height -= 2 * c->border;
            geometry.width -= 2 * c->border;
            client_resize(c, geometry, c->honorsizehints);
            geometry.height += 2 * c->border;
            geometry.width += 2 * c->border;
            geometry.y += geometry.height;
        }

bailout:
    p_delete(&curtags);
}
예제 #16
0
파일: events.c 프로젝트: segin/matwm2
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();
				}
			}
	}
}