more redraws to get rid of some redraw bugs
[k8sterm.git] / src / termswitch.c
blob2973099230035835082e610b003eb2af445f0ba5
1 ////////////////////////////////////////////////////////////////////////////////
2 static void fixWindowTitle (const K8Term *t) {
3 if (t != NULL) {
4 const char *title = (t != NULL) ? t->title : NULL;
5 //
6 if (title == NULL || !title[0]) {
7 title = opt_title;
8 if (title == NULL) title = "";
10 XStoreName(xw.dpy, xw.win, title);
11 XChangeProperty(xw.dpy, xw.win, XA_NETWM_NAME, XA_UTF8, 8, PropModeReplace, (const unsigned char *)title, strlen(title));
16 // find latest active terminal (but not current %-)
17 static int findTermToSwitch (void) {
18 int maxlat = -1, idx = -1;
20 for (int f = 0; f < term_count; ++f) {
21 if (curterm != term_array[f] && term_array[f]->lastActiveTime > maxlat) {
22 maxlat = term_array[f]->lastActiveTime;
23 idx = f;
26 if (idx < 0) {
27 if (termidx == 0) idx = 0; else idx = termidx+1;
28 if (idx > term_count) idx = term_count-1;
30 return idx;
34 static void fixFirstTab (void) {
35 if (termidx < firstVisibleTab) firstVisibleTab = termidx;
36 else if (termidx > firstVisibleTab+opt_tabcount-1) firstVisibleTab = termidx-opt_tabcount+1;
37 if (firstVisibleTab < 0) firstVisibleTab = 0;
38 updateTabBar = 1;
42 static void switchToTerm (int idx, int redraw) {
43 if (idx >= 0 && idx < term_count && term_array[idx] != NULL && term_array[idx] != curterm) {
44 K8TTimeMSec tt = mclock_ticks();
46 if (curterm != NULL) curterm->lastActiveTime = tt;
47 termidx = idx;
48 curterm = term_array[termidx];
49 curterm->curbhidden = 0;
50 curterm->lastBlinkTime = tt;
52 fixFirstTab();
54 xseturgency(0);
55 k8t_tmFullDirty(curterm);
56 fixWindowTitle(curterm);
57 updateTabBar = 1;
58 XSetWindowBackground(xw.dpy, xw.win, getColor(curterm->defbg));
59 xclearunused();
60 if (redraw) {
61 k8t_tmFullDirty(curterm);
62 k8t_drawTerm(curterm, 1);
63 if (!updateTabBar) updateTabBar = 1;
64 xdrawTabBar();
66 //FIXME: optimize memory allocations
67 if (curterm->sel.clip != NULL && curterm->sel.bx >= 0) {
68 if (lastSelStr != NULL) {
69 if (strlen(lastSelStr) >= strlen(curterm->sel.clip)) {
70 strcpy(lastSelStr, curterm->sel.clip);
71 } else {
72 free(lastSelStr);
73 lastSelStr = NULL;
76 if (lastSelStr == NULL) lastSelStr = strdup(curterm->sel.clip);
77 //fprintf(stderr, "newsel: [%s]\n", lastSelStr);
79 xfixsel();
80 //fprintf(stderr, "curterm #%d\n", termidx);
81 //fprintf(stderr, "needConv: %d\n", curterm->needConv);
86 static K8Term *k8t_termalloc (void) {
87 K8Term *t;
89 if (term_count >= term_array_size) {
90 int newsz = ((term_count==0) ? 1 : term_array_size+64);
91 K8Term **n = realloc(term_array, sizeof(K8Term *)*newsz);
93 if (n == NULL && term_count == 0) k8t_die("out of memory!");
94 term_array = n;
95 term_array_size = newsz;
97 if ((t = calloc(1, sizeof(K8Term))) == NULL) return NULL;
99 t->wrbufsize = K8T_WBUFSIZ;
100 t->deffg = defaultFG;
101 t->defbg = defaultBG;
102 t->dead = 1;
103 t->needConv = (needConversion ? 1 : 0);
104 t->belltype = (opt_audiblebell?K8T_BELL_AUDIO:0)|(opt_urgentbell?K8T_BELL_URGENT:0);
105 t->curblink = opt_cursorBlink;
106 t->curblinkinactive = opt_cursorBlinkInactive;
107 t->fastredraw = opt_fastredraw;
109 termSetCallbacks(t);
110 termSetDefaults(t);
112 term_array[term_count++] = t;
114 return t;
118 // newer delete last terminal!
119 static void termfree (int idx) {
120 if (idx >= 0 && idx < term_count && term_array[idx] != NULL) {
121 K8Term *t = term_array[idx];
122 K8TermData *td = K8T_DATA(t);
124 if (K8T_DATA(t)->pid != 0) {
125 kill(K8T_DATA(t)->pid, SIGKILL);
126 return;
129 if (t->cmdfd >= 0) {
130 close(t->cmdfd);
131 t->cmdfd = -1;
134 exitcode = K8T_DATA(t)->exitcode;
136 if (K8T_DATA(t)->waitkeypress) return;
138 if (idx == termidx) {
139 if (term_count > 1) {
140 t->dead = 1;
141 //switchToTerm((idx > 0) ? idx-1 : 1, 0);
142 switchToTerm(findTermToSwitch(), 0);
143 return;
145 curterm = NULL;
148 for (int y = 0; y < t->row; ++y) free(t->alt[y]);
149 for (int y = 0; y < t->linecount; ++y) free(t->line[y]);
150 free(t->dirty);
151 free(t->alt);
152 free(t->line);
154 if (td->execcmd != NULL) free(td->execcmd);
155 // condense array
156 if (termidx > idx) --termidx; // it's not current, and current is at the right
157 for (int f = idx+1; f < term_count; ++f) term_array[f-1] = term_array[f];
158 --term_count;
160 //if (td->picalloced) XFreePixmap(xw.dpy, td->picbuf);
161 free(td);
162 free(t);
167 static void termcleanup (void) {
168 int f = 0, needredraw = 0;
170 while (f < term_count) {
171 if (term_array[f]->dead) {
172 termfree(f);
173 needredraw = 1;
174 } else {
175 ++f;
179 if (needredraw) {
180 updateTabBar = 1;
181 k8t_drawTerm(curterm, 1);