231 lines
5.4 KiB
C
231 lines
5.4 KiB
C
/*
|
|
* Copyright (C) 2000-2005 Carsten Haitzler, Geoff Harrison and various contributors
|
|
* Copyright (C) 2004-2005 Kim Woelders
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
* of this software and associated documentation files (the "Software"), to
|
|
* deal in the Software without restriction, including without limitation the
|
|
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
* sell copies of the Software, and to permit persons to whom the Software is
|
|
* furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in
|
|
* all copies of the Software, its documentation and marketing & publicity
|
|
* materials, and acknowledgment shall be given in the documentation, materials
|
|
* and software packages that this Software was used.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
* THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
*/
|
|
#include "E.h"
|
|
|
|
static Window w1 = 0, w2 = 0, w3 = 0, w4 = 0;
|
|
|
|
static void
|
|
EdgeTimeout(int val, void *data __UNUSED__)
|
|
{
|
|
int ax, ay, aw, ah, dx, dy, dax, day;
|
|
EWin *ewin;
|
|
|
|
if (MenusActive())
|
|
return;
|
|
if (!Conf.edge_flip_resistance)
|
|
return;
|
|
|
|
/* Quit if pointer has left screen */
|
|
if (!PointerAt(NULL, NULL))
|
|
return;
|
|
|
|
/* Quit if in fullscreen window */
|
|
ewin = GetEwinPointerInClient();
|
|
if (ewin && ewin->st.fullscreen)
|
|
return;
|
|
|
|
DeskGetCurrentArea(&ax, &ay);
|
|
GetAreaSize(&aw, &ah);
|
|
dx = 0;
|
|
dy = 0;
|
|
dax = 0;
|
|
day = 0;
|
|
switch (val)
|
|
{
|
|
case 0:
|
|
if (ax == 0 && !Conf.desks.areas_wraparound)
|
|
return;
|
|
dx = VRoot.w - 2;
|
|
dax = -1;
|
|
break;
|
|
case 1:
|
|
if (ax == (aw - 1) && !Conf.desks.areas_wraparound)
|
|
return;
|
|
dx = -(VRoot.w - 2);
|
|
dax = 1;
|
|
break;
|
|
case 2:
|
|
if (ay == 0 && !Conf.desks.areas_wraparound)
|
|
return;
|
|
dy = VRoot.h - 2;
|
|
day = -1;
|
|
break;
|
|
case 3:
|
|
if (ay == (ah - 1) && !Conf.desks.areas_wraparound)
|
|
return;
|
|
dy = -(VRoot.h - 2);
|
|
day = 1;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
if (aw == 1)
|
|
dx = 0;
|
|
if (ah == 1)
|
|
dy = 0;
|
|
Mode.px = Mode.x;
|
|
Mode.py = Mode.y;
|
|
Mode.x += dx;
|
|
Mode.y += dy;
|
|
XWarpPointer(disp, None, VRoot.win, 0, 0, 0, 0, Mode.x, Mode.y);
|
|
Mode.flipp = 1;
|
|
MoveCurrentAreaBy(dax, day);
|
|
Mode.flipp = 0;
|
|
Mode.px = Mode.x;
|
|
Mode.py = Mode.y;
|
|
}
|
|
|
|
static void
|
|
EdgeEvent(int dir)
|
|
{
|
|
static int lastdir = -1;
|
|
|
|
#if 0
|
|
Eprintf("EdgeEvent %d -> %d\n", lastdir, dir);
|
|
#endif
|
|
if (lastdir == dir || !Conf.edge_flip_resistance)
|
|
return;
|
|
|
|
RemoveTimerEvent("EDGE_TIMEOUT");
|
|
if (dir >= 0)
|
|
{
|
|
DoIn("EDGE_TIMEOUT",
|
|
((double)Conf.edge_flip_resistance) / 100.0, EdgeTimeout,
|
|
dir, NULL);
|
|
}
|
|
lastdir = dir;
|
|
}
|
|
|
|
static void
|
|
EdgeHandleEvents(XEvent * ev, void *prm)
|
|
{
|
|
static Time last_time;
|
|
int dir;
|
|
unsigned long dt;
|
|
|
|
dir = (int)prm;
|
|
|
|
switch (ev->type)
|
|
{
|
|
case EnterNotify:
|
|
/* Avoid excessive flipping */
|
|
dt = ev->xcrossing.time - last_time;
|
|
if (dt < 500)
|
|
return;
|
|
last_time = ev->xcrossing.time;
|
|
EdgeEvent(dir);
|
|
break;
|
|
|
|
case LeaveNotify:
|
|
EdgeEvent(-1);
|
|
break;
|
|
|
|
#if 0
|
|
case MotionNotify:
|
|
if (Mode.mode != MODE_MOVE_PENDING && Mode.mode != MODE_MOVE)
|
|
break;
|
|
|
|
EdgeEvent(dir);
|
|
break;
|
|
#endif
|
|
}
|
|
}
|
|
|
|
void
|
|
EdgeCheckMotion(int x, int y)
|
|
{
|
|
int dir;
|
|
|
|
if (x == 0)
|
|
dir = 0;
|
|
else if (x == VRoot.w - 1)
|
|
dir = 1;
|
|
else if (y == 0)
|
|
dir = 2;
|
|
else if (y == VRoot.h - 1)
|
|
dir = 3;
|
|
else
|
|
dir = -1;
|
|
EdgeEvent(dir);
|
|
}
|
|
|
|
void
|
|
EdgeWindowsShow(void)
|
|
{
|
|
int ax, ay, cx, cy;
|
|
|
|
if (Conf.edge_flip_resistance <= 0)
|
|
{
|
|
EdgeWindowsHide();
|
|
return;
|
|
}
|
|
|
|
if (!w1)
|
|
{
|
|
w1 = ECreateEventWindow(VRoot.win, 0, 0, 1, VRoot.h);
|
|
w2 = ECreateEventWindow(VRoot.win, VRoot.w - 1, 0, 1, VRoot.h);
|
|
w3 = ECreateEventWindow(VRoot.win, 0, 0, VRoot.w, 1);
|
|
w4 = ECreateEventWindow(VRoot.win, 0, VRoot.h - 1, VRoot.w, 1);
|
|
ESelectInput(w1, EnterWindowMask | LeaveWindowMask);
|
|
ESelectInput(w2, EnterWindowMask | LeaveWindowMask);
|
|
ESelectInput(w3, EnterWindowMask | LeaveWindowMask);
|
|
ESelectInput(w4, EnterWindowMask | LeaveWindowMask);
|
|
EventCallbackRegister(w1, 0, EdgeHandleEvents, (void *)0);
|
|
EventCallbackRegister(w2, 0, EdgeHandleEvents, (void *)1);
|
|
EventCallbackRegister(w3, 0, EdgeHandleEvents, (void *)2);
|
|
EventCallbackRegister(w4, 0, EdgeHandleEvents, (void *)3);
|
|
}
|
|
DeskGetCurrentArea(&cx, &cy);
|
|
GetAreaSize(&ax, &ay);
|
|
|
|
if (cx == 0 && !Conf.desks.areas_wraparound)
|
|
EUnmapWindow(w1);
|
|
else
|
|
EMapRaised(w1);
|
|
if (cx == (ax - 1) && !Conf.desks.areas_wraparound)
|
|
EUnmapWindow(w2);
|
|
else
|
|
EMapRaised(w2);
|
|
if (cy == 0 && !Conf.desks.areas_wraparound)
|
|
EUnmapWindow(w3);
|
|
else
|
|
EMapRaised(w3);
|
|
if (cy == (ay - 1) && !Conf.desks.areas_wraparound)
|
|
EUnmapWindow(w4);
|
|
else
|
|
EMapRaised(w4);
|
|
}
|
|
|
|
void
|
|
EdgeWindowsHide(void)
|
|
{
|
|
if (w1)
|
|
{
|
|
EUnmapWindow(w1);
|
|
EUnmapWindow(w2);
|
|
EUnmapWindow(w3);
|
|
EUnmapWindow(w4);
|
|
}
|
|
}
|