Implement window matches doing window ops.

SVN revision: 13360
This commit is contained in:
Kim Woelders 2005-02-13 22:54:17 +00:00
parent b56efff6ca
commit 272e363189
7 changed files with 356 additions and 139 deletions

View File

@ -2161,6 +2161,7 @@ int WindowMatchConfigLoad(FILE * fs);
void *WindowMatchEwin(EWin * ewin);
Border *WindowMatchEwinBorder(const EWin * ewin);
const char *WindowMatchEwinIcon(const EWin * ewin);
void WindowMatchEwinOps(EWin * ewin);
/* x.c */
Display *EDisplayOpen(const char *dstr);

View File

@ -21,6 +21,7 @@ e16_SOURCES = \
econfig.h \
ecore-e16.h \
emodule.h \
ewin-ops.h \
timestamp.h \
aclass.c \
actions.c \

View File

@ -21,9 +21,73 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "E.h"
#include "ecompmgr.h"
#include "ecompmgr.h" /* FIXME - Resize hack - to be removed */
#include "ewin-ops.h"
#include <sys/time.h>
static const WinOp winops[] = {
{"close", 2, 1, 0, EWIN_OP_CLOSE},
{"kill", 0, 1, 0, EWIN_OP_KILL},
{"iconify", 2, 1, 1, EWIN_OP_ICONIFY},
{"opacity", 2, 1, 1, EWIN_OP_OPACITY},
{"shadow", 0, 1, 1, EWIN_OP_SHADOW}, /* Place before "shade" */
{"shade", 2, 1, 1, EWIN_OP_SHADE},
{"stick", 2, 1, 1, EWIN_OP_STICK},
{"fixedpos", 0, 1, 1, EWIN_OP_FIXED_POS},
{"never_use_area", 0, 1, 1, EWIN_OP_NEVER_USE_AREA},
{"focusclick", 0, 1, 1, EWIN_OP_FOCUS_CLICK},
{"neverfocus", 0, 1, 1, EWIN_OP_FOCUS_NEVER},
{"title", 2, 1, 1, EWIN_OP_TITLE},
{"toggle_width", 0, 1, 0, EWIN_OP_MAX_WIDTH},
{"tw", 2, 1, 0, EWIN_OP_MAX_WIDTH},
{"toggle_height", 0, 1, 0, EWIN_OP_MAX_HEIGHT},
{"th", 0, 1, 0, EWIN_OP_MAX_HEIGHT},
{"toggle_size", 0, 1, 0, EWIN_OP_MAX_SIZE},
{"ts", 2, 1, 0, EWIN_OP_MAX_SIZE},
{"raise", 2, 1, 0, EWIN_OP_RAISE},
{"lower", 2, 1, 0, EWIN_OP_LOWER},
{"layer", 2, 1, 1, EWIN_OP_LAYER},
{"border", 2, 1, 0, EWIN_OP_BORDER},
{"desk", 2, 1, 1, EWIN_OP_DESK},
{"area", 2, 1, 1, EWIN_OP_AREA},
{"move", 2, 1, 1, EWIN_OP_MOVE},
{"resize", 0, 1, 1, EWIN_OP_SIZE},
{"sz", 2, 1, 1, EWIN_OP_SIZE},
{"move_relative", 0, 1, 0, EWIN_OP_MOVE_REL},
{"mr", 2, 1, 0, EWIN_OP_MOVE_REL},
{"resize_relative", 0, 1, 0, EWIN_OP_SIZE_REL},
{"sr", 2, 1, 0, EWIN_OP_SIZE_REL},
{"focus", 2, 1, 0, EWIN_OP_FOCUS},
{"fullscreen", 2, 1, 1, EWIN_OP_FULLSCREEN},
{"skiplists", 4, 1, 1, EWIN_OP_SKIP_LISTS},
{"zoom", 2, 1, 0, EWIN_OP_ZOOM},
{"snap", 0, 1, 0, EWIN_OP_SNAP},
{NULL, 0, 0, 0, EWIN_OP_INVALID} /* Terminator */
};
const WinOp *
EwinOpFind(const char *op)
{
const WinOp *wop;
wop = winops;
for (; wop->name; wop++)
{
if (wop->len)
{
if (!strncmp(op, wop->name, wop->len))
return wop;
}
else
{
if (!strcmp(op, wop->name))
return wop;
}
}
return NULL;
}
void
SlideEwinTo(EWin * ewin, int fx, int fy, int tx, int ty, int speed)
{

72
src/ewin-ops.h Normal file
View File

@ -0,0 +1,72 @@
/*
* Copyright (C) 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.
*/
#ifndef _EWIN_OPS_H_
#define _EWIN_OPS_H_
typedef enum
{
EWIN_OP_INVALID,
EWIN_OP_CLOSE,
EWIN_OP_KILL,
EWIN_OP_ICONIFY,
EWIN_OP_OPACITY,
EWIN_OP_SHADOW,
EWIN_OP_SHADE,
EWIN_OP_STICK,
EWIN_OP_FIXED_POS,
EWIN_OP_NEVER_USE_AREA,
EWIN_OP_FOCUS_CLICK,
EWIN_OP_FOCUS_NEVER,
EWIN_OP_TITLE,
EWIN_OP_MAX_WIDTH,
EWIN_OP_MAX_HEIGHT,
EWIN_OP_MAX_SIZE,
EWIN_OP_RAISE,
EWIN_OP_LOWER,
EWIN_OP_LAYER,
EWIN_OP_BORDER,
EWIN_OP_DESK,
EWIN_OP_AREA,
EWIN_OP_MOVE,
EWIN_OP_SIZE,
EWIN_OP_MOVE_REL,
EWIN_OP_SIZE_REL,
EWIN_OP_FOCUS,
EWIN_OP_FULLSCREEN,
EWIN_OP_SKIP_LISTS,
EWIN_OP_ZOOM,
EWIN_OP_SNAP,
} winop_e;
typedef struct
{
const char *name;
char len;
char ok_ipc;
char ok_match;
char op;
} WinOp;
const WinOp *EwinOpFind(const char *op);
#endif /* _EWIN_OPS_H_ */

View File

@ -518,9 +518,10 @@ Adopt(EWin * ewin, Window win)
#if 0 /* Do we want this? */
MatchEwinToSM(ewin);
#endif
MatchEwinToSnapInfo(ewin);
WindowMatchEwinOps(ewin); /* Window matches */
MatchEwinToSnapInfo(ewin); /* Saved settings */
if (Mode.wm.startup)
EHintsGetInfo(ewin);
EHintsGetInfo(ewin); /* E restart hints */
ICCCM_MatchSize(ewin);
EwinAdopt(ewin);
@ -599,7 +600,8 @@ AdoptInternal(Window win, Border * border, int type)
ewin->client.no_resize_h = ewin->client.no_resize_v = 1;
break;
}
MatchEwinToSnapInfo(ewin);
WindowMatchEwinOps(ewin); /* Window matches */
MatchEwinToSnapInfo(ewin); /* Saved settings */
ICCCM_MatchSize(ewin);
EwinAdopt(ewin);

119
src/ipc.c
View File

@ -22,6 +22,7 @@
*/
#include <ctype.h>
#include "E.h"
#include "ewin-ops.h"
#define SS(s) ((s) ? (s) : NoText)
static const char NoText[] = "-NONE-";
@ -374,113 +375,6 @@ doMoveConstrainedNoGroup(EWin * ewin, const char *params)
}
#endif
typedef enum
{
EWIN_OP_INVALID,
EWIN_OP_CLOSE,
EWIN_OP_KILL,
EWIN_OP_ICONIFY,
EWIN_OP_OPACITY,
EWIN_OP_SHADOW,
EWIN_OP_SHADE,
EWIN_OP_STICK,
EWIN_OP_FIXED_POS,
EWIN_OP_NEVER_USE_AREA,
EWIN_OP_FOCUS_CLICK,
EWIN_OP_FOCUS_NEVER,
EWIN_OP_TITLE,
EWIN_OP_MAX_WIDTH,
EWIN_OP_MAX_HEIGHT,
EWIN_OP_MAX_SIZE,
EWIN_OP_RAISE,
EWIN_OP_LOWER,
EWIN_OP_LAYER,
EWIN_OP_BORDER,
EWIN_OP_DESK,
EWIN_OP_AREA,
EWIN_OP_MOVE,
EWIN_OP_SIZE,
EWIN_OP_MOVE_REL,
EWIN_OP_SIZE_REL,
EWIN_OP_FOCUS,
EWIN_OP_FULLSCREEN,
EWIN_OP_SKIP_LISTS,
EWIN_OP_ZOOM,
EWIN_OP_SNAP,
} winop_e;
typedef struct
{
const char *name;
char len;
char ok_ipc;
char ok_match;
char op;
} WinOp;
static const WinOp winops[] = {
{"close", 2, 1, 1, EWIN_OP_CLOSE},
{"kill", 0, 1, 1, EWIN_OP_KILL},
{"iconify", 2, 1, 1, EWIN_OP_ICONIFY},
{"opacity", 2, 1, 1, EWIN_OP_OPACITY},
{"shadow", 0, 1, 1, EWIN_OP_SHADOW}, /* Place before "shade" */
{"shade", 2, 1, 1, EWIN_OP_SHADE},
{"stick", 2, 1, 1, EWIN_OP_STICK},
{"fixedpos", 0, 1, 1, EWIN_OP_FIXED_POS},
{"never_use_area", 0, 1, 1, EWIN_OP_NEVER_USE_AREA},
{"focusclick", 0, 1, 1, EWIN_OP_FOCUS_CLICK},
{"neverfocus", 0, 1, 1, EWIN_OP_FOCUS_NEVER},
{"title", 2, 1, 1, EWIN_OP_TITLE},
{"toggle_width", 0, 1, 1, EWIN_OP_MAX_WIDTH},
{"tw", 2, 1, 1, EWIN_OP_MAX_WIDTH},
{"toggle_height", 0, 1, 1, EWIN_OP_MAX_HEIGHT},
{"th", 0, 1, 1, EWIN_OP_MAX_HEIGHT},
{"toggle_size", 0, 1, 1, EWIN_OP_MAX_SIZE},
{"ts", 2, 1, 1, EWIN_OP_MAX_SIZE},
{"raise", 2, 1, 1, EWIN_OP_RAISE},
{"lower", 2, 1, 1, EWIN_OP_LOWER},
{"layer", 2, 1, 1, EWIN_OP_LAYER},
{"border", 2, 1, 1, EWIN_OP_BORDER},
{"desk", 2, 1, 1, EWIN_OP_DESK},
{"area", 2, 1, 1, EWIN_OP_AREA},
{"move", 2, 1, 1, EWIN_OP_MOVE},
{"resize", 0, 1, 1, EWIN_OP_SIZE},
{"sz", 2, 1, 1, EWIN_OP_SIZE},
{"move_relative", 0, 1, 1, EWIN_OP_MOVE_REL},
{"mr", 2, 1, 1, EWIN_OP_MOVE_REL},
{"resize_relative", 0, 1, 1, EWIN_OP_SIZE_REL},
{"sr", 2, 1, 1, EWIN_OP_SIZE_REL},
{"focus", 2, 1, 1, EWIN_OP_FOCUS},
{"fullscreen", 2, 1, 1, EWIN_OP_FULLSCREEN},
{"skiplists", 4, 1, 1, EWIN_OP_SKIP_LISTS},
{"zoom", 2, 1, 1, EWIN_OP_ZOOM},
{"snap", 0, 1, 1, EWIN_OP_SNAP},
{NULL, 0, 0, 0, EWIN_OP_INVALID} /* Terminator */
};
static const WinOp *
WinopFind(const char *op)
{
const WinOp *wop;
wop = winops;
for (; wop->name; wop++)
{
if (wop->len)
{
if (!strncmp(op, wop->name, wop->len))
break;
}
else
{
if (!strcmp(op, wop->name))
break;
}
}
return wop;
}
static void
IPC_WinOps(const char *params, Client * c __UNUSED__)
{
@ -521,14 +415,19 @@ IPC_WinOps(const char *params, Client * c __UNUSED__)
goto done;
}
wop = WinopFind(operation);
wop = EwinOpFind(operation);
if (!wop)
{
IpcPrintf("Error: unknown operation");
goto done;
}
switch (wop->op)
{
default:
case EWIN_OP_INVALID:
/* We should not get here */
IpcPrintf("Error: unknown operation");
break;
return;
case EWIN_OP_CLOSE:
EwinOpClose(ewin);

View File

@ -23,6 +23,9 @@
*/
#include "E.h"
#include "conf.h"
#include "ewin-ops.h"
static int WindowMatchEwinOpsParse(EWin * ewin, const char *ops);
struct _windowmatch
{
@ -298,19 +301,18 @@ WindowMatchConfigLoad(FILE * fs)
static WindowMatch *
WindowMatchDecode(const char *line)
{
char match[32], value[1024], op[32], args[1024];
char match[32], value[1024], op[32];
const char *args;
WindowMatch *wm = NULL;
int err, num, w1, w2, h1, h2;
match[0] = value[0] = op[0] = args[0] = '\0';
num = sscanf(line, "%32s %1024s %32s %1024s", match, value, op, args);
if (num < 4)
match[0] = value[0] = op[0] = '\0';
num = sscanf(line, "%32s %1024s %32s %n", match, value, op, &w1);
if (num < 3)
return NULL;
args = line + w1;
if (*args == '\0')
return NULL;
#if 0
Eprintf("-- %s\n", s);
Eprintf("++ %s %s %s %s\n", match, value, op, args);
#endif
err = 0;
@ -399,10 +401,17 @@ WindowMatchDecode(const char *line)
break;
case MATCH_OP_ICON:
/* FIXME - Check if exists */
wm->args = Estrdup(args);
break;
case MATCH_OP_WINOP:
if (WindowMatchEwinOpsParse(NULL, args))
{
Eprintf("WindowMatchDecode: Error (%s): %s\n", args, line);
err = 1;
goto done;
}
wm->args = Estrdup(args);
break;
}
@ -584,22 +593,8 @@ WindowMatchType(const EWin * ewin, int type)
{
wm = lst[i];
switch (type)
{
default:
continue;
case MATCH_OP_BORDER:
if (!wm->border)
continue;
break;
case MATCH_OP_ICON:
case MATCH_OP_WINOP:
if (!wm->args)
continue;
break;
}
if (wm->op != type)
continue;
if (!WindowMatchTest(ewin, lst[i]))
continue;
@ -644,6 +639,189 @@ WindowMatchEwinIcon(const EWin * ewin)
return NULL;
}
static int
GetBoolean(const char *value)
{
/* We set off if "0" or "off", otherwise on */
if (!value)
return 1;
else if (!strcmp(value, "0") || !strcmp(value, "off"))
return 0;
return 1;
}
#define WINOP_GET_BOOL(item, val) item = GetBoolean(val)
static void
WindowMatchEwinOpsAction(EWin * ewin, int op, const char *args)
{
int a, b;
/* NB! This must only be used when a new client is being adopted */
switch (op)
{
default:
/* We should not get here */
return;
case EWIN_OP_ICONIFY:
WINOP_GET_BOOL(ewin->client.start_iconified, args);
break;
case EWIN_OP_SHADE:
WINOP_GET_BOOL(ewin->shaded, args);
break;
case EWIN_OP_STICK:
WINOP_GET_BOOL(ewin->o.sticky, args);
break;
case EWIN_OP_FIXED_POS:
WINOP_GET_BOOL(ewin->fixedpos, args);
break;
case EWIN_OP_NEVER_USE_AREA:
WINOP_GET_BOOL(ewin->never_use_area, args);
break;
case EWIN_OP_FOCUS_CLICK:
WINOP_GET_BOOL(ewin->focusclick, args);
break;
case EWIN_OP_FOCUS_NEVER:
WINOP_GET_BOOL(ewin->neverfocus, args);
break;
case EWIN_OP_FULLSCREEN:
WINOP_GET_BOOL(ewin->st.fullscreen, args);
break;
case EWIN_OP_SKIP_LISTS:
WINOP_GET_BOOL(ewin->skipwinlist, args);
ewin->skipfocus = ewin->skiptask = ewin->skipwinlist;
break;
#if USE_COMPOSITE
case EWIN_OP_OPACITY:
EoSetOpacity(ewin, OpacityExt(atoi(args)));
break;
case EWIN_OP_SHADOW:
WINOP_GET_BOOL(ewin->o.shadow, args);
break;
#endif
case EWIN_OP_TITLE:
_EFREE(ewin->icccm.wm_name);
ewin->icccm.wm_name = Estrdup(args);
break;
case EWIN_OP_LAYER:
EoSetLayer(ewin, atoi(args));
break;
case EWIN_OP_DESK:
EoSetDesk(ewin, atoi(args));
break;
case EWIN_OP_AREA:
a = b = 0;
if (sscanf(args, "%u %u", &a, &b) < 2)
break;
MoveEwinToArea(ewin, a, b); /* FIXME - We should not move here */
break;
case EWIN_OP_MOVE:
a = ewin->client.x;
b = ewin->client.y;
if (sscanf(args, "%i %i", &a, &b) < 2)
break;
ewin->client.x = a;
ewin->client.y = b;
ewin->client.already_placed = 1;
break;
case EWIN_OP_SIZE:
a = ewin->client.w;
b = ewin->client.h;
if (sscanf(args, "%u %u", &a, &b) < 2)
break;
ewin->client.w = a;
ewin->client.h = b;
break;
}
}
static int
WindowMatchEwinOpsParse(EWin * ewin, const char *ops)
{
int err, len;
const WinOp *wop;
char *ops2, *s, *p, op[32];
if (!ops)
return -1;
/* Parse ':' separated operations list, e.g. "layer 3:desk 1: shade" */
p = ops2 = Estrdup(ops);
err = 0;
for (; p; p = s)
{
/* Break at ':' */
s = strchr(p, ':');
if (s)
*s++ = '\0';
len = 0;
sscanf(p, "%31s %n", op, &len);
if (len <= 0)
break;
p += len;
wop = EwinOpFind(op);
if (!wop || !wop->ok_match)
{
err = -1;
break;
}
/* If ewin is NULL, we are validating the configuration */
if (ewin)
WindowMatchEwinOpsAction(ewin, wop->op, p);
}
Efree(ops2);
return err;
}
void
WindowMatchEwinOps(EWin * ewin)
{
WindowMatch **lst, *wm;
int i, num;
lst = (WindowMatch **) ListItemType(&num, LIST_TYPE_WINDOWMATCH);
for (i = 0; i < num; i++)
{
wm = lst[i];
if (wm->op != MATCH_OP_WINOP)
continue;
if (!WindowMatchTest(ewin, lst[i]))
continue;
/* Match found - do the ops */
WindowMatchEwinOpsParse(ewin, wm->args);
}
if (lst)
Efree(lst);
}
/*
* Winmatch module
*/