commit 1e4b2bb0614442c66039425f464f339dfea31392
parent ef672bf5fec47dcc997f924ef9cabb930d5b068a
Author: Anselm R. Garbe <garbeam@wmii.de>
Date: Fri, 26 May 2006 14:16:19 +0200
removed crappy blitz_strtorect, added move/size commands for client ctl, cleaned up liblitz/geometry somewhat
Diffstat:
8 files changed, 173 insertions(+), 274 deletions(-)
diff --git a/TODO.wmii-4 b/TODO.wmii-4
@@ -15,10 +15,6 @@
- make /foo/ -> bar+! -alike rules working
- /def/ncol defines num of columns which should be created by default if possible.
- wmiimenu -t <title> flag (add an additional line if -t is supplied)
-- remove the geom syntax as it is now (with the +- stuff, and only
- allowing explicit coordinates, instead additionally resize
- +/-<w> +/-<h> and move +/-<x> +/-<y> actions are needed in the
- associated ctl devices of clients.
- remove internal labels, now tagging seems easy and straightforward that they
THINK: We'll need CreateTag, DestroyTag, UnfocusTag, FocusTag and the
event loop in wmiirc must be before TAGGING can be externalized again
diff --git a/cmd/wm/client.c b/cmd/wm/client.c
@@ -604,9 +604,94 @@ newcol_client(Client *c, char *arg)
flush_masked_events(EnterWindowMask);
}
+static int
+parse_int_arg(int *i, const char *ival)
+{
+ int imult = 0, inum;
+ const char *errstr;
+
+ if(*ival == '-')
+ imult = -1;
+ else if(*ival == '+')
+ imult = 1;
+
+ inum = cext_strtonum(ival, -32765, 32765, &errstr);
+ if(errstr)
+ return -1;
+
+ if(inum < 0)
+ inum *= -1;
+
+ if(imult < 0)
+ *i -= inum;
+ else if(imult > 0)
+ *i += inum;
+ else
+ *i = inum;
+ return 0;
+}
+
+/* Parses "[+|-]<int> [+|-]<int>" and applies to the given vals */
+static int
+parse_mvsize_arg(int *i1, int *i2, const char *val)
+{
+ char buf[64], *p;
+ int i;
+
+ cext_strlcpy(buf, val, sizeof(buf));
+ p = strchr(buf, ' ');
+ if(!p)
+ return -1;
+ *p = 0;
+ p++;
+ i = *i1;
+ if(parse_int_arg(&i, buf) == -1)
+ return -1;
+ *i1 = i;
+ i = *i2;
+ if(parse_int_arg(&i, buf) == -1)
+ return -1;
+ *i2 = i;
+ return 0;
+}
+
void
move_client(Client *c, char *arg)
{
+ Frame *f = c->frame.data[c->sel];
+ XRectangle new = f->rect;
+ int x = new.x, y = new.y;
+
+ if(parse_mvsize_arg(&x, &y, arg) == -1)
+ return;
+ new.x = x;
+ new.y = y;
+ if(idx_of_area(f->area))
+ resize_column(f->client, &new, nil);
+ else
+ resize_client(f->client, &new, False);
+}
+
+void
+size_client(Client *c, char *arg)
+{
+ Frame *f = c->frame.data[c->sel];
+ XRectangle new = f->rect;
+ int w = new.width, h = new.height;
+
+ if(parse_mvsize_arg(&w, &h, arg) == -1)
+ return;
+ new.width = w;
+ new.height = h;
+ if(idx_of_area(f->area))
+ resize_column(f->client, &new, nil);
+ else
+ resize_client(f->client, &new, False);
+}
+
+void
+send_client(Client *c, char *arg)
+{
const char *errstr;
Frame *f = c->frame.data[c->sel];
Area *to, *a = f->area;
diff --git a/cmd/wm/event.c b/cmd/wm/event.c
@@ -104,7 +104,7 @@ handle_buttonpress(XEvent *e)
break;
case Button3:
{
- BlitzAlign align = blitz_align_of_rect(&c->rect, ev->x, ev->y);
+ BlitzAlign align = blitz_quadofcoord(&c->rect, ev->x, ev->y);
if(align != CENTER)
do_mouse_resize(c, align);
else
diff --git a/cmd/wm/fs.c b/cmd/wm/fs.c
@@ -71,7 +71,7 @@ enum { WMII_IOUNIT = 2048 };
*/
Qid root_qid;
-const char *err;
+static const char *errstr;
/* IXP stuff */
@@ -325,8 +325,8 @@ type_of_name(Qid wqid[IXP_MAX_WELEM], unsigned short qsel, char *name)
return FsDview;
if(!strncmp(name, "sel", 4))
goto dyndir;
- i = (unsigned short) cext_strtonum(name, 0, 0xffff, &err);
- if(err)
+ i = (unsigned short) cext_strtonum(name, 0, 0xffff, &errstr);
+ if(errstr)
return FsLast;
dyndir:
switch(dir_type) {
@@ -385,8 +385,8 @@ qid_of_name(Qid wqid[IXP_MAX_WELEM], unsigned short qsel, char *name)
new.path = pack_qpath(FsDarea, p->id, p->area.data[p->sel]->id, 0);
}
else {
- i = cext_strtonum(name, 0, 0xffff, &err);
- if(err || (i >= p->area.size))
+ i = cext_strtonum(name, 0, 0xffff, &errstr);
+ if(errstr || (i >= p->area.size))
return nil;
new.path = pack_qpath(FsDarea, p->id, p->area.data[i]->id, 0);
}
@@ -405,8 +405,8 @@ qid_of_name(Qid wqid[IXP_MAX_WELEM], unsigned short qsel, char *name)
new.path = pack_qpath(FsDclient, p->id, a->id, a->frame.data[a->sel]->id);
}
else {
- i = cext_strtonum(name, 0, 0xffff, &err);
- if(err || (i >= a->frame.size))
+ i = cext_strtonum(name, 0, 0xffff, &errstr);
+ if(errstr || (i >= a->frame.size))
return nil;
new.path = pack_qpath(FsDclient, p->id, a->id, a->frame.data[i]->id);
}
@@ -415,8 +415,8 @@ qid_of_name(Qid wqid[IXP_MAX_WELEM], unsigned short qsel, char *name)
case FsDGclient:
if(dir_type != FsDclients)
return nil;
- i = cext_strtonum(name, 0, 0xffff, &err);
- if(err || (i >= client.size))
+ i = cext_strtonum(name, 0, 0xffff, &errstr);
+ if(errstr || (i >= client.size))
return nil;
new.path = pack_qpath(FsDGclient, client.data[i]->id, 0, 0);
break;
@@ -506,6 +506,7 @@ stat_of_name(Stat *stat, char *name, Qid wqid[IXP_MAX_WELEM], unsigned short qse
unsigned char dir_type, type;
int i1 = 0, i2 = 0, i3 = 0;
char buf[256];
+ XRectangle fr;
Frame *f;
unpack_qpath(wqid, qsel, &dir_type, &i1, &i2, &i3);
@@ -539,16 +540,13 @@ stat_of_name(Stat *stat, char *name, Qid wqid[IXP_MAX_WELEM], unsigned short qse
return pack_stat(stat, wqid, qsel, name, strlen(buf), IXP_DMREAD | IXP_DMWRITE);
break;
case FsFgeom:
- if(dir_type == FsDclient) {
- f = view.data[i1]->area.data[i2]->frame.data[i3];
- snprintf(buf, sizeof(buf), "%d %d %d %d", f->rect.x, f->rect.y,
- f->rect.width, f->rect.height);
- }
- else {
- Client *c = client.data[i1];
- snprintf(buf, sizeof(buf), "%d %d %d %d", c->rect.x, c->rect.y,
- c->rect.width, c->rect.height);
- }
+ if(dir_type == FsDclient)
+ fr = view.data[i1]->area.data[i2]->frame.data[i3]->rect;
+ else if(client.data[i1]->frame.size)
+ fr = client.data[i1]->frame.data[client.data[i1]->sel]->rect;
+ else
+ fr = client.data[i1]->rect;
+ snprintf(buf, sizeof(buf), "%d %d %d %d", fr.x, fr.y, fr.width, fr.height);
return pack_stat(stat, wqid, qsel, name, strlen(buf), IXP_DMREAD | IXP_DMWRITE);
break;
case FsFclass:
@@ -812,7 +810,7 @@ xread(IXPConn *c, Fcall *fcall)
unsigned int i, len;
unsigned char dir_type, type, *p = fcall->data;
char buf[256];
- Frame *f;
+ XRectangle fr;
if(!m)
return Enofile;
@@ -1121,16 +1119,13 @@ xread(IXPConn *c, Fcall *fcall)
memcpy(p, buf, fcall->count);
break;
case FsFgeom:
- if(dir_type == FsDclient) {
- f = view.data[i1]->area.data[i2]->frame.data[i3];
- snprintf(buf, sizeof(buf), "%d %d %d %d", f->rect.x, f->rect.y,
- f->rect.width, f->rect.height);
- }
- else {
- Client *c = client.data[i1];
- snprintf(buf, sizeof(buf), "%d %d %d %d", c->rect.x, c->rect.y,
- c->rect.width, c->rect.height);
- }
+ if(dir_type == FsDclient)
+ fr = view.data[i1]->area.data[i2]->frame.data[i3]->rect;
+ else if(client.data[i1]->frame.size)
+ fr = client.data[i1]->frame.data[client.data[i1]->sel]->rect;
+ else
+ fr = client.data[i1]->rect;
+ snprintf(buf, sizeof(buf), "%d %d %d %d", fr.x, fr.y, fr.width, fr.height);
fcall->count = strlen(buf);
memcpy(p, buf, fcall->count);
break;
@@ -1315,9 +1310,13 @@ xwrite(IXPConn *c, Fcall *fcall)
return Enocommand;
break;
case FsDview:
- if(!strncmp(buf, "select ", 7))
+ if(!strncmp(buf, "select ", 7)) {
if(view.size)
- select_area(view.data[i1]->area.data[view.data[i1]->sel], &buf[7]);
+ select_area(view.data[i1]->area.data[view.data[i1]->sel],
+ &buf[7]);
+ }
+ else
+ return Enocommand;
break;
case FsDarea:
if(!strncmp(buf, "select ", 7)) {
@@ -1325,6 +1324,8 @@ xwrite(IXPConn *c, Fcall *fcall)
if(a->frame.size)
select_client(a->frame.data[a->sel]->client, &buf[7]);
}
+ else
+ return Enocommand;
break;
case FsDclient:
f = view.data[i1]->area.data[i2]->frame.data[i3];
@@ -1332,12 +1333,20 @@ xwrite(IXPConn *c, Fcall *fcall)
kill_client(f->client);
else if(!strncmp(buf, "newcol ", 7))
newcol_client(f->client, &buf[7]);
+ else if(!strncmp(buf, "send ", 5))
+ send_client(f->client, &buf[5]);
else if(!strncmp(buf, "move ", 5))
move_client(f->client, &buf[5]);
+ else if(!strncmp(buf, "size ", 5))
+ size_client(f->client, &buf[5]);
+ else
+ return Enocommand;
break;
case FsDGclient:
if(!strncmp(buf, "kill", 5))
kill_client(client.data[i1]);
+ else
+ return Enocommand;
break;
default:
break;
@@ -1348,8 +1357,8 @@ xwrite(IXPConn *c, Fcall *fcall)
return Ebadvalue;
memcpy(buf, fcall->data, fcall->count);
buf[fcall->count] = 0;
- i = cext_strtonum(buf, 0, 0xffff, &err);
- if(err)
+ i = cext_strtonum(buf, 0, 0xffff, &errstr);
+ if(errstr)
return Ebadvalue;
def.border = i;
resize_all_clients();
@@ -1370,22 +1379,6 @@ xwrite(IXPConn *c, Fcall *fcall)
update_views();
draw_client(cl);
break;
- case FsFgeom:
- if(fcall->count > sizeof(buf))
- return Ebadvalue;
- memcpy(buf, fcall->data, fcall->count);
- buf[fcall->count] = 0;
- if(dir_type == FsDclient) {
- XRectangle new;
- f = view.data[i1]->area.data[i2]->frame.data[i3];
- new = f->rect;
- blitz_strtorect(&rect, &new, buf);
- if(i2)
- resize_column(f->client, &new, nil);
- else
- resize_client(f->client, &new, False);
- }
- break;
case FsFdata:
len = fcall->count;
if(len >= sizeof(bar.data[i1]->data))
@@ -1449,6 +1442,26 @@ xwrite(IXPConn *c, Fcall *fcall)
memcpy(def.rules + fcall->offset, fcall->data, fcall->count);
def.rules[fcall->offset + fcall->count] = 0;
break;
+ case FsFgeom:
+ if(fcall->count > sizeof(buf))
+ return Ebadvalue;
+ memcpy(buf, fcall->data, fcall->count);
+ buf[fcall->count] = 0;
+ if(dir_type == FsDclient) {
+ XRectangle new;
+ f = view.data[i1]->area.data[i2]->frame.data[i3];
+ new = f->rect;
+ blitz_strtorect(&new, buf);
+ if(new.width == 0)
+ new.width = rect.width;
+ if(new.height == 0)
+ new.height = rect.height;
+ if(i2)
+ resize_column(f->client, &new, nil);
+ else
+ resize_client(f->client, &new, False);
+ }
+ break;
case FsFgrabmod:
{
unsigned long mod;
@@ -1471,8 +1484,8 @@ xwrite(IXPConn *c, Fcall *fcall)
return Ebadvalue;
memcpy(buf, fcall->data, fcall->count);
buf[fcall->count] = 0;
- i = cext_strtonum(buf, 0, rect.width - MIN_COLWIDTH, &err);
- if(err || (i && i < MIN_COLWIDTH))
+ i = cext_strtonum(buf, 0, rect.width - MIN_COLWIDTH, &errstr);
+ if(errstr || (i && i < MIN_COLWIDTH))
return Ebadvalue;
def.colw = i;
break;
diff --git a/cmd/wm/wm.h b/cmd/wm/wm.h
@@ -237,7 +237,9 @@ void focus_client(Client *c, Bool restack);
void focus(Client *c, Bool restack);
void resize_client(Client *c, XRectangle *r, Bool ignore_xcall);
void select_client(Client *c, char *arg);
+void send_client(Client *c, char *arg);
void move_client(Client *c, char *arg);
+void size_client(Client *c, char *arg);
void newcol_client(Client *c, char *arg);
void resize_all_clients();
Client *sel_client();
diff --git a/liblitz/blitz.h b/liblitz/blitz.h
@@ -65,9 +65,6 @@ void blitz_drawlabel(Display *dpy, BlitzDraw *d);
void blitz_drawborder(Display *dpy, BlitzDraw *d);
/* geometry.c */
-BlitzAlign blitz_align_of_rect(XRectangle *rect, int x, int y);
-int blitz_strtoalign(BlitzAlign *result, char *val);
-int blitz_strtorect(XRectangle *root, XRectangle *r, char *val);
+int blitz_strtorect(XRectangle *r, const char *val);
+BlitzAlign blitz_quadofcoord(XRectangle *rect, int x, int y);
Bool blitz_ispointinrect(int x, int y, XRectangle *r);
-int blitz_distance(XRectangle *origin, XRectangle *target);
-void blitz_getbasegeometry(unsigned int size, unsigned int *cols, unsigned int *rows);
diff --git a/liblitz/geometry.c b/liblitz/geometry.c
@@ -4,14 +4,14 @@
*/
#include <math.h>
-#include <string.h>
+#include <stdio.h>
#include <stdlib.h>
#include <cext.h>
#include "blitz.h"
BlitzAlign
-blitz_align_of_rect(XRectangle *rect, int x, int y)
+blitz_quadofcoord(XRectangle *rect, int x, int y)
{
int w = x <= rect->x + rect->width / 2;
int n = y <= rect->y + rect->height / 2;
@@ -34,217 +34,23 @@ blitz_align_of_rect(XRectangle *rect, int x, int y)
return CENTER;
}
-int blitz_strtoalign(BlitzAlign *result, char *val)
+Bool blitz_ispointinrect(int x, int y, XRectangle * r)
{
- /*
- * note, resize allows syntax like "east-20", this we cannot do
- * include zero termination in strncmp checking!
- */
-
- *result = CENTER;
- if (!strncmp(val, "west", 4))
- *result = WEST;
- else if (!strncmp(val, "nwest", 5))
- *result = NWEST;
- else if (!strncmp(val, "north", 5))
- *result = NORTH;
- else if (!strncmp(val, "neast", 5))
- *result = NEAST;
- else if (!strncmp(val, "east", 4))
- *result = EAST;
- else if (!strncmp(val, "seast", 5))
- *result = SEAST;
- else if (!strncmp(val, "south", 5))
- *result = SOUTH;
- else if (!strncmp(val, "swest", 5))
- *result = SWEST;
- else if (!strncmp(val, "center", 6))
- *result = CENTER;
- else
- return -1;
- return 0;
+ return (x >= r->x) && (x <= r->x + r->width)
+ && (y >= r->y) && (y <= r->y + r->height);
}
-/**
- * Basic Syntax: <x> <y> <width> <height>
- * Each component can be of following format:
- * <...> = [+|-]0..n|<alignment>[[+|-]0..n]
- */
-int blitz_strtorect(XRectangle *root, XRectangle *r, char *val)
-{
- const char *err;
- char buf[64];
- char *x, *y, *w, *h;
- char *p;
- int rx, ry, rw, rh, sx, sy, sw, sh;
+/* Syntax: <x> <y> <width> <height> */
+int blitz_strtorect(XRectangle *r, const char *val)
+{
+ XRectangle new;
if (!val)
return -1;
- rx = r->x;
- ry = r->y;
- rw = r->width;
- rh = r->height;
- sx = sy = sw = sh = 0;
- x = y = w = h = 0;
- cext_strlcpy(buf, val, sizeof(buf));
-
- x = strtok_r(buf, " ", &p);
- if (x) {
- y = strtok_r(0, " ", &p);
- if (y) {
- w = strtok_r(0, " ", &p);
- if (w) {
- h = strtok_r(0, "", &p);
- }
- }
- }
- if (x && (sx = (x[0] >= '0') && (x[0] <= '9')))
- rx = cext_strtonum(x, 0, 65535, &err);
- if (y && (sy = (y[0] >= '0') && (y[0] <= '9')))
- ry = cext_strtonum(y, 0, 65535, &err);
- if (w && (sw = (w[0] >= '0') && (w[0] <= '9')))
- rw = cext_strtonum(w, 0, 65535, &err);
- if (h && (sh = (h[0] >= '0') && (h[0] <= '9')))
- rh = cext_strtonum(h, 0, 65535, &err);
- if (!sx && !sw && x && w
- && x[0] != '-' && x[0] != '+' && w[0] != '-' && w[0] != '+') {
- BlitzAlign ax, aw;
- blitz_strtoalign(&ax, x);
- blitz_strtoalign(&aw, w);
- if ((ax == CENTER) && (aw == EAST)) {
- rx = root->x + root->width / 2;
- rw = root->width / 2;
- } else {
- rx = root->x;
- if (aw == CENTER) {
- rw = root->width / 2;
- } else {
- rw = root->width;
- }
- }
- } else if (!sx && x && x[0] != '-' && x[0] != '+') {
- BlitzAlign ax;
- blitz_strtoalign(&ax, x);
- if (ax == CENTER) {
- rx = root->x + (root->width / 2) - (rw / 2);
- } else if (ax == EAST) {
- rx = root->x + root->width - rw;
- } else {
- rx = root->x;
- }
- } else if (!sw && w && w[0] != '-' && w[0] != '+') {
- BlitzAlign aw;
- blitz_strtoalign(&aw, w);
- if (aw == CENTER) {
- rw = (root->width / 2) - rx;
- } else {
- rw = root->width - rx;
- }
- }
- if (!sy && !sh && y && h
- && y[0] != '-' && y[0] != '+' && h[0] != '-' && h[0] != '+') {
- BlitzAlign ay, ah;
- blitz_strtoalign(&ay, y);
- blitz_strtoalign(&ah, h);
- if ((ay == CENTER) && (ah == SOUTH)) {
- ry = root->y + root->height / 2;
- rh = root->height / 2;
- } else {
- ry = root->y;
- if (ah == CENTER) {
- rh = root->height / 2;
- } else {
- rh = root->height;
- }
- }
- } else if (!sy && y && y[0] != '-' && y[0] != '+') {
- BlitzAlign ay;
- blitz_strtoalign(&ay, y);
- if (ay == CENTER) {
- ry = root->y + (root->height / 2) - (rh / 2);
- } else if (ay == SOUTH) {
- ry = root->y + root->height - rh;
- } else {
- ry = root->y;
- }
- } else if (!sh && h && h[0] != '-' && h[0] != '+') {
- BlitzAlign ah;
- blitz_strtoalign(&ah, h);
- if (ah == CENTER) {
- rh = (root->height / 2) - ry;
- } else {
- rh = root->height - ry;
- }
- }
- /* now do final calculations */
- if (x) {
- p = strchr(x, '-');
- if (p)
- rx -= cext_strtonum(++p, 0, 65535, &err);
- p = strchr(x, '+');
- if (p)
- rx += cext_strtonum(++p, 0, 65535, &err);
- }
- if (y) {
- p = strchr(y, '-');
- if (p)
- ry -= cext_strtonum(++p, 0, 65535, &err);
- p = strchr(y, '+');
- if (p)
- ry += cext_strtonum(++p, 0, 65535, &err);
- }
- if (w) {
- p = strchr(w, '-');
- if (p)
- rw -= cext_strtonum(++p, 0, 65535, &err);
- p = strchr(w, '+');
- if (p)
- rw += cext_strtonum(++p, 0, 65535, &err);
- }
- if (h) {
- p = strchr(h, '-');
- if (p)
- rh -= cext_strtonum(++p, 0, 65535, &err);
- p = strchr(h, '+');
- if (p)
- rh += cext_strtonum(++p, 0, 65535, &err);
- }
+ if(sscanf(val, "%hd %hd %hu %hu", &new.x, &new.y, &new.width, &new.height) != 4)
+ return -1;
- if (rw < 1)
- rw = 10;
- if (rh < 1)
- rh = 10;
- r->x = rx;
- r->y = ry;
- r->width = rw;
- r->height = rh;
+ *r = new;
return 0;
}
-
-Bool blitz_ispointinrect(int x, int y, XRectangle * r)
-{
- return (x >= r->x) && (x <= r->x + r->width) && (y >= r->y) && (y <= r->y + r->height);
-}
-
-int blitz_distance(XRectangle * origin, XRectangle * target)
-{
- int ox = origin->x + origin->width / 2;
- int oy = origin->y + origin->height / 2;
- int tx = target->x + target->width / 2;
- int ty = target->y + target->height / 2;
-
- return (int) sqrt((double) (((ox - tx) * (ox - tx)) + ((oy - ty) * (oy - ty))));
-}
-
-void blitz_getbasegeometry(unsigned int size, unsigned int *cols, unsigned int *rows)
-{
- float sq, dummy;
-
- sq = sqrt(size);
- if (modff(sq, &dummy) < 0.5)
- *rows = floor(sq);
- else
- *rows = ceil(sq);
- *cols = ((*rows) * (*rows)) < (size) ? *rows + 1 : *rows;
-}
diff --git a/rc/wmiirc b/rc/wmiirc
@@ -133,7 +133,7 @@ do
$MODKEY-m)
xwrite /tag/sel/sel/mode max;;
$MODKEY-f)
- xwrite /tag/sel/0/sel/geom 0 0 east south;;
+ xwrite /tag/sel/0/sel/geom 0 0 0 0;;
$MODKEY-a)
PATH=$HOME/.wmii-4:CONFPREFIX/wmii-4:$PATH `proglist CONFPREFIX/wmii-4 $HOME/.wmii-4 | wmiimenu` &;;
$MODKEY-p)
@@ -145,15 +145,15 @@ do
$MODKEY-Return)
xterm &;;
$MODKEY-Shift-$LEFT)
- xwrite /tag/sel/sel/sel/ctl move prev;;
+ xwrite /tag/sel/sel/sel/ctl send prev;;
$MODKEY-Shift-$RIGHT)
- xwrite /tag/sel/sel/sel/ctl move next;;
+ xwrite /tag/sel/sel/sel/ctl send next;;
$MODKEY-Shift-$DOWN)
- xwrite /tag/sel/sel/sel/ctl move down;;
+ xwrite /tag/sel/sel/sel/ctl send down;;
$MODKEY-Shift-$UP)
- xwrite /tag/sel/sel/sel/ctl move up;;
+ xwrite /tag/sel/sel/sel/ctl send up;;
$MODKEY-Shift-space)
- xwrite /tag/sel/sel/sel/ctl move toggle;;
+ xwrite /tag/sel/sel/sel/ctl send toggle;;
$MODKEY-Shift-c)
xwrite /tag/sel/sel/sel/ctl kill;;
$MODKEY-Shift-t)