X-Git-Url: https://git.danieliu.xyz/?a=blobdiff_plain;f=st.c;h=5d5ac301b4b7bfe4a73fcc6a2fafea66bb0fe2df;hb=3a50a4fd931ed58454b680c9fc5c1bc2278e67f3;hp=79746297e62f71f0061aefc06428d7df0a33a20d;hpb=8c3757986a41ff8fa95b175be40f67d67d7e27b1;p=st.git diff --git a/st.c b/st.c index 7974629..5d5ac30 100644 --- a/st.c +++ b/st.c @@ -107,6 +107,8 @@ typedef struct { Colormap cmap; Window win; Pixmap buf; + XIM xim; + XIC xic; int scr; int w; /* window width */ int h; /* window height */ @@ -114,7 +116,8 @@ typedef struct { int bufh; /* pixmap height */ int ch; /* char height */ int cw; /* char width */ - int hasfocus; + int focus; + int vis; /* is visible */ } XWindow; typedef struct { @@ -187,6 +190,8 @@ static void xloadcols(void); static void xseturgency(int); static void expose(XEvent *); +static void visibility(XEvent *); +static void unmap(XEvent *); static char* kmap(KeySym); static void kpress(XEvent *); static void resize(XEvent *); @@ -198,8 +203,10 @@ static void bmotion(XEvent *); static void (*handler[LASTEvent])(XEvent *) = { [KeyPress] = kpress, - [Expose] = expose, [ConfigureNotify] = resize, + [VisibilityNotify] = visibility, + [UnmapNotify] = unmap, + [Expose] = expose, [FocusIn] = focus, [FocusOut] = focus, [MotionNotify] = bmotion, @@ -236,8 +243,9 @@ static inline int selected(int x, int y) { } static void getbuttoninfo(XEvent *e, int *b, int *x, int *y) { - if(b) *b = e->xbutton.state, - *b=*b==4096?5:*b==2048?4:*b==1024?3:*b==512?2:*b==256?1:-1; + if(b) + *b = e->xbutton.button; + *x = e->xbutton.x/xw.cw; *y = e->xbutton.y/xw.ch; sel.b.x = sel.by < sel.ey ? sel.bx : sel.ex; @@ -1038,7 +1046,7 @@ tputc(char c) { tnewline(); break; case '\a': - if(!xw.hasfocus) + if(!xw.focus) xseturgency(1); break; case '\033': @@ -1211,9 +1219,9 @@ xinit(void) { attrs.background_pixel = dc.col[DefaultBG]; attrs.border_pixel = dc.col[DefaultBG]; attrs.bit_gravity = NorthWestGravity; - attrs.event_mask = ExposureMask | KeyPressMask - | StructureNotifyMask | FocusChangeMask | PointerMotionMask - | ButtonPressMask | ButtonReleaseMask; + attrs.event_mask = FocusChangeMask | KeyPressMask + | ExposureMask | VisibilityChangeMask | StructureNotifyMask + | PointerMotionMask | ButtonPressMask | ButtonReleaseMask; attrs.colormap = xw.cmap; xw.win = XCreateWindow(xw.dis, XRootWindow(xw.dis, xw.scr), 0, 0, @@ -1223,6 +1231,13 @@ xinit(void) { | CWColormap, &attrs); xw.buf = XCreatePixmap(xw.dis, xw.win, xw.bufw, xw.bufh, XDefaultDepth(xw.dis, xw.scr)); + + + /* input methods */ + xw.xim = XOpenIM(xw.dis, NULL, NULL, NULL); + xw.xic = XCreateIC(xw.xim, XNInputStyle, XIMPreeditNothing + | XIMStatusNothing, XNClientWindow, xw.win, + XNFocusWindow, xw.win, NULL); /* gc */ dc.gc = XCreateGC(xw.dis, xw.win, 0, NULL); @@ -1281,7 +1296,7 @@ xdrawcursor(void) { xclear(oldx, oldy, oldx, oldy); /* draw the new one */ - if(!(term.c.state & CURSOR_HIDE) && xw.hasfocus) { + if(!(term.c.state & CURSOR_HIDE) && xw.focus) { xdraws(&g.c, g, term.c.x, term.c.y, 1); oldx = term.c.x, oldy = term.c.y; } @@ -1321,8 +1336,10 @@ draw(int redraw_all) { Glyph base, new; char buf[DRAW_BUF_SIZ]; - XSetForeground(xw.dis, dc.gc, dc.col[DefaultBG]); - XFillRectangle(xw.dis, xw.buf, dc.gc, 0, 0, xw.bufw, xw.bufh); + if(!xw.vis) + return; + + xclear(0, 0, term.col-1, term.row-1); for(y = 0; y < term.row; y++) { base = term.line[y][0]; i = ox = 0; @@ -1358,6 +1375,19 @@ expose(XEvent *ev) { draw(SCREEN_REDRAW); } +void +visibility(XEvent *ev) { + XVisibilityEvent *e = &ev->xvisibility; + /* XXX if this goes from 0 to 1, need a full redraw for next Expose, + * not just a buf copy */ + xw.vis = e->state != VisibilityFullyObscured; +} + +void +unmap(XEvent *ev) { + xw.vis = 0; +} + void xseturgency(int add) { XWMHints *h = XGetWMHints(xw.dis, xw.win); @@ -1368,7 +1398,7 @@ xseturgency(int add) { void focus(XEvent *ev) { - if((xw.hasfocus = ev->type == FocusIn)) + if((xw.focus = ev->type == FocusIn)) xseturgency(0); draw(SCREEN_UPDATE); } @@ -1391,10 +1421,11 @@ kpress(XEvent *ev) { int len; int meta; int shift; + Status status; meta = e->state & Mod1Mask; shift = e->state & ShiftMask; - len = XLookupString(e, buf, sizeof(buf), &ksym, NULL); + len = XmbLookupString(xw.xic, e, buf, sizeof(buf), &ksym, &status); if((customkey = kmap(ksym))) ttywrite(customkey, strlen(customkey)); @@ -1464,6 +1495,8 @@ run(void) { } while(XPending(xw.dis)) { XNextEvent(xw.dis, &ev); + if (XFilterEvent(&ev, xw.win)) + continue; if(handler[ev.type]) (handler[ev.type])(&ev); }