2007-04-27 11:58:48 -06:00
|
|
|
/*
|
|
|
|
* calmwm - the calm window manager
|
|
|
|
*
|
|
|
|
* Copyright (c) 2004 Marius Aamodt Eriksen <marius@monkey.org>
|
|
|
|
*
|
2008-01-11 09:06:44 -07:00
|
|
|
* Permission to use, copy, modify, and distribute this software for any
|
|
|
|
* purpose with or without fee is hereby granted, provided that the above
|
|
|
|
* copyright notice and this permission notice appear in all copies.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
|
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
|
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
|
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
|
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
|
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
|
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
|
|
*
|
2020-02-27 07:56:39 -07:00
|
|
|
* $OpenBSD: xevents.c,v 1.149 2020/02/27 14:56:39 okan Exp $
|
2007-04-27 11:58:48 -06:00
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* NOTE:
|
|
|
|
* It is the responsibility of the caller to deal with memory
|
|
|
|
* management of the xevent's.
|
|
|
|
*/
|
|
|
|
|
2015-01-19 07:54:16 -07:00
|
|
|
#include <sys/types.h>
|
2009-12-14 21:10:42 -07:00
|
|
|
#include <sys/queue.h>
|
|
|
|
|
|
|
|
#include <err.h>
|
|
|
|
#include <errno.h>
|
2015-01-19 07:54:16 -07:00
|
|
|
#include <limits.h>
|
2012-11-08 20:52:02 -07:00
|
|
|
#include <stdio.h>
|
2009-12-14 21:10:42 -07:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
|
2007-04-27 11:58:48 -06:00
|
|
|
#include "calmwm.h"
|
|
|
|
|
2009-05-17 18:14:19 -06:00
|
|
|
static void xev_handle_maprequest(XEvent *);
|
|
|
|
static void xev_handle_unmapnotify(XEvent *);
|
|
|
|
static void xev_handle_destroynotify(XEvent *);
|
|
|
|
static void xev_handle_configurerequest(XEvent *);
|
|
|
|
static void xev_handle_propertynotify(XEvent *);
|
|
|
|
static void xev_handle_enternotify(XEvent *);
|
|
|
|
static void xev_handle_buttonpress(XEvent *);
|
|
|
|
static void xev_handle_buttonrelease(XEvent *);
|
|
|
|
static void xev_handle_keypress(XEvent *);
|
|
|
|
static void xev_handle_keyrelease(XEvent *);
|
|
|
|
static void xev_handle_clientmessage(XEvent *);
|
|
|
|
static void xev_handle_randr(XEvent *);
|
|
|
|
static void xev_handle_mappingnotify(XEvent *);
|
2013-12-13 07:45:47 -07:00
|
|
|
static void xev_handle_expose(XEvent *);
|
2009-05-17 18:14:19 -06:00
|
|
|
|
|
|
|
void (*xev_handlers[LASTEvent])(XEvent *) = {
|
|
|
|
[MapRequest] = xev_handle_maprequest,
|
|
|
|
[UnmapNotify] = xev_handle_unmapnotify,
|
2013-12-13 07:45:47 -07:00
|
|
|
[DestroyNotify] = xev_handle_destroynotify,
|
2009-05-17 18:14:19 -06:00
|
|
|
[ConfigureRequest] = xev_handle_configurerequest,
|
|
|
|
[PropertyNotify] = xev_handle_propertynotify,
|
|
|
|
[EnterNotify] = xev_handle_enternotify,
|
|
|
|
[ButtonPress] = xev_handle_buttonpress,
|
|
|
|
[ButtonRelease] = xev_handle_buttonrelease,
|
|
|
|
[KeyPress] = xev_handle_keypress,
|
|
|
|
[KeyRelease] = xev_handle_keyrelease,
|
|
|
|
[ClientMessage] = xev_handle_clientmessage,
|
|
|
|
[MappingNotify] = xev_handle_mappingnotify,
|
2013-12-13 07:45:47 -07:00
|
|
|
[Expose] = xev_handle_expose,
|
2009-05-17 18:14:19 -06:00
|
|
|
};
|
2007-04-27 11:58:48 -06:00
|
|
|
|
2012-05-15 19:09:17 -06:00
|
|
|
static KeySym modkeys[] = { XK_Alt_L, XK_Alt_R, XK_Super_L, XK_Super_R,
|
2020-02-03 09:38:02 -07:00
|
|
|
XK_Control_L, XK_Control_R, XK_ISO_Level3_Shift };
|
2012-05-15 19:09:17 -06:00
|
|
|
|
2009-05-17 18:14:19 -06:00
|
|
|
static void
|
|
|
|
xev_handle_maprequest(XEvent *ee)
|
2007-04-27 11:58:48 -06:00
|
|
|
{
|
2008-07-11 08:21:28 -06:00
|
|
|
XMapRequestEvent *e = &ee->xmaprequest;
|
2019-03-10 14:38:28 -06:00
|
|
|
struct screen_ctx *sc;
|
|
|
|
struct client_ctx *cc, *old_cc;
|
2007-04-27 11:58:48 -06:00
|
|
|
|
2019-03-10 14:38:28 -06:00
|
|
|
LOG_DEBUG3("parent: 0x%lx window: 0x%lx", e->parent, e->window);
|
|
|
|
|
|
|
|
if ((sc = screen_find(e->parent)) == NULL)
|
|
|
|
return;
|
2018-02-02 06:50:22 -07:00
|
|
|
|
2019-03-10 14:38:28 -06:00
|
|
|
if ((old_cc = client_current(sc)) != NULL)
|
2020-02-27 07:56:39 -07:00
|
|
|
client_ptr_save(old_cc);
|
2007-04-27 11:58:48 -06:00
|
|
|
|
2014-02-02 14:34:05 -07:00
|
|
|
if ((cc = client_find(e->window)) == NULL)
|
2016-09-16 08:32:02 -06:00
|
|
|
cc = client_init(e->window, NULL, 0);
|
2007-04-27 11:58:48 -06:00
|
|
|
|
2014-09-15 07:00:49 -06:00
|
|
|
if ((cc != NULL) && (!(cc->flags & CLIENT_IGNORE)))
|
2020-02-27 07:56:39 -07:00
|
|
|
client_ptr_warp(cc);
|
2007-04-27 11:58:48 -06:00
|
|
|
}
|
|
|
|
|
2009-05-17 18:14:19 -06:00
|
|
|
static void
|
|
|
|
xev_handle_unmapnotify(XEvent *ee)
|
2007-04-27 11:58:48 -06:00
|
|
|
{
|
2008-07-11 08:21:28 -06:00
|
|
|
XUnmapEvent *e = &ee->xunmap;
|
|
|
|
struct client_ctx *cc;
|
2007-04-27 11:58:48 -06:00
|
|
|
|
2018-02-04 15:56:26 -07:00
|
|
|
LOG_DEBUG3("window: 0x%lx", e->window);
|
2018-02-02 06:50:22 -07:00
|
|
|
|
2009-01-17 11:41:50 -07:00
|
|
|
if ((cc = client_find(e->window)) != NULL) {
|
2013-11-12 14:25:00 -07:00
|
|
|
if (e->send_event) {
|
2020-02-27 07:56:39 -07:00
|
|
|
xu_set_wm_state(cc->win, WithdrawnState);
|
2013-12-02 07:30:12 -07:00
|
|
|
} else {
|
|
|
|
if (!(cc->flags & CLIENT_HIDDEN))
|
2019-02-22 12:40:32 -07:00
|
|
|
client_remove(cc);
|
2013-12-02 07:30:12 -07:00
|
|
|
}
|
2009-01-17 11:41:50 -07:00
|
|
|
}
|
2007-04-27 11:58:48 -06:00
|
|
|
}
|
|
|
|
|
2009-05-17 18:14:19 -06:00
|
|
|
static void
|
|
|
|
xev_handle_destroynotify(XEvent *ee)
|
2007-04-27 11:58:48 -06:00
|
|
|
{
|
2008-07-11 08:21:28 -06:00
|
|
|
XDestroyWindowEvent *e = &ee->xdestroywindow;
|
|
|
|
struct client_ctx *cc;
|
2007-04-27 11:58:48 -06:00
|
|
|
|
2018-02-04 15:56:26 -07:00
|
|
|
LOG_DEBUG3("window: 0x%lx", e->window);
|
2018-02-02 06:50:22 -07:00
|
|
|
|
2007-04-27 11:58:48 -06:00
|
|
|
if ((cc = client_find(e->window)) != NULL)
|
2019-02-22 12:40:32 -07:00
|
|
|
client_remove(cc);
|
2007-04-27 11:58:48 -06:00
|
|
|
}
|
|
|
|
|
2009-05-17 18:14:19 -06:00
|
|
|
static void
|
|
|
|
xev_handle_configurerequest(XEvent *ee)
|
2007-04-27 11:58:48 -06:00
|
|
|
{
|
2008-07-11 08:21:28 -06:00
|
|
|
XConfigureRequestEvent *e = &ee->xconfigurerequest;
|
|
|
|
struct client_ctx *cc;
|
|
|
|
struct screen_ctx *sc;
|
|
|
|
XWindowChanges wc;
|
2007-04-27 11:58:48 -06:00
|
|
|
|
2018-02-04 15:56:26 -07:00
|
|
|
LOG_DEBUG3("window: 0x%lx", e->window);
|
2018-02-02 06:50:22 -07:00
|
|
|
|
2007-04-27 11:58:48 -06:00
|
|
|
if ((cc = client_find(e->window)) != NULL) {
|
2009-08-26 19:38:08 -06:00
|
|
|
sc = cc->sc;
|
2007-04-27 11:58:48 -06:00
|
|
|
|
|
|
|
if (e->value_mask & CWWidth)
|
2012-07-13 11:01:04 -06:00
|
|
|
cc->geom.w = e->width;
|
2007-04-27 11:58:48 -06:00
|
|
|
if (e->value_mask & CWHeight)
|
2012-07-13 11:01:04 -06:00
|
|
|
cc->geom.h = e->height;
|
2007-04-27 11:58:48 -06:00
|
|
|
if (e->value_mask & CWX)
|
|
|
|
cc->geom.x = e->x;
|
|
|
|
if (e->value_mask & CWY)
|
|
|
|
cc->geom.y = e->y;
|
2009-01-22 12:01:56 -07:00
|
|
|
if (e->value_mask & CWBorderWidth)
|
2013-06-10 14:11:43 -06:00
|
|
|
cc->bwidth = e->border_width;
|
|
|
|
if (e->value_mask & CWSibling)
|
|
|
|
wc.sibling = e->above;
|
|
|
|
if (e->value_mask & CWStackMode)
|
|
|
|
wc.stack_mode = e->detail;
|
2007-04-27 11:58:48 -06:00
|
|
|
|
2012-07-13 11:01:04 -06:00
|
|
|
if (cc->geom.x == 0 && cc->geom.w >= sc->view.w)
|
2007-04-27 11:58:48 -06:00
|
|
|
cc->geom.x -= cc->bwidth;
|
|
|
|
|
2012-07-13 11:01:04 -06:00
|
|
|
if (cc->geom.y == 0 && cc->geom.h >= sc->view.h)
|
2008-04-15 14:24:41 -06:00
|
|
|
cc->geom.y -= cc->bwidth;
|
2007-04-27 11:58:48 -06:00
|
|
|
|
2009-01-22 12:01:56 -07:00
|
|
|
wc.x = cc->geom.x;
|
|
|
|
wc.y = cc->geom.y;
|
2012-07-13 11:01:04 -06:00
|
|
|
wc.width = cc->geom.w;
|
|
|
|
wc.height = cc->geom.h;
|
2009-01-16 08:24:14 -07:00
|
|
|
wc.border_width = cc->bwidth;
|
2007-04-27 11:58:48 -06:00
|
|
|
|
2009-01-16 08:24:14 -07:00
|
|
|
XConfigureWindow(X_Dpy, cc->win, e->value_mask, &wc);
|
2013-06-10 15:37:30 -06:00
|
|
|
client_config(cc);
|
2009-01-16 08:24:14 -07:00
|
|
|
} else {
|
|
|
|
/* let it do what it wants, it'll be ours when we map it. */
|
|
|
|
wc.x = e->x;
|
|
|
|
wc.y = e->y;
|
|
|
|
wc.width = e->width;
|
|
|
|
wc.height = e->height;
|
2009-01-22 12:01:56 -07:00
|
|
|
wc.border_width = e->border_width;
|
2009-01-16 08:24:14 -07:00
|
|
|
wc.stack_mode = Above;
|
|
|
|
e->value_mask &= ~CWStackMode;
|
|
|
|
|
|
|
|
XConfigureWindow(X_Dpy, e->window, e->value_mask, &wc);
|
2007-04-27 11:58:48 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-05-17 18:14:19 -06:00
|
|
|
static void
|
|
|
|
xev_handle_propertynotify(XEvent *ee)
|
2007-04-27 11:58:48 -06:00
|
|
|
{
|
2008-07-11 08:21:28 -06:00
|
|
|
XPropertyEvent *e = &ee->xproperty;
|
2009-12-11 10:51:42 -07:00
|
|
|
struct screen_ctx *sc;
|
2008-07-11 08:21:28 -06:00
|
|
|
struct client_ctx *cc;
|
2007-04-27 11:58:48 -06:00
|
|
|
|
2018-02-04 15:56:26 -07:00
|
|
|
LOG_DEBUG3("window: 0x%lx", e->window);
|
2018-02-02 06:50:22 -07:00
|
|
|
|
2007-04-27 11:58:48 -06:00
|
|
|
if ((cc = client_find(e->window)) != NULL) {
|
2008-04-15 14:24:41 -06:00
|
|
|
switch (e->atom) {
|
2007-04-27 11:58:48 -06:00
|
|
|
case XA_WM_NORMAL_HINTS:
|
2020-02-27 07:56:39 -07:00
|
|
|
client_get_sizehints(cc);
|
2007-04-27 11:58:48 -06:00
|
|
|
break;
|
|
|
|
case XA_WM_NAME:
|
2020-02-27 07:56:39 -07:00
|
|
|
client_set_name(cc);
|
2007-04-27 11:58:48 -06:00
|
|
|
break;
|
2013-12-11 08:41:11 -07:00
|
|
|
case XA_WM_HINTS:
|
|
|
|
client_wm_hints(cc);
|
2013-12-13 07:40:52 -07:00
|
|
|
client_draw_border(cc);
|
2013-12-11 08:41:11 -07:00
|
|
|
break;
|
2011-09-13 02:41:57 -06:00
|
|
|
case XA_WM_TRANSIENT_FOR:
|
|
|
|
client_transient(cc);
|
2018-11-13 10:37:13 -07:00
|
|
|
client_draw_border(cc);
|
|
|
|
if (cc->gc)
|
|
|
|
group_movetogroup(cc, cc->gc->num);
|
2011-09-13 02:41:57 -06:00
|
|
|
break;
|
2007-04-27 11:58:48 -06:00
|
|
|
default:
|
2019-04-29 13:02:21 -06:00
|
|
|
if (e->atom == ewmh[_NET_WM_NAME])
|
2020-02-27 07:56:39 -07:00
|
|
|
client_set_name(cc);
|
2007-04-27 11:58:48 -06:00
|
|
|
break;
|
|
|
|
}
|
2019-03-11 09:25:46 -06:00
|
|
|
} else {
|
|
|
|
if (e->atom == ewmh[_NET_DESKTOP_NAMES]) {
|
|
|
|
if ((sc = screen_find(e->window)) != NULL)
|
|
|
|
xu_ewmh_net_desktop_names(sc);
|
|
|
|
}
|
2007-04-27 11:58:48 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-05-17 18:14:19 -06:00
|
|
|
static void
|
|
|
|
xev_handle_enternotify(XEvent *ee)
|
2007-04-27 11:58:48 -06:00
|
|
|
{
|
2008-07-11 08:21:28 -06:00
|
|
|
XCrossingEvent *e = &ee->xcrossing;
|
|
|
|
struct client_ctx *cc;
|
2007-04-27 11:58:48 -06:00
|
|
|
|
2018-02-04 15:56:26 -07:00
|
|
|
LOG_DEBUG3("window: 0x%lx", e->window);
|
2018-02-02 06:50:22 -07:00
|
|
|
|
2013-12-12 13:15:07 -07:00
|
|
|
Last_Event_Time = e->time;
|
|
|
|
|
2009-01-17 13:39:24 -07:00
|
|
|
if ((cc = client_find(e->window)) != NULL)
|
2020-02-27 07:56:39 -07:00
|
|
|
client_set_active(cc);
|
2007-04-27 11:58:48 -06:00
|
|
|
}
|
|
|
|
|
2009-05-17 18:14:19 -06:00
|
|
|
static void
|
|
|
|
xev_handle_buttonpress(XEvent *ee)
|
2007-04-27 11:58:48 -06:00
|
|
|
{
|
2008-06-17 14:21:17 -06:00
|
|
|
XButtonEvent *e = &ee->xbutton;
|
2016-10-18 11:03:30 -06:00
|
|
|
struct client_ctx *cc;
|
|
|
|
struct screen_ctx *sc;
|
|
|
|
struct bind_ctx *mb;
|
2007-04-27 11:58:48 -06:00
|
|
|
|
2019-03-08 08:04:39 -07:00
|
|
|
LOG_DEBUG3("root: 0x%lx window: 0x%lx subwindow: 0x%lx",
|
|
|
|
e->root, e->window, e->subwindow);
|
2018-02-02 06:50:22 -07:00
|
|
|
|
2019-03-08 10:40:43 -07:00
|
|
|
if ((sc = screen_find(e->root)) == NULL)
|
|
|
|
return;
|
|
|
|
|
2012-12-18 10:37:39 -07:00
|
|
|
e->state &= ~IGNOREMODMASK;
|
2008-06-17 17:40:33 -06:00
|
|
|
|
2016-10-18 11:03:30 -06:00
|
|
|
TAILQ_FOREACH(mb, &Conf.mousebindq, entry) {
|
2014-01-29 14:13:52 -07:00
|
|
|
if (e->button == mb->press.button && e->state == mb->modmask)
|
2008-06-17 14:55:48 -06:00
|
|
|
break;
|
2008-06-17 14:21:17 -06:00
|
|
|
}
|
2008-06-17 14:55:48 -06:00
|
|
|
if (mb == NULL)
|
2009-05-17 18:14:19 -06:00
|
|
|
return;
|
2017-05-09 07:40:18 -06:00
|
|
|
mb->cargs->xev = CWM_XEV_BTN;
|
2016-10-18 11:03:30 -06:00
|
|
|
switch (mb->context) {
|
|
|
|
case CWM_CONTEXT_CC:
|
2013-07-10 08:15:58 -06:00
|
|
|
if (((cc = client_find(e->window)) == NULL) &&
|
2019-03-08 10:40:43 -07:00
|
|
|
((cc = client_current(sc)) == NULL))
|
2013-07-10 08:15:58 -06:00
|
|
|
return;
|
2017-05-09 07:40:18 -06:00
|
|
|
(*mb->callback)(cc, mb->cargs);
|
2016-10-18 11:03:30 -06:00
|
|
|
break;
|
|
|
|
case CWM_CONTEXT_SC:
|
2017-05-09 07:40:18 -06:00
|
|
|
(*mb->callback)(sc, mb->cargs);
|
2016-10-18 11:03:30 -06:00
|
|
|
break;
|
|
|
|
case CWM_CONTEXT_NONE:
|
2017-05-09 07:40:18 -06:00
|
|
|
(*mb->callback)(NULL, mb->cargs);
|
2016-10-18 11:03:30 -06:00
|
|
|
break;
|
2013-07-10 08:15:58 -06:00
|
|
|
}
|
2007-04-27 11:58:48 -06:00
|
|
|
}
|
|
|
|
|
2009-05-17 18:14:19 -06:00
|
|
|
static void
|
|
|
|
xev_handle_buttonrelease(XEvent *ee)
|
2007-04-27 11:58:48 -06:00
|
|
|
{
|
2016-09-14 13:45:33 -06:00
|
|
|
XButtonEvent *e = &ee->xbutton;
|
|
|
|
struct client_ctx *cc;
|
2007-04-27 11:58:48 -06:00
|
|
|
|
2019-03-08 08:04:39 -07:00
|
|
|
LOG_DEBUG3("root: 0x%lx window: 0x%lx subwindow: 0x%lx",
|
|
|
|
e->root, e->window, e->subwindow);
|
2018-02-02 06:50:22 -07:00
|
|
|
|
2016-09-14 13:45:33 -06:00
|
|
|
if ((cc = client_find(e->window)) != NULL) {
|
2017-12-29 09:55:50 -07:00
|
|
|
if (cc->flags & (CLIENT_ACTIVE | CLIENT_HIGHLIGHT)) {
|
|
|
|
cc->flags &= ~CLIENT_HIGHLIGHT;
|
|
|
|
client_draw_border(cc);
|
|
|
|
}
|
2016-09-14 13:45:33 -06:00
|
|
|
}
|
2007-04-27 11:58:48 -06:00
|
|
|
}
|
|
|
|
|
2009-05-17 18:14:19 -06:00
|
|
|
static void
|
|
|
|
xev_handle_keypress(XEvent *ee)
|
2007-04-27 11:58:48 -06:00
|
|
|
{
|
2008-07-11 08:21:28 -06:00
|
|
|
XKeyEvent *e = &ee->xkey;
|
2016-10-18 11:03:30 -06:00
|
|
|
struct client_ctx *cc;
|
|
|
|
struct screen_ctx *sc;
|
|
|
|
struct bind_ctx *kb;
|
2008-07-11 08:21:28 -06:00
|
|
|
KeySym keysym, skeysym;
|
2014-01-03 08:29:06 -07:00
|
|
|
unsigned int modshift;
|
2007-04-27 11:58:48 -06:00
|
|
|
|
2019-03-08 08:04:39 -07:00
|
|
|
LOG_DEBUG3("root: 0x%lx window: 0x%lx subwindow: 0x%lx",
|
2019-03-08 07:48:02 -07:00
|
|
|
e->root, e->window, e->subwindow);
|
|
|
|
|
|
|
|
if ((sc = screen_find(e->root)) == NULL)
|
|
|
|
return;
|
2018-02-02 06:50:22 -07:00
|
|
|
|
2012-05-15 19:04:36 -06:00
|
|
|
keysym = XkbKeycodeToKeysym(X_Dpy, e->keycode, 0, 0);
|
|
|
|
skeysym = XkbKeycodeToKeysym(X_Dpy, e->keycode, 0, 1);
|
2008-04-15 14:24:41 -06:00
|
|
|
|
2012-12-18 10:37:39 -07:00
|
|
|
e->state &= ~IGNOREMODMASK;
|
2008-06-17 17:40:33 -06:00
|
|
|
|
2016-10-18 11:03:30 -06:00
|
|
|
TAILQ_FOREACH(kb, &Conf.keybindq, entry) {
|
2014-01-29 14:13:52 -07:00
|
|
|
if (keysym != kb->press.keysym && skeysym == kb->press.keysym)
|
2007-04-27 11:58:48 -06:00
|
|
|
modshift = ShiftMask;
|
|
|
|
else
|
|
|
|
modshift = 0;
|
|
|
|
|
|
|
|
if ((kb->modmask | modshift) != e->state)
|
|
|
|
continue;
|
|
|
|
|
2015-07-01 08:36:42 -06:00
|
|
|
if (kb->press.keysym == ((modshift == 0) ? keysym : skeysym))
|
2007-04-27 11:58:48 -06:00
|
|
|
break;
|
2008-04-15 14:24:41 -06:00
|
|
|
}
|
2007-04-27 11:58:48 -06:00
|
|
|
if (kb == NULL)
|
2009-05-17 18:14:19 -06:00
|
|
|
return;
|
2017-05-09 07:40:18 -06:00
|
|
|
kb->cargs->xev = CWM_XEV_KEY;
|
2016-10-18 11:03:30 -06:00
|
|
|
switch (kb->context) {
|
|
|
|
case CWM_CONTEXT_CC:
|
2019-03-08 07:48:02 -07:00
|
|
|
if (((cc = client_find(e->subwindow)) == NULL) &&
|
|
|
|
((cc = client_current(sc)) == NULL))
|
2009-05-17 18:14:19 -06:00
|
|
|
return;
|
2017-05-09 07:40:18 -06:00
|
|
|
(*kb->callback)(cc, kb->cargs);
|
2016-10-18 11:03:30 -06:00
|
|
|
break;
|
|
|
|
case CWM_CONTEXT_SC:
|
2017-05-09 07:40:18 -06:00
|
|
|
(*kb->callback)(sc, kb->cargs);
|
2016-10-18 11:03:30 -06:00
|
|
|
break;
|
|
|
|
case CWM_CONTEXT_NONE:
|
2017-05-09 07:40:18 -06:00
|
|
|
(*kb->callback)(NULL, kb->cargs);
|
2016-10-18 11:03:30 -06:00
|
|
|
break;
|
2009-12-10 10:16:51 -07:00
|
|
|
}
|
2007-04-27 11:58:48 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2012-05-15 19:09:17 -06:00
|
|
|
* This is only used for the modifier suppression detection.
|
2007-04-27 11:58:48 -06:00
|
|
|
*/
|
2009-05-17 18:14:19 -06:00
|
|
|
static void
|
|
|
|
xev_handle_keyrelease(XEvent *ee)
|
2007-04-27 11:58:48 -06:00
|
|
|
{
|
2008-07-11 08:21:28 -06:00
|
|
|
XKeyEvent *e = &ee->xkey;
|
|
|
|
struct screen_ctx *sc;
|
2017-12-29 11:50:43 -07:00
|
|
|
struct client_ctx *cc;
|
2013-05-10 09:44:43 -06:00
|
|
|
KeySym keysym;
|
2014-01-03 08:29:06 -07:00
|
|
|
unsigned int i;
|
2008-07-11 08:21:28 -06:00
|
|
|
|
2019-03-08 08:04:39 -07:00
|
|
|
LOG_DEBUG3("root: 0x%lx window: 0x%lx subwindow: 0x%lx",
|
|
|
|
e->root, e->window, e->subwindow);
|
2018-02-02 06:50:22 -07:00
|
|
|
|
2015-06-30 08:01:43 -06:00
|
|
|
if ((sc = screen_find(e->root)) == NULL)
|
|
|
|
return;
|
2007-04-27 11:58:48 -06:00
|
|
|
|
2012-05-15 19:04:36 -06:00
|
|
|
keysym = XkbKeycodeToKeysym(X_Dpy, e->keycode, 0, 0);
|
2012-05-15 19:09:17 -06:00
|
|
|
for (i = 0; i < nitems(modkeys); i++) {
|
|
|
|
if (keysym == modkeys[i]) {
|
2019-03-10 14:38:28 -06:00
|
|
|
if ((cc = client_current(sc)) != NULL) {
|
2017-12-29 11:50:43 -07:00
|
|
|
if (sc->cycling) {
|
|
|
|
sc->cycling = 0;
|
|
|
|
client_mtf(cc);
|
|
|
|
}
|
|
|
|
if (cc->flags & CLIENT_HIGHLIGHT) {
|
|
|
|
cc->flags &= ~CLIENT_HIGHLIGHT;
|
|
|
|
client_draw_border(cc);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
XUngrabKeyboard(X_Dpy, CurrentTime);
|
2012-05-15 19:09:17 -06:00
|
|
|
break;
|
|
|
|
}
|
2008-05-19 06:56:58 -06:00
|
|
|
}
|
2007-04-27 11:58:48 -06:00
|
|
|
}
|
|
|
|
|
2009-05-17 18:14:19 -06:00
|
|
|
static void
|
|
|
|
xev_handle_clientmessage(XEvent *ee)
|
2007-04-27 11:58:48 -06:00
|
|
|
{
|
2008-07-11 08:21:28 -06:00
|
|
|
XClientMessageEvent *e = &ee->xclient;
|
2013-05-20 15:19:15 -06:00
|
|
|
struct client_ctx *cc, *old_cc;
|
2014-01-02 15:43:55 -07:00
|
|
|
struct screen_ctx *sc;
|
2007-04-27 11:58:48 -06:00
|
|
|
|
2018-02-04 15:56:26 -07:00
|
|
|
LOG_DEBUG3("window: 0x%lx", e->window);
|
2018-02-02 06:50:22 -07:00
|
|
|
|
2015-06-30 08:01:43 -06:00
|
|
|
if (e->message_type == cwmh[WM_CHANGE_STATE]) {
|
|
|
|
if ((cc = client_find(e->window)) != NULL) {
|
|
|
|
if (e->data.l[0] == IconicState)
|
|
|
|
client_hide(cc);
|
|
|
|
}
|
|
|
|
} else if (e->message_type == ewmh[_NET_CLOSE_WINDOW]) {
|
|
|
|
if ((cc = client_find(e->window)) != NULL) {
|
2019-02-22 12:40:32 -07:00
|
|
|
client_close(cc);
|
2015-06-30 08:01:43 -06:00
|
|
|
}
|
|
|
|
} else if (e->message_type == ewmh[_NET_ACTIVE_WINDOW]) {
|
|
|
|
if ((cc = client_find(e->window)) != NULL) {
|
2019-03-07 07:28:17 -07:00
|
|
|
if ((old_cc = client_current(NULL)) != NULL)
|
2020-02-27 07:56:39 -07:00
|
|
|
client_ptr_save(old_cc);
|
2017-12-29 05:54:54 -07:00
|
|
|
client_show(cc);
|
2020-02-27 07:56:39 -07:00
|
|
|
client_ptr_warp(cc);
|
2015-06-30 08:01:43 -06:00
|
|
|
}
|
|
|
|
} else if (e->message_type == ewmh[_NET_WM_DESKTOP]) {
|
|
|
|
if ((cc = client_find(e->window)) != NULL) {
|
|
|
|
/*
|
|
|
|
* The EWMH spec states that if the cardinal returned
|
|
|
|
* is 0xFFFFFFFF (-1) then the window should appear
|
|
|
|
* on all desktops, in our case, group 0.
|
|
|
|
*/
|
|
|
|
if (e->data.l[0] == (unsigned long)-1)
|
|
|
|
group_movetogroup(cc, 0);
|
|
|
|
else
|
2019-02-28 16:26:12 -07:00
|
|
|
if (e->data.l[0] >= 0 &&
|
|
|
|
e->data.l[0] < Conf.ngroups)
|
|
|
|
group_movetogroup(cc, e->data.l[0]);
|
2015-06-30 08:01:43 -06:00
|
|
|
}
|
|
|
|
} else if (e->message_type == ewmh[_NET_WM_STATE]) {
|
|
|
|
if ((cc = client_find(e->window)) != NULL) {
|
|
|
|
xu_ewmh_handle_net_wm_state_msg(cc,
|
|
|
|
e->data.l[0], e->data.l[1], e->data.l[2]);
|
|
|
|
}
|
|
|
|
} else if (e->message_type == ewmh[_NET_CURRENT_DESKTOP]) {
|
|
|
|
if ((sc = screen_find(e->window)) != NULL) {
|
2019-02-28 16:26:12 -07:00
|
|
|
if (e->data.l[0] >= 0 &&
|
|
|
|
e->data.l[0] < Conf.ngroups)
|
|
|
|
group_only(sc, e->data.l[0]);
|
2015-06-30 08:01:43 -06:00
|
|
|
}
|
2014-01-28 06:40:40 -07:00
|
|
|
}
|
2007-04-27 11:58:48 -06:00
|
|
|
}
|
|
|
|
|
2009-05-17 18:14:19 -06:00
|
|
|
static void
|
|
|
|
xev_handle_randr(XEvent *ee)
|
2008-09-29 17:16:46 -06:00
|
|
|
{
|
2019-03-10 16:53:11 -06:00
|
|
|
XRRScreenChangeNotifyEvent *e = (XRRScreenChangeNotifyEvent *)ee;
|
2008-09-29 17:16:46 -06:00
|
|
|
struct screen_ctx *sc;
|
2009-05-01 11:50:20 -06:00
|
|
|
|
2019-03-10 16:53:11 -06:00
|
|
|
LOG_DEBUG3("size: %d/%d", e->width, e->height);
|
2018-02-02 06:50:22 -07:00
|
|
|
|
2019-03-10 16:53:11 -06:00
|
|
|
if ((sc = screen_find(e->root)) == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
XRRUpdateConfiguration(ee);
|
|
|
|
screen_update_geometry(sc);
|
|
|
|
screen_assert_clients_within(sc);
|
2008-09-29 17:16:46 -06:00
|
|
|
}
|
|
|
|
|
2009-11-28 10:52:12 -07:00
|
|
|
/*
|
2008-07-22 15:01:54 -06:00
|
|
|
* Called when the keymap has changed.
|
|
|
|
* Ungrab all keys, reload keymap and then regrab
|
|
|
|
*/
|
2009-05-17 18:14:19 -06:00
|
|
|
static void
|
|
|
|
xev_handle_mappingnotify(XEvent *ee)
|
2008-07-22 15:01:54 -06:00
|
|
|
{
|
|
|
|
XMappingEvent *e = &ee->xmapping;
|
2013-05-23 10:52:39 -06:00
|
|
|
struct screen_ctx *sc;
|
2008-07-22 15:01:54 -06:00
|
|
|
|
2018-02-04 15:56:26 -07:00
|
|
|
LOG_DEBUG3("window: 0x%lx", e->window);
|
2018-02-02 06:50:22 -07:00
|
|
|
|
2008-07-22 15:01:54 -06:00
|
|
|
XRefreshKeyboardMapping(e);
|
2013-05-23 10:52:39 -06:00
|
|
|
if (e->request == MappingKeyboard) {
|
|
|
|
TAILQ_FOREACH(sc, &Screenq, entry)
|
|
|
|
conf_grab_kbd(sc->rootwin);
|
|
|
|
}
|
2007-04-27 11:58:48 -06:00
|
|
|
}
|
|
|
|
|
2009-03-28 10:38:54 -06:00
|
|
|
static void
|
2009-05-17 18:14:19 -06:00
|
|
|
xev_handle_expose(XEvent *ee)
|
2007-04-27 11:58:48 -06:00
|
|
|
{
|
2008-07-11 08:21:28 -06:00
|
|
|
XExposeEvent *e = &ee->xexpose;
|
|
|
|
struct client_ctx *cc;
|
2007-04-27 11:58:48 -06:00
|
|
|
|
2018-02-04 15:56:26 -07:00
|
|
|
LOG_DEBUG3("window: 0x%lx", e->window);
|
2018-02-02 06:50:22 -07:00
|
|
|
|
2009-01-16 08:24:14 -07:00
|
|
|
if ((cc = client_find(e->window)) != NULL && e->count == 0)
|
2007-04-27 11:58:48 -06:00
|
|
|
client_draw_border(cc);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2014-01-22 14:48:27 -07:00
|
|
|
xev_process(void)
|
2007-04-27 11:58:48 -06:00
|
|
|
{
|
2008-07-11 08:21:28 -06:00
|
|
|
XEvent e;
|
2007-04-27 11:58:48 -06:00
|
|
|
|
2017-12-27 10:04:35 -07:00
|
|
|
while (XPending(X_Dpy)) {
|
|
|
|
XNextEvent(X_Dpy, &e);
|
2019-03-08 06:17:26 -07:00
|
|
|
if ((e.type - Conf.xrandr_event_base) == RRScreenChangeNotify)
|
2017-12-27 10:04:35 -07:00
|
|
|
xev_handle_randr(&e);
|
2019-03-08 06:17:26 -07:00
|
|
|
else if ((e.type < LASTEvent) && (xev_handlers[e.type] != NULL))
|
2017-12-27 10:04:35 -07:00
|
|
|
(*xev_handlers[e.type])(&e);
|
|
|
|
}
|
2007-04-27 11:58:48 -06:00
|
|
|
}
|