clear selections in all tabs when selection ownership is lost
[k8sterm.git] / src / termswitch.c
blob3fcfd9a24cf62d1ecd37fcf267945b222c954c7d
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) { k8t_drawTerm(curterm, 1); xdrawTabBar(); }
61 //FIXME: optimize memory allocations
62 if (curterm->sel.clip != NULL && curterm->sel.bx >= 0) {
63 if (lastSelStr != NULL) free(lastSelStr);
64 lastSelStr = strdup(curterm->sel.clip);
65 //fprintf(stderr, "newsel: [%s]\n", lastSelStr);
67 xfixsel();
68 //fprintf(stderr, "curterm #%d\n", termidx);
69 //fprintf(stderr, "needConv: %d\n", curterm->needConv);
74 static K8Term *k8t_termalloc (void) {
75 K8Term *t;
77 if (term_count >= term_array_size) {
78 int newsz = ((term_count==0) ? 1 : term_array_size+64);
79 K8Term **n = realloc(term_array, sizeof(K8Term *)*newsz);
81 if (n == NULL && term_count == 0) k8t_die("out of memory!");
82 term_array = n;
83 term_array_size = newsz;
85 if ((t = calloc(1, sizeof(K8Term))) == NULL) return NULL;
87 t->wrbufsize = K8T_WBUFSIZ;
88 t->deffg = defaultFG;
89 t->defbg = defaultBG;
90 t->dead = 1;
91 t->needConv = (needConversion ? 1 : 0);
92 t->belltype = (opt_audiblebell?K8T_BELL_AUDIO:0)|(opt_urgentbell?K8T_BELL_URGENT:0);
93 t->curblink = opt_cursorBlink;
94 t->curblinkinactive = opt_cursorBlinkInactive;
95 t->fastredraw = opt_fastredraw;
97 termSetCallbacks(t);
98 termSetDefaults(t);
100 term_array[term_count++] = t;
102 return t;
106 // newer delete last terminal!
107 static void termfree (int idx) {
108 if (idx >= 0 && idx < term_count && term_array[idx] != NULL) {
109 K8Term *t = term_array[idx];
110 K8TermData *td = K8T_DATA(t);
112 if (K8T_DATA(t)->pid != 0) {
113 kill(K8T_DATA(t)->pid, SIGKILL);
114 return;
117 if (t->cmdfd >= 0) {
118 close(t->cmdfd);
119 t->cmdfd = -1;
122 exitcode = K8T_DATA(t)->exitcode;
124 if (K8T_DATA(t)->waitkeypress) return;
126 if (idx == termidx) {
127 if (term_count > 1) {
128 t->dead = 1;
129 //switchToTerm((idx > 0) ? idx-1 : 1, 0);
130 switchToTerm(findTermToSwitch(), 0);
131 return;
133 curterm = NULL;
136 for (int y = 0; y < t->row; ++y) free(t->alt[y]);
137 for (int y = 0; y < t->linecount; ++y) free(t->line[y]);
138 free(t->dirty);
139 free(t->alt);
140 free(t->line);
142 if (td->execcmd != NULL) free(td->execcmd);
143 // condense array
144 if (termidx > idx) --termidx; // it's not current, and current is at the right
145 for (int f = idx+1; f < term_count; ++f) term_array[f-1] = term_array[f];
146 --term_count;
148 //if (td->picalloced) XFreePixmap(xw.dpy, td->picbuf);
149 free(td);
150 free(t);
155 static void termcleanup (void) {
156 int f = 0, needredraw = 0;
158 while (f < term_count) {
159 if (term_array[f]->dead) {
160 termfree(f);
161 needredraw = 1;
162 } else {
163 ++f;
167 if (needredraw) {
168 updateTabBar = 1;
169 k8t_drawTerm(curterm, 1);