Unified · Split
| @@ -455,7 +455,7 @@ struct Tk · 454 unmodified lines | ||
| 455 | 455 | Tk* master; /* Pack owner */ |
| 456 | 456 | Tk* slave; /* Packer slaves */ |
| 457 | 457 | Tk* next; /* Link for packer slaves */ |
| 458 | − Tk* parent; /* Window is sub of canvas or text */ | |
| 458 | + Tk* parent; /* Window is sub of this canvas or text */ | |
| 459 | 459 | Tk* depth; /* Window depth when mapped */ |
| 460 | 460 | void (*geom)(Tk*, int, int, int, int); /* Geometry change notify function */ |
| 461 | 461 | void (*destroyed)(Tk*); /* Destroy notify function */ |
| @@ -473,7 +473,7 @@ struct Tk · 11 unmodified lines | ||
| 473 | 473 | Rectangle dirty; /* dirty rectangle, relative to widget */ |
| 474 | 474 | TkGrid* grid; /* children are packed in a grid */ |
| 475 | 475 | |
| 476 | −// char obj[TKSTRUCTALIGN]; | |
| 476 | + /* followed by widget-dependent data */ | |
| 477 | 477 | }; |
| 478 | 478 | |
| 479 | 479 | struct TkWin |
| @@ -514,6 +514,7 @@ struct TkMethod · 34 unmodified lines | ||
| 514 | 514 | void (*see)(Tk*, Rectangle*, Point*); |
| 515 | 515 | Tk* (*inwindow)(Tk*, Point*); |
| 516 | 516 | void (*varchanged)(Tk*, char*, char*); |
| 517 | + void (*forgetsub)(Tk*, Tk*); | |
| 517 | 518 | int ncmd; |
| 518 | 519 | }; |
| 519 | 520 | |
| @@ -733,6 +734,7 @@ extern TkEnv* tkdefaultenv(TkTop*); · 213 unmodified lines | ||
| 733 | 734 | extern void tkputenv(TkEnv*); |
| 734 | 735 | extern TkEnv* tkdupenv(TkEnv**); |
| 735 | 736 | extern Tk* tknewobj(TkTop*, int, int); |
| 737 | +extern Tk* tkfindsub(Tk*); | |
| 736 | 738 | extern void tkfreebind(TkAction*); |
| 737 | 739 | extern void tkfreename(TkName*); |
| 738 | 740 | extern void tkfreeobj(Tk*); |
| @@ -750,7 +752,6 @@ extern int tksubdeliver(Tk*, TkAction*, int, void*, int); · 11 unmodified lines | ||
| 750 | 752 | extern void tkcancel(TkAction**, int); |
| 751 | 753 | extern char* tkaction(TkAction**, int, int, char*, int); |
| 752 | 754 | extern char* tkitem(char*, char*); |
| 753 | −extern int tkismapped(Tk*); | |
| 754 | 755 | extern Point tkposn(Tk*); |
| 755 | 756 | extern Point tkscrn2local(Tk*, Point); |
| 756 | 757 | extern int tkvisiblerect(Tk *tk, Rectangle *rr); |
| @@ -818,6 +819,11 @@ extern int tkextnnewctxt(TkCtxt*); · 61 unmodified lines | ||
| 818 | 819 | extern void tkextnfreectxt(TkCtxt*); |
| 819 | 820 | extern char* tkextnparseseq(char*, char*, int*); |
| 820 | 821 | |
| 822 | +/* Debugging */ | |
| 823 | +extern void tkdump(Tk*); | |
| 824 | +extern void tktopdump(Tk*); | |
| 825 | +extern void tkcvsdump(Tk*); | |
| 826 | + | |
| 821 | 827 | /* External to libtk */ |
| 822 | 828 | extern void tkenterleave(TkTop*); |
| 823 | 829 | extern void tksetwinimage(Tk*, Image*); |
| @@ -1 +1 @@ | ||
| 1 | −#define VERSION "Fourth Edition (20100819)" | |
| 1 | +#define VERSION "Fourth Edition (20100821)" | |
| @@ -2214,5 +2214,7 @@ TkMethod canvasmethod = { · 2213 unmodified lines | ||
| 2214 | 2214 | tkcvsrelpos, |
| 2215 | 2215 | tkcvsevent, |
| 2216 | 2216 | tkcvsseesub, |
| 2217 | − tkcvsinwindow | |
| 2217 | + tkcvsinwindow, | |
| 2218 | + nil, | |
| 2219 | + tkcvsforgetsub, | |
| 2218 | 2220 | }; |
| @@ -236,3 +236,5 @@ extern char* tkcvsimgcoord(TkCitem*, char*, int, int); · 235 unmodified lines | ||
| 236 | 236 | extern char* tkcvsimgcget(TkCitem*, char*, char**); |
| 237 | 237 | extern char* tkcvsimgconf(Tk*, TkCitem*, char*); |
| 238 | 238 | |
| 239 | +extern TkCitem* tkcvsfindwin(Tk*); | |
| 240 | +extern void tkcvsforgetsub(Tk*, Tk*); | |
| @@ -426,18 +426,22 @@ tkcvsdeliver(Tk *tk, TkCitem *i, int event, void *data) · 425 unmodified lines | ||
| 426 | 426 | if(!(event & TkKey) && (event & TkEmouse)) { |
| 427 | 427 | ftk = tkcvsmouseinsub(w, *(TkMouse*)data); |
| 428 | 428 | if(ftk != w->focus) { |
| 429 | +{TkCitem *si; if(w->focus != nil && (si = tkcvsfindwin(w->focus)) != i)print("focus botch 4: i=%p si=%p\n", i, si);} | |
| 429 | 430 | tkdeliver(w->focus, TkLeave, data); |
| 431 | +{TkCitem *si; if(ftk != nil && (si = tkcvsfindwin(ftk)) != i)print("focus botch: i=%p si=%p\n", i, si);} | |
| 432 | +if(0)print("focus %p %q %p %q\n", w->sub, tkname(w->sub), ftk, tkname(ftk)); | |
| 430 | 433 | tkdeliver(ftk, TkEnter, data); |
| 431 | 434 | w->focus = ftk; |
| 432 | 435 | } |
| 436 | +else{TkCitem *si; if(ftk != nil && (si = tkcvsfindwin(ftk)) != i)print("focus botch 2: i=%p si=%p\n", i, si);} | |
| 433 | 437 | if(ftk != nil) |
| 434 | 438 | dest = tkdeliver(ftk, event, data); |
| 435 | − } | |
| 436 | − else { | |
| 437 | − if (event & TkLeave) { | |
| 439 | + } else { | |
| 440 | +{TkCitem *si; if(w->focus != nil && (si = tkcvsfindwin(w->focus)) != i)print("focus botch 3: i=%p si=%p\n", i, si);} | |
| 441 | + if(event & TkLeave) { | |
| 438 | 442 | tkdeliver(w->focus, TkLeave, data); |
| 439 | 443 | w->focus = nil; |
| 440 | − } else if (event & TkEnter) { | |
| 444 | + } else if(event & TkEnter) { | |
| 441 | 445 | ftk = tkcvsmouseinsub(w, *(TkMouse*)data); |
| 442 | 446 | tkdeliver(ftk, TkEnter, data); |
| 443 | 447 | w->focus = ftk; |
| @@ -504,3 +508,39 @@ tkcvsevent(Tk *tk, int event, void *data) · 60 unmodified lines | ||
| 504 | 508 | tksubdeliver(tk, tk->binds, event, data, 0); |
| 505 | 509 | return dest; |
| 506 | 510 | } |
| 511 | + | |
| 512 | +/* | |
| 513 | + * debugging | |
| 514 | + */ | |
| 515 | +void | |
| 516 | +tkcvsdump(Tk *tk) | |
| 517 | +{ | |
| 518 | + TkCanvas *c; | |
| 519 | + TkCitem *it; | |
| 520 | + TkCwind *w; | |
| 521 | + char v1[Tkminitem], v2[Tkminitem]; | |
| 522 | + int i; | |
| 523 | + | |
| 524 | + if(tk == nil) | |
| 525 | + return; | |
| 526 | + c = TKobj(TkCanvas, tk); | |
| 527 | + tkfprint(v1, c->width); | |
| 528 | + tkfprint(v2, c->height); | |
| 529 | + print("%q configure -width %s -height %s", tkname(tk), v1, v2); | |
| 530 | + print(" # focus %#p mouse %#p grab %#p\n", c->focus, c->mouse, c->grab); | |
| 531 | + for(it = c->head; it != nil; it = it->next){ | |
| 532 | + print("%q create %q", tkname(tk), tkcimethod[it->type].name); | |
| 533 | + for(i = 0; i < it->p.npoint; i++){ | |
| 534 | + tkfprint(v1, it->p.parampt[i].x); | |
| 535 | + tkfprint(v2, it->p.parampt[i].y); | |
| 536 | + print(" %s %s", v1, v2); | |
| 537 | + } | |
| 538 | + if(it->type == TkCVwindow){ | |
| 539 | + w = TKobj(TkCwind, it); | |
| 540 | + if(w->sub != nil) | |
| 541 | + print(" -window %q", tkname(w->sub)); | |
| 542 | + print(" # item %#p id %d sub %#p focus [%#p %q]\n", it, it->id, w->sub, w->focus, tkname(w->focus)); | |
| 543 | + }else | |
| 544 | + print("# item %#p id %d\n", it, it->id); | |
| 545 | + } | |
| 546 | +} | |
| @@ -64,6 +64,47 @@ tkcvswindsize(TkCitem *i) · 63 unmodified lines | ||
| 64 | 64 | i->p.bb.max.y = p.y + s->act.height + bw; |
| 65 | 65 | } |
| 66 | 66 | |
| 67 | +TkCitem* | |
| 68 | +tkcvsfindwin(Tk *tk) | |
| 69 | +{ | |
| 70 | + Tk *parent, *sub; | |
| 71 | + TkCitem *i; | |
| 72 | + TkCanvas *c; | |
| 73 | + TkCwind *w; | |
| 74 | + | |
| 75 | + sub = tkfindsub(tk); | |
| 76 | + if(sub == nil) | |
| 77 | + return nil; | |
| 78 | + parent = sub->parent; | |
| 79 | + if(parent->type != TKcanvas) | |
| 80 | + return nil; /* inconsistent */ | |
| 81 | + c = TKobj(TkCanvas, parent); | |
| 82 | + for(i = c->head; i != nil; i = i->next) { | |
| 83 | + if(i->type == TkCVwindow) { | |
| 84 | + w = TKobj(TkCwind, i); | |
| 85 | + if(w->sub == sub) | |
| 86 | + return i; | |
| 87 | + } | |
| 88 | + } | |
| 89 | + return nil; | |
| 90 | +} | |
| 91 | + | |
| 92 | +void | |
| 93 | +tkcvsforgetsub(Tk *sub, Tk *tk) | |
| 94 | +{ | |
| 95 | + TkCwind *w; | |
| 96 | + TkCitem *i; | |
| 97 | + | |
| 98 | + i = tkcvsfindwin(sub); | |
| 99 | + if(i == nil) | |
| 100 | + return; | |
| 101 | + w = TKobj(TkCwind, i); | |
| 102 | + if(w->focus == tk) { | |
| 103 | +if(0)print("tkcsvsforget sub %p %q focus %p %q\n", sub, tkname(sub), tk, tkname(tk)); | |
| 104 | + w->focus = nil; | |
| 105 | + } | |
| 106 | +} | |
| 107 | + | |
| 67 | 108 | static int |
| 68 | 109 | tkcvschkwfocus(TkCwind *w, Tk *tk) |
| 69 | 110 | { |
| @@ -97,6 +138,7 @@ tkcvswindgeom(Tk *sub, int x, int y, int w, int h) · 27 unmodified lines | ||
| 97 | 138 | } |
| 98 | 139 | |
| 99 | 140 | if(win->focus != nil) { |
| 141 | +if(0)print("check focus %p %q %p %q\n", win, tkname(win->focus), sub, tkname(sub)); | |
| 100 | 142 | if(tkcvschkwfocus(win, sub) == 0) |
| 101 | 143 | win->focus = nil; |
| 102 | 144 | } |
| @@ -128,6 +170,15 @@ tkcvssubdestry(Tk *sub) · 25 unmodified lines | ||
| 128 | 170 | if(tk == nil) |
| 129 | 171 | return; |
| 130 | 172 | |
| 173 | +if(0)print("tkcvssubdestry %p %q\n", sub, tkname(sub)); | |
| 174 | + i = tkcvsfindwin(sub); | |
| 175 | + if(i != nil){ | |
| 176 | + win = TKobj(TkCwind, i); | |
| 177 | + if(win->sub != sub){ | |
| 178 | + print("inconsistent tkcvssubdestry %p %q\n", sub, tkname(sub)); | |
| 179 | + } | |
| 180 | + } | |
| 181 | + | |
| 131 | 182 | c = TKobj(TkCanvas, tk); |
| 132 | 183 | for(i = c->head; i; i = i->next) { |
| 133 | 184 | if(i->type == TkCVwindow) { |
| @@ -810,7 +810,7 @@ tkdestroy(TkTop *t, char *arg, char **ret) · 809 unmodified lines | ||
| 810 | 810 | if(strcmp(buf, n) == 0) { |
| 811 | 811 | tk->flag |= Tkdestroy; |
| 812 | 812 | found = 1; |
| 813 | − } else if(isroot || (strncmp(buf, n, len) == 0 &&n[len] == '.')) | |
| 813 | + } else if(isroot || (strncmp(buf, n, len) == 0 && n[len] == '.')) | |
| 814 | 814 | tk->flag |= Tkdestroy; |
| 815 | 815 | } |
| 816 | 816 | } |
| @@ -827,13 +827,14 @@ tkdestroy(TkTop *t, char *arg, char **ret) · 10 unmodified lines | ||
| 827 | 827 | continue; |
| 828 | 828 | if(tk->flag & Tkwindow) { |
| 829 | 829 | tkunmap(tk); |
| 830 | − if((tk->name != nil) | |
| 831 | − && (strcmp(tk->name->name, ".") == 0)) | |
| 830 | + if(tk->name != nil && | |
| 831 | + strcmp(tk->name->name, ".") == 0) | |
| 832 | 832 | tk->flag &= ~Tkdestroy; |
| 833 | 833 | else |
| 834 | 834 | tkdeliver(tk, TkDestroy, nil); |
| 835 | 835 | } else |
| 836 | 836 | tkdeliver(tk, TkDestroy, nil); |
| 837 | +if(0)print("tkdestroy %q\n", tkname(tk)); | |
| 837 | 838 | if(tk->destroyed != nil) |
| 838 | 839 | tk->destroyed(tk); |
| 839 | 840 | tkpackqit(tk->master); |
| @@ -179,17 +179,6 @@ x2index(Tk *tk, int x, int *xc) · 178 unmodified lines | ||
| 179 | 179 | return t1; |
| 180 | 180 | } |
| 181 | 181 | |
| 182 | −static int | |
| 183 | −x2index0(Tk *tk, int x, int *xc) | |
| 184 | −{ | |
| 185 | − int xx, z; | |
| 186 | − z = x2index(tk, x, &xx); | |
| 187 | − print("x2index(%d)-> (%d, %d)\n", x, z, xx); | |
| 188 | − if (xc) | |
| 189 | − *xc = xx; | |
| 190 | − return z; | |
| 191 | −} | |
| 192 | − | |
| 193 | 182 | /* |
| 194 | 183 | * recalculate derived values |
| 195 | 184 | */ |
| @@ -143,7 +143,7 @@ ensuregridsize(TkGrid *grid, Point dim) · 142 unmodified lines | ||
| 143 | 143 | for(i = olddim.y; i < dim.y; i++){ |
| 144 | 144 | cells[i] = malloc(sizeof(TkGridcell)*dim.x); |
| 145 | 145 | if(cells[i] == nil){ |
| 146 | − for(i--; i >= olddim.y; i--) | |
| 146 | + while(--i >= olddim.y) | |
| 147 | 147 | free(cells[i]); |
| 148 | 148 | return TkNomem; |
| 149 | 149 | } |
| @@ -721,32 +721,6 @@ gridfindloc(TkGridbeam *beam, int blen, int f) · 571 unmodified lines | ||
| 721 | 721 | return -1; |
| 722 | 722 | } |
| 723 | 723 | |
| 724 | −/* | |
| 725 | − * optimised way to find a given slave, but somewhat more fragile | |
| 726 | − * as it assumes the slave has already been placed on the grid. | |
| 727 | − * not tested. | |
| 728 | − */ | |
| 729 | −static int | |
| 730 | −findslave(TkGrid *grid, Tk *tk, Point *pt) | |
| 731 | −{ | |
| 732 | − Point loc, dim, p; | |
| 733 | − TkGridcell **cells; | |
| 734 | − dim = grid->dim; | |
| 735 | − cells = grid->cells; | |
| 736 | − loc.x = gridfindloc(grid->cols, grid->dim.x, tk->act.x); | |
| 737 | − if(loc.x == -1) | |
| 738 | − loc.x = 0; | |
| 739 | − loc.y = gridfindloc(grid->rows, grid->dim.y, tk->act.y); | |
| 740 | − if(loc.y == -1) | |
| 741 | − loc.y = 0; | |
| 742 | − for(p.y = loc.y; p.y < dim.y; p.y++) | |
| 743 | − for(p.x = loc.x; p.x < dim.x; p.x++) | |
| 744 | − if(cells[p.y][p.x].tk == tk){ | |
| 745 | − *pt = p; | |
| 746 | − return 1; | |
| 747 | − } | |
| 748 | − return 0; | |
| 749 | −} | |
| 750 | 724 | static char* |
| 751 | 725 | tkgridcellinfo(TkTop *t, char *arg, char **val, char *buf, char *ebuf) |
| 752 | 726 | { |
| @@ -80,7 +80,14 @@ TkOption opts[] = · 79 unmodified lines | ||
| 80 | 80 | void |
| 81 | 81 | tkdelpack(Tk *t) |
| 82 | 82 | { |
| 83 | − Tk *f, **l; | |
| 83 | + Tk *f, **l, *sub, *p; | |
| 84 | + | |
| 85 | + sub = tkfindsub(t); | |
| 86 | + if(sub != nil) { | |
| 87 | + p = sub->parent; | |
| 88 | + if(tkmethod[p->type]->forgetsub != nil) | |
| 89 | + tkmethod[p->type]->forgetsub(sub, t); | |
| 90 | + } | |
| 84 | 91 | |
| 85 | 92 | if(t->master == nil) |
| 86 | 93 | return; |
| @@ -571,6 +571,7 @@ tktbbox(Tk *tk, TkTindex *ix) · 570 unmodified lines | ||
| 571 | 571 | /* r in V space */ |
| 572 | 572 | r.min = subpt(l->orig, tkt->deltatv); |
| 573 | 573 | r.min.y += l->ascent; |
| 574 | + r.max = r.min; | |
| 574 | 575 | |
| 575 | 576 | /* tabs dependon tags of first non-mark on display line */ |
| 576 | 577 | for(i = l->items; i->kind == TkTmark; ) |
| @@ -117,6 +117,8 @@ static TkEbind tktbinds[] = { · 116 unmodified lines | ||
| 117 | 117 | {TkKey|Pgdown, "%W yview scroll 0.75 page"}, |
| 118 | 118 | {TkKey|CNTL('w'), "%W tkTextDelIns -w"}, |
| 119 | 119 | {TkKey|Pgup, "%W yview scroll -0.75 page"}, |
| 120 | + {TkButton4P, "%W yview scroll -0.2 page"}, | |
| 121 | + {TkButton5P, "%W yview scroll 0.2 page"}, | |
| 120 | 122 | {TkFocusout, "%W tkTextCursor delete"}, |
| 121 | 123 | {TkKey|APP|'\t', ""}, |
| 122 | 124 | {TkKey|BackTab, ""}, |
| @@ -112,16 +112,16 @@ struct TkText · 111 unmodified lines | ||
| 112 | 112 | struct TkTwind |
| 113 | 113 | { |
| 114 | 114 | Tk* sub; /* Subwindow of canvas */ |
| 115 | + Tk* focus; /* Current Mouse focus */ | |
| 116 | + int width; /* current internal width */ | |
| 117 | + int height; /* current internal height */ | |
| 118 | + int owned; /* true if window is destroyed on item deletion */ | |
| 115 | 119 | int align; /* how to align within line */ |
| 116 | 120 | char* create; /* creation script */ |
| 117 | 121 | int padx; /* extra space on each side */ |
| 118 | 122 | int pady; /* extra space on top and bot */ |
| 119 | − int width; /* current internal width */ | |
| 120 | − int height; /* current internal height */ | |
| 121 | 123 | int ascent; /* distance from top of widget to baseline */ |
| 122 | 124 | int stretch; /* true if need to stretch height */ |
| 123 | − int owned; /* true if window is destroyed on item deletion */ | |
| 124 | − Tk* focus; /* Current Mouse focus */ | |
| 125 | 125 | }; |
| 126 | 126 | |
| 127 | 127 | struct TkTitem |
| @@ -383,9 +383,9 @@ tktwinnames(Tk *tk, char *arg, char **val) · 382 unmodified lines | ||
| 383 | 383 | tktstartind(tkt, &ix); |
| 384 | 384 | fmt = "%s"; |
| 385 | 385 | do { |
| 386 | − if(ix.item->kind == TkTwin | |
| 387 | − && ix.item->iwin->sub != nil | |
| 388 | − && (ix.item->iwin->sub->name != nil)) { | |
| 386 | + if(ix.item->kind == TkTwin && | |
| 387 | + ix.item->iwin->sub != nil && | |
| 388 | + ix.item->iwin->sub->name != nil) { | |
| 389 | 389 | e = tkvalue(val, fmt, ix.item->iwin->sub->name->name); |
| 390 | 390 | if(e != nil) |
| 391 | 391 | return e; |
| @@ -56,7 +56,8 @@ static struct Cmd cmdmain[] = · 55 unmodified lines | ||
| 56 | 56 | |
| 57 | 57 | char* tkfont; |
| 58 | 58 | |
| 59 | −/* auto-repeating support | |
| 59 | +/* | |
| 60 | + * auto-repeating support | |
| 60 | 61 | * should perhaps be one rptproc per TkCtxt |
| 61 | 62 | * This is not done for the moment as there isn't |
| 62 | 63 | * a mechanism for terminating the rptproc |
| @@ -1016,17 +1017,25 @@ tkdrawstring(Tk *tk, Image *i, Point o, char *text, int ul, Image *col, int j) · 953 unmodified lines | ||
| 1016 | 1017 | char* |
| 1017 | 1018 | tkname(Tk *tk) |
| 1018 | 1019 | { |
| 1019 | − return tk ? (tk->name ? tk->name->name : "(noname)") : "(nil)"; | |
| 1020 | + if(tk == nil) | |
| 1021 | + return "(nil)"; | |
| 1022 | + if(tk->name == nil) | |
| 1023 | + return "(noname)"; | |
| 1024 | + return tk->name->name; | |
| 1020 | 1025 | } |
| 1021 | 1026 | |
| 1022 | 1027 | Tk* |
| 1023 | 1028 | tkdeliver(Tk *tk, int event, void *data) |
| 1024 | 1029 | { |
| 1025 | 1030 | Tk *dest; |
| 1031 | + | |
| 1032 | + if(tk != nil && ((ulong)tk->type >= TKwidgets || (ulong)tk->name < 4096 && tk->name != nil)){ | |
| 1033 | + print("invalid Tk: type %d name %p\n", tk->type, tk->name); | |
| 1034 | + abort(); | |
| 1035 | + } | |
| 1026 | 1036 | //print("tkdeliver %v to %s\n", event, tkname(tk)); |
| 1027 | 1037 | if(tk == nil || ((tk->flag&Tkdestroy) && event != TkDestroy)) |
| 1028 | 1038 | return tk; |
| 1029 | − | |
| 1030 | 1039 | if(event&(TkFocusin|TkFocusout) && (tk->flag&Tktakefocus)) |
| 1031 | 1040 | tk->dirty = tkrect(tk, 1); |
| 1032 | 1041 | |
| @@ -1058,6 +1067,7 @@ tksubdeliver(Tk *tk, TkAction *binds, int event, void *data, int extn) · 25 unmodified lines | ||
| 1058 | 1067 | TkAction *a; |
| 1059 | 1068 | int delivered, genkey, delivered2, iskey; |
| 1060 | 1069 | //int (*debug)(char *fmt, ...); |
| 1070 | + | |
| 1061 | 1071 | if (!extn) |
| 1062 | 1072 | return tkextndeliver(tk, binds, event, data); |
| 1063 | 1073 | |
| @@ -1201,20 +1211,18 @@ tkitem(char *buf, char *a) · 137 unmodified lines | ||
| 1201 | 1211 | return a; |
| 1202 | 1212 | } |
| 1203 | 1213 | |
| 1204 | −int | |
| 1205 | −tkismapped(Tk *tk) | |
| 1214 | +/* | |
| 1215 | + * if tk is a subwindow or a descendent, return the subwindow; | |
| 1216 | + * return nil otherwise | |
| 1217 | + */ | |
| 1218 | +Tk* | |
| 1219 | +tkfindsub(Tk *tk) | |
| 1206 | 1220 | { |
| 1207 | − while(tk->master) | |
| 1208 | − tk = tk->master; | |
| 1209 | − | |
| 1210 | − /* We need subwindows of text & canvas to appear mapped always | |
| 1211 | − * so that the geom function update are seen by the parent | |
| 1212 | − * widget | |
| 1213 | − */ | |
| 1214 | − if((tk->flag & Tkwindow) == 0) | |
| 1215 | − return 1; | |
| 1216 | − | |
| 1217 | − return tk->flag & Tkmapped; | |
| 1221 | + for(; tk != nil; tk = tk->master){ | |
| 1222 | + if(tk->parent != nil) | |
| 1223 | + return tk; /* tk->parent is canvas or text */ | |
| 1224 | + } | |
| 1225 | + return nil; | |
| 1218 | 1226 | } |
| 1219 | 1227 | |
| 1220 | 1228 | /* |
| @@ -1233,21 +1241,19 @@ tkposn(Tk *tk) · 12 unmodified lines | ||
| 1233 | 1241 | if(tk->parent != nil) { |
| 1234 | 1242 | g = tkmethod[tk->parent->type]->relpos(tk); |
| 1235 | 1243 | f = tk->parent; |
| 1236 | − } | |
| 1237 | − else { | |
| 1244 | + } else { | |
| 1238 | 1245 | g.x = tk->act.x; |
| 1239 | 1246 | g.y = tk->act.y; |
| 1240 | 1247 | f = tk->master; |
| 1241 | 1248 | } |
| 1242 | − while(f) { | |
| 1249 | + while(f != nil) { | |
| 1243 | 1250 | g.x += f->borderwidth; |
| 1244 | 1251 | g.y += f->borderwidth; |
| 1245 | 1252 | last = f; |
| 1246 | 1253 | if(f->parent != nil) { |
| 1247 | 1254 | g = addpt(g, tkmethod[f->parent->type]->relpos(f)); |
| 1248 | 1255 | f = f->parent; |
| 1249 | − } | |
| 1250 | − else { | |
| 1256 | + } else { | |
| 1251 | 1257 | g.x += f->act.x; |
| 1252 | 1258 | g.y += f->act.y; |
| 1253 | 1259 | f = f->master; |
| @@ -2064,3 +2070,55 @@ tkblink(Tk *tk, void (*callback)(Tk*, int)) · 810 unmodified lines | ||
| 2064 | 2070 | else |
| 2065 | 2071 | rptwakeup(nil, blinkrpt); |
| 2066 | 2072 | } |
| 2073 | + | |
| 2074 | +/* | |
| 2075 | + * debugging | |
| 2076 | + */ | |
| 2077 | +void | |
| 2078 | +tkdump(Tk *tk) | |
| 2079 | +{ | |
| 2080 | + Tk *sl; | |
| 2081 | + | |
| 2082 | + if(tk == nil) | |
| 2083 | + return; | |
| 2084 | + if((uint)tk->type < TKwidgets) | |
| 2085 | + print("%s", tkmethod[tk->type]->name); | |
| 2086 | + else | |
| 2087 | + print("TYPE#%#ux", tk->type); | |
| 2088 | + if(tk->name == nil || (ulong)tk->name < 512) | |
| 2089 | + print(" NAME %p", tk->name); | |
| 2090 | + else | |
| 2091 | + print(" %s", tkname(tk)); | |
| 2092 | + print(" # tk %#p flag %#ux grid %#p", tk, tk->flag, tk->grid); | |
| 2093 | + if(tk->parent != nil) | |
| 2094 | + print(" parent [%#p %q]", tk->parent, tkname(tk->parent)); | |
| 2095 | + if(tk->master != nil) | |
| 2096 | + print(" master [%#p %q]", tk->master, tkname(tk->master)); | |
| 2097 | + if(tk->slave != nil){ | |
| 2098 | + print(" slaves"); | |
| 2099 | + for(sl = tk->slave; sl != nil; sl = sl->next) | |
| 2100 | + print(" [%#p %q]", sl, tkname(sl)); | |
| 2101 | + } | |
| 2102 | + print("\n"); | |
| 2103 | + if(tk->type != TKcanvas) | |
| 2104 | + return; | |
| 2105 | + tkcvsdump(tk); | |
| 2106 | +} | |
| 2107 | + | |
| 2108 | +void | |
| 2109 | +tktopdump(Tk *tk) | |
| 2110 | +{ | |
| 2111 | + TkTop *top; | |
| 2112 | + Tk *sub; | |
| 2113 | + | |
| 2114 | + if(tk == nil || tk->env == nil){ | |
| 2115 | + print("# %#p no top\n", tk); | |
| 2116 | + return; | |
| 2117 | + } | |
| 2118 | + top = tk->env->top; | |
| 2119 | + print("# env %#p top %#p\n", tk->env, top); | |
| 2120 | + if(top != nil){ | |
| 2121 | + for(sub = top->root; sub != nil; sub = sub->siblings) | |
| 2122 | + tkdump(sub); | |
| 2123 | + } | |
| 2124 | +} | |
| @@ -388,29 +388,6 @@ tkmap(Tk *tk) · 387 unmodified lines | ||
| 388 | 388 | //tkupdate(tk->env->top); |
| 389 | 389 | } |
| 390 | 390 | |
| 391 | −void | |
| 392 | −tkclrfocus(Tk *master) | |
| 393 | −{ | |
| 394 | − TkCtxt *c; | |
| 395 | − Tk *tk; | |
| 396 | − TkTop *top; | |
| 397 | − | |
| 398 | − if(master == nil) | |
| 399 | − return; | |
| 400 | − top = master->env->top; | |
| 401 | − c = top->ctxt; | |
| 402 | − | |
| 403 | − tk = c->mgrab; | |
| 404 | − if(tkischild(master, tk)) | |
| 405 | − tksetmgrab(top, nil); | |
| 406 | − | |
| 407 | − tk = c->entered; | |
| 408 | − if(tkischild(master, tk)){ | |
| 409 | − c->entered = nil; | |
| 410 | − tkdeliver(tk, TkLeave, nil); | |
| 411 | − } | |
| 412 | −} | |
| 413 | − | |
| 414 | 391 | void |
| 415 | 392 | tkunmap(Tk *tk) |
| 416 | 393 | { |