📄 tabbar.c
字号:
#ifdef XFT_SUPPORT if( ISSET_OPTION( r, Opt_xft ) ) r->tabBar.xftifg = r->xftColorsFocus[Color_Black];#endif } /* create the inactive tab background color */ if( r->h->rs[Rs_itabbg] && rxvt_parse_alloc_color( r, &color, r->h->rs[Rs_itabbg] ) ) r->tabBar.ibg = color.pixel; else { color.red = 0xa100; color.green = 0xa100; color.blue = 0xac00; if( rxvt_alloc_color( r, &color, "Inactive_Tab_Bg" ) ) r->tabBar.ibg = color.pixel; else r->tabBar.ibg = VTBG(r,0); } /* create the delimit color (average of 3*fg & bg) */ color.pixel = r->pixColorsFocus[Color_fg]; XQueryColor( r->Xdisplay, XCMAP, &color ); bgcolor.pixel = r->pixColorsFocus[Color_bg]; XQueryColor( r->Xdisplay, XCMAP, &bgcolor ); color.red = ( bgcolor.red + 3 * color.red ) / 4; color.green = ( bgcolor.green + 3 * color.green ) / 4; color.blue = ( bgcolor.blue + 3 * color.blue ) / 4; if( rxvt_alloc_color( r, &color, "Tab_Delimit" ) ) r->tabBar.delimit = color.pixel; else r->tabBar.delimit = VTFG(r,0); rxvt_dbgmsg ((DBG_DEBUG, DBG_TABBAR, "Delimit color: %hx, %hx, %hx (#%lx)\n", color.red, color.green, color.blue, r->tabBar.delimit)); } sx = 0; sy = 0;#ifdef HAVE_MENUBAR sy += rxvt_menubar_height (r);#endif if (ISSET_OPTION(r, Opt2_bottomTabbar)) sy += VT_HEIGHT(r); /* * create the window of the tabbar. Use ifg and ibg for the background of * the tabBar so that the active tab stands out better. */ r->tabBar.win = XCreateSimpleWindow( r->Xdisplay, r->TermWin.parent, sx, sy, TWIN_WIDTH(r), rxvt_tabbar_rheight( r ), 0, r->tabBar.ifg, r->tabBar.ibg ); assert(IS_WIN(r->tabBar.win));#ifdef XFT_SUPPORT if (ISSET_OPTION(r, Opt_xft)) { r->tabBar.xftwin = XftDrawCreate (r->Xdisplay, r->tabBar.win, XVISUAL, XCMAP); }#endif#ifdef DEBUG_X rxvt_set_win_title (r, r->tabBar.win, "tabbar");#endif#ifdef BACKGROUND_IMAGE r->tabBar.hasPixmap = False; /* initialize it to None */ if (#ifdef TRANSPARENT /* Transparency overrides background */ !( ISSET_OPTION(r, Opt_transparent) && ISSET_OPTION(r, Opt_transparent_tabbar) ) &&#endif r->h->rs[Rs_tabbarPixmap] ) { long w = 0, h = 0; Pixmap pmap; pmap = rxvt_load_pixmap (r, r->h->rs[Rs_tabbarPixmap], &w, &h); if (IS_PIXMAP(pmap)) { XSetWindowBackgroundPixmap (r->Xdisplay, r->tabBar.win, pmap); XFreePixmap( r->Xdisplay, pmap); r->tabBar.hasPixmap = True; } else r->tabBar.hasPixmap = False; }#endif#ifdef TRANSPARENT if ( ISSET_OPTION(r, Opt_transparent) && ISSET_OPTION(r, Opt_transparent_tabbar) ) XSetWindowBackgroundPixmap( r->Xdisplay, r->tabBar.win, ParentRelative);#endif /* create the GC for the tab window */ gcvalue.foreground = r->tabBar.fg; gcvalue.line_width = 0; gcvalue.line_style = LineSolid; gcvalue.cap_style = CapButt; gcvalue.join_style = JoinMiter; gcvalue.arc_mode = ArcChord; /* For coloring ATAB */ gcvalue.fill_style = FillSolid; /* Probably default ... */ gcmask = GCForeground | GCLineWidth | GCLineStyle | GCCapStyle | GCJoinStyle | GCArcMode | GCFillStyle;#ifdef TRANSPARENT /* set background color when there's no transparent */ if (!(( r->h->am_transparent || r->h->am_pixmap_trans) && ISSET_OPTION(r, Opt_transparent_tabbar)))#endif#ifdef BACKGROUND_IMAGE /* set background color when there's no bg image */ if ( ! r->tabBar.hasPixmap )#endif { gcvalue.background = r->tabBar.bg; gcmask |= GCBackground; } r->tabBar.gc = XCreateGC (r->Xdisplay, r->tabBar.win, gcmask, &gcvalue); assert (IS_GC(r->tabBar.gc)); XDefineCursor (r->Xdisplay, r->tabBar.win, r->h->bar_pointer); XSelectInput (r->Xdisplay, r->tabBar.win, ExposureMask | ButtonPressMask | ButtonReleaseMask#ifdef HAVE_MENUBAR | Button3MotionMask#endif );#ifdef XFT_SUPPORT if (NOTSET_OPTION(r, Opt_xft))#endif XSetFont (r->Xdisplay, r->tabBar.gc, r->TermWin.font->fid);#ifdef HAVE_LIBXPM xpm_color_sym.pixel = r->tabBar.bg; xpm_attr.colorsymbols = &xpm_color_sym; xpm_attr.numsymbols = 1; xpm_attr.visual = XVISUAL; xpm_attr.colormap = XCMAP; xpm_attr.depth = XDEPTH; xpm_attr.closeness = 65535; xpm_attr.valuemask = XpmVisual | XpmColormap | XpmDepth | XpmCloseness | XpmReturnPixels | XpmColorSymbols;#endif /* now, create the buttons */ for (i = 0; i < NB_XPM; i++) {#ifdef HAVE_LIBXPM XpmCreatePixmapFromData (r->Xdisplay, r->tabBar.win, xpm_name[i], &img_e[i], &img_emask[i], &xpm_attr); assert (IS_PIXMAP(img_e[i])); XpmCreatePixmapFromData (r->Xdisplay, r->tabBar.win, xpm_d_name[i], &img_d[i], &img_dmask[i], &xpm_attr); assert (IS_PIXMAP(img_d[i]));#else img[i] = XCreatePixmapFromBitmapData (r->Xdisplay, r->tabBar.win, (char *) xbm_name[i], BTN_WIDTH, BTN_HEIGHT, r->tabBar.fg, r->tabBar.bg, XDEPTH); assert (IS_PIXMAP(img[i]));#endif } rxvt_dbgmsg ((DBG_DEBUG, DBG_TABBAR, "TXT_XOFF=%d, TXT_YOFF=%d, ATAB_EXTRA=%d, TAB_RADIUS=%d\n", TXT_XOFF, TXT_YOFF, ATAB_EXTRA, TAB_RADIUS));}/* * Create the tab bar window *//* EXTPROTO */voidrxvt_tabbar_clean_exit (rxvt_t* r){ register int i; UNSET_WIN(r->tabBar.win); /* destroyed by XDestroySubwindows */ /* free resource strings */ if (r->tabBar.rsfg) rxvt_free ((void*) r->h->rs[Rs_tabfg]); if (r->tabBar.rsbg) rxvt_free ((void*) r->h->rs[Rs_tabbg]); if (r->tabBar.rsifg) rxvt_free ((void*) r->h->rs[Rs_itabfg]); if (r->tabBar.rsibg) rxvt_free ((void*) r->h->rs[Rs_itabbg]); if (IS_GC(r->tabBar.gc)) { XFreeGC (r->Xdisplay, r->tabBar.gc); UNSET_GC(r->tabBar.gc); } for (i = 0; i < NB_XPM; i ++) {#ifdef HAVE_LIBXPM if (IS_PIXMAP(img_e[i])) { XFreePixmap (r->Xdisplay, img_e[i]); UNSET_PIXMAP(img_e[i]); } if (IS_PIXMAP(img_emask[i])) { XFreePixmap (r->Xdisplay, img_emask[i]); UNSET_PIXMAP(img_emask[i]); } if (IS_PIXMAP(img_d[i])) { XFreePixmap (r->Xdisplay, img_d[i]); UNSET_PIXMAP(img_d[i]); } if (IS_PIXMAP(img_dmask[i])) { XFreePixmap (r->Xdisplay, img_dmask[i]); UNSET_PIXMAP(img_dmask[i]); }#else if (IS_PIXMAP(img[i])) XFreePixmap (r->Xdisplay, img[i]);#endif UNSET_PIXMAP(img[i]); } /* for */}/* EXTPROTO */unsigned shortrxvt_tabbar_height (rxvt_t* r){ if (NOT_WIN(r->tabBar.win) || !r->tabBar.state) return 0; return (rxvt_tabbar_rheight(r));}/* EXTPROTO */unsigned shortrxvt_tabbar_rheight (rxvt_t* r){ return (r->TermWin.FHEIGHT + 2*TXT_MARGIN + 2*TAB_BORDER + ATAB_EXTRA);}/* EXTPROTO */unsigned intrxvt_tab_width (rxvt_t *r, const char *str){#ifdef XFT_SUPPORT if ( ISSET_OPTION (r, Opt_xft) && r->TermWin.xftpfont) { /* * With a proportionally spaced font defined, let's try and make the * tabs look like firefox. All tabs have the same width. The more tabs * there are, the narrower the width becomes. The width does not depend * on the tab title. */ if( LTAB(r) >= 0 ) { int twidth = (TAB_SPACE - TAB_BORDER) / min( LTAB(r) + 1, r->TermWin.minVisibleTabs ) - TAB_BORDER; return min( twidth, MAX_TAB_PIXEL_WIDTH); } else return MAX_TAB_PIXEL_WIDTH; } else#endif { int len; uint16_t maxw = r->TermWin.maxTabWidth; assert (str); len = STRLEN (str); if (len > maxw) len = maxw;#ifdef XFT_SUPPORT if (ISSET_OPTION (r, Opt_xft) && (NULL != r->tabBar.xftwin)) { return (2 * TXT_XOFF + Width2Pixel(len)); } else#endif /* XFT_SUPPORT */ return (2 * TXT_XOFF + XTextWidth (r->TermWin.font, str, len)); }}/* EXTPROTO */intrxvt_is_tabbar_win (rxvt_t* r, Window w){ return (w == r->tabBar.win);}/* EXTPROTO */voidrxvt_tabbar_change_color (rxvt_t* r, int item, const char* str){ XColor xcol; int changed = 0; switch (item) { case MRxvt_tabfg: if (r->h->rs[Rs_tabfg] && !STRCASECMP(str, r->h->rs[Rs_tabfg])) break; /* no color change */ if (rxvt_parse_alloc_color (r, &xcol, str)) { r->tabBar.fg = xcol.pixel;#ifdef XFT_SUPPORT rxvt_alloc_xft_color( r, &xcol, &(r->tabBar.xftfg) );#endif if (r->tabBar.rsfg) /* free previous string */ rxvt_free ((void*) r->h->rs[Rs_tabfg]); r->h->rs[Rs_tabfg] = STRDUP(str); r->tabBar.rsfg = 1; /* free resource string later */ changed = 1; } break; case MRxvt_tabbg: if (r->h->rs[Rs_tabbg] && !STRCASECMP(str, r->h->rs[Rs_tabbg])) break; /* no color change */ if (rxvt_parse_alloc_color (r, &xcol, str)) { r->tabBar.bg = xcol.pixel; if (r->tabBar.rsbg) /* free previous string */ rxvt_free ((void*) r->h->rs[Rs_tabbg]); r->h->rs[Rs_tabbg] = STRDUP(str); r->tabBar.rsbg = 1; /* free resource string later */ changed = 1; } break; case MRxvt_itabfg: if (r->h->rs[Rs_itabfg] && !STRCASECMP(str, r->h->rs[Rs_itabfg])) break; /* no color change */ if (rxvt_parse_alloc_color (r, &xcol, str)) { r->tabBar.ifg = xcol.pixel;#ifdef XFT_SUPPORT rxvt_alloc_xft_color( r, &xcol, &(r->tabBar.xftifg) );#endif if (r->tabBar.rsifg) /* free previous string */ rxvt_free ((void*) r->h->rs[Rs_itabfg]); r->h->rs[Rs_itabfg] = STRDUP(str); r->tabBar.rsifg = 1; /* free resource string later */ changed = 1; } break; case MRxvt_itabbg: if (r->h->rs[Rs_itabbg] && !STRCASECMP(str, r->h->rs[Rs_itabbg])) break; if (rxvt_parse_alloc_color (r, &xcol, str)) { r->tabBar.ibg = xcol.pixel; if (r->tabBar.rsibg) /* free previous string */ rxvt_free ((void*) r->h->rs[Rs_itabbg]); r->h->rs[Rs_itabbg] = STRDUP(str); r->tabBar.rsibg = 1; /* free resource string later */ changed = 1; } break; default: break; } if (changed) { if (MRxvt_itabbg == item) {#if defined(TRANSPARENT) || defined(BACKGROUND_IMAGE) if (# ifdef TRANSPARENT ( (r->h->am_transparent || r->h->am_pixmap_trans) && ISSET_OPTION (r, Opt_transparent_tabbar) )# endif# if defined(TRANSPARENT) && defined(BACKGROUND_IMAGE) ||# endif# ifdef BACKGROUND_IMAGE ( r->tabBar.hasPixmap )# endif ) {# ifdef HAVE_LIBXRENDER /* Background image needs to be regrabed */ rxvt_refresh_bg_image(r, ATAB(r), False);# endif } else#endif { XSetWindowBackground (r->Xdisplay, r->tabBar.win, r->tabBar.ibg); } } /* * Better to put the expose event on the queue, than expose immediately. * Expose events can be expensive when using XRender transparency. */ XClearArea( r->Xdisplay, r->tabBar.win, 0, 0, 0, 0, True); }}/* * Move active tab to position newPage. *//* EXTPROTO */voidrxvt_tabbar_move_tab (rxvt_t* r, short newPage){ short curPage = ATAB(r); short i; if ( 0 == LTAB(r) || /* Only one tab (no move possible) */ newPage == curPage || /* Move to itself */ newPage < 0 || newPage > LTAB(r) /* Out of range */ ) return; if( newPage < curPage ) { term_t* temp_vt = r->vts[curPage]; /* Shift pages newPage .. curPage-1 one to the right. */ for( i = curPage; i > newPage; i--) r->vts[i] = r->vts[i-1]; r->vts[newPage] = temp_vt; /* Update selection */ if( r->selection.vt >= newPage && r->selection.vt < curPage ) r->selection.vt++; else if( r->selection.vt == curPage ) r->selection.vt = newPage; } else { term_t* temp_vt = r->vts[curPage]; /* Shift pages curPage+1 .. newPage one to the left. */ for( i = curPage; i < newPage; i++) r->vts[i] = r->vts[i+1]; r->vts[newPage] = temp_vt; /* Update selection */ if( r->selection.vt > curPage && r->selection.vt <= newPage) r->selection.vt--; else if( r->selection.vt == curPage ) r->selection.vt = newPage; } /* adjust active tab */ ATAB(r) = newPage; /* adjust previous active tab */ if (PTAB(r) == newPage) PTAB(r) = curPage; /* refresh tabbar */ if (newPage < FVTAB(r) || newPage > LVTAB(r)) rxvt_tabbar_set_visible_tabs (r, True); else { /* * If the width of newPage is different from that of curPage, then all * tabs in between newPage and curPage will have to be refreshed. */ for( i = min( newPage, curPage ); i <= max( newPage, curPage ); i++ ) refresh_tabbar_tab( r, i); } if( ISSET_OPTION( r, Opt2_syncTabTitle ) ) sync_tab_title( r, ATAB(r) );}/* * Synchronize the window title to th
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -