📄 menubar.c
字号:
y = this_y; if (NOT_NULL(thisitem)) { item = ActiveMenu->item; if (item->entry.itemType != MenuLabel) rxvt_drawbox_menuitem(r, y, +1); if (item->entry.itemType == MenuSubMenu) { int x; rxvt_menubar_draw_triangle(r, amenu_width, y, -1); x = ev->x + ActiveMenu->x; if (x >= item->entry.submenu.menu->x) { r->h->ActiveMenu = item->entry.submenu.menu; rxvt_menu_show(r); return 1; } } } return 0;}/* INTPROTO */voidrxvt_menubar_select(rxvt_t *r, XButtonEvent *ev){ menu_t *menu = NULL; rxvt_dbgmsg ((DBG_DEBUG, DBG_MENUBAR, "rxvt_menubar_select()\n")); /* determine the pulldown menu corresponding to the X index */ if ( ev->y >= 0 && ev->y <= (rxvt_menubar_height(r)-MENUBAR_MARGIN) ) { for (menu = r->h->MenuBar.head; NOT_NULL(menu); menu = menu->next) { int w = HSPACE_PIXEL + PTEXTWIDTH( r, menu->name, menu->len); if ((ev->x >= menu->x && ev->x < menu->x + w)) break; } } switch (ev->type) { case ButtonRelease: rxvt_menu_hide_all(r); break; case ButtonPress: if (IS_NULL(menu) && r->h->Arrows_x && ev->x >= r->h->Arrows_x) { int i; for (i = 0; i < NARROWS; i++) { if (ev->x >= (r->h->Arrows_x + (Width2Pixel(4 * i + i)) / 4) && ev->x < (r->h->Arrows_x + (Width2Pixel(4 * i + i + 4)) / 4)) { rxvt_draw_arrows(r, Arrows[i].name, -1); {#ifdef HAVE_NANOSLEEP struct timespec rqt; rqt.tv_sec = 0; rqt.tv_nsec = MENU_DELAY_USEC * 1000; nanosleep(&rqt, NULL);#else /* use select for timing */ struct timeval tv; tv.tv_sec = 0; tv.tv_usec = MENU_DELAY_USEC; select(0, NULL, NULL, NULL, &tv);#endif } rxvt_draw_arrows(r, Arrows[i].name, +1); rxvt_dispatch_action(r, &(r->h->MenuBar.arrows[i]), (XEvent *) ev); return; } } } /* FALLTHROUGH */ default: /* * press menubar or move to a new entry */ if (NOT_NULL(menu) && menu != r->h->ActiveMenu) { rxvt_menu_hide_all(r); /* pop down old menu */ r->h->ActiveMenu = menu; rxvt_menu_show(r); /* pop up new menu */ } break; }}/* EXTPROTO */voidrxvt_menubar_create (rxvt_t* r){ XGCValues gcvalue; unsigned long gcmask; rxvt_dbgmsg ((DBG_DEBUG, DBG_MENUBAR,"rxvt_menubar_create\n")); /* * Only create a menubar if it's non-empty. */ r->menuBar.state = 0; r->menuBar.win = XCreateSimpleWindow(r->Xdisplay, r->TermWin.parent, 0, 0, TWIN_WIDTH(r), rxvt_menubar_rheight (r), 0, r->pixColorsFocus[Color_fg], r->pixColorsFocus[Color_scroll]); assert (IS_WIN(r->menuBar.win));# ifdef DEBUG_X rxvt_set_win_title (r, r->menuBar.win, "menubar");# endif XDefineCursor(r->Xdisplay, r->menuBar.win, r->h->bar_pointer); XSelectInput(r->Xdisplay, r->menuBar.win, (ExposureMask | ButtonPressMask | ButtonReleaseMask | Button1MotionMask));# ifdef BACKGROUND_IMAGE UNSET_PIXMAP(r->menuBar.pixmap); /* Initialize it to None */# ifdef TRANSPARENT if (!(ISSET_OPTION(r, Opt_transparent) && ISSET_OPTION(r, Opt_transparent_menubar) ))# endif if (r->h->rs[Rs_menubarPixmap]) { long w = 0, h = 0; r->menuBar.pixmap = rxvt_load_pixmap (r, r->h->rs[Rs_menubarPixmap], &w, &h); if (IS_PIXMAP(r->menuBar.pixmap)) XSetWindowBackgroundPixmap (r->Xdisplay, r->menuBar.win, r->menuBar.pixmap); }# endif# ifdef TRANSPARENT if (ISSET_OPTION(r, Opt_transparent) && ISSET_OPTION(r, Opt_transparent_menubar)) { XSetWindowBackgroundPixmap (r->Xdisplay, r->menuBar.win, ParentRelative); }# endif /* * Initialize the colors. TODO: Add a sperate resource for this, instead of * mooching of the scroll bar resources. */ if( XDEPTH > 2 ) { /* * If Color_scroll is too dark, then we should use White for the menu * foreground. */ XColor xcol; xcol.pixel = r->pixColorsFocus[Color_scroll]; XQueryColor( r->Xdisplay, XCMAP, &xcol); r->menuBar.fg = r->pixColorsFocus[ (xcol.red <= 0x60 && xcol.green <= 0x60 && xcol.blue <= 0x60 ) ? Color_White : Color_Black ]; } else r->menuBar.fg = r->pixColorsFocus[ Color_bg ]; /* Reverse video */ r->menuBar.bg = r->pixColorsFocus[XDEPTH <= 2 ? Color_fg : Color_scroll]; r->menuBar.topshadow = r->pixColorsFocus[Color_topShadow]; r->menuBar.botshadow = r->pixColorsFocus[Color_bottomShadow]; gcvalue.foreground = r->menuBar.fg;# ifdef TRANSPARENT if (!(ISSET_OPTION(r, Opt_transparent) && ISSET_OPTION(r, Opt_transparent_menubar) ))# endif# ifdef BACKGROUND_IMAGE if (NOT_PIXMAP(r->menuBar.pixmap))# endif gcvalue.background = r->menuBar.bg; gcmask = GCForeground;# ifdef TRANSPARENT if (!(ISSET_OPTION(r, Opt_transparent) && ISSET_OPTION(r, Opt_transparent_menubar) ))# endif# ifdef BACKGROUND_IMAGE if (NOT_PIXMAP(r->menuBar.pixmap))# endif gcmask |= GCBackground; r->menuBar.gc = XCreateGC (r->Xdisplay, r->menuBar.win, gcmask, &gcvalue); assert (IS_GC(r->menuBar.gc));# ifdef XFT_SUPPORT if (ISSET_OPTION(r, Opt_xft)) { /* * Set up Xft stuff here. */ XColor xcol; r->menuBar.xftDraw = XftDrawCreate( r->Xdisplay, r->menuBar.win, XVISUAL, XCMAP); xcol.pixel = r->menuBar.fg; XQueryColor( r->Xdisplay, XCMAP, &xcol ); rxvt_alloc_xft_color( r, &xcol, &r->menuBar.xftFore); } else# endif { XSetFont(r->Xdisplay, r->menuBar.gc, r->TermWin.font->fid); }}/* EXTPROTO */voidrxvt_menubar_clean_exit (rxvt_t* r){ rxvt_dbgmsg ((DBG_DEBUG, DBG_MENUBAR, "rxvt_menubar_clean_exit()\n"));# ifdef XFT_SUPPORT /* * Sometimes gives a RenderBadPicture error, so don't destroy it. */# if 0 if (ISSET_OPTION(r, Opt_xft)) { XftDrawDestroy( r->menuBar.xftDraw); }# endif# endif UNSET_WIN(r->menuBar.win); /* Destroyed by XDestroySubwindows */ if (IS_GC(r->menuBar.gc)) { XFreeGC (r->Xdisplay, r->menuBar.gc); UNSET_GC(r->menuBar.gc); }# ifdef BACKGROUND_IMAGE if (IS_PIXMAP(r->menuBar.pixmap)) { XFreePixmap (r->Xdisplay, r->menuBar.pixmap); UNSET_PIXMAP(r->menuBar.pixmap); }# endif}/*** Is the menubar visible*//* EXTPROTO */intrxvt_menubar_visible (rxvt_t* r){ rxvt_dbgmsg ((DBG_DEBUG, DBG_MENUBAR, "rxvt_menubar_visible()\n")); return (IS_WIN(r->menuBar.win) && r->menuBar.state);}/*** Hide the menubar*//* EXTPROTO */intrxvt_menubar_hide (rxvt_t* r){ int changed = 0; rxvt_dbgmsg ((DBG_DEBUG, DBG_MENUBAR, "rxvt_menubar_hide()\n")); assert (IS_WIN(r->menuBar.win)); changed = r->menuBar.state; XUnmapWindow(r->Xdisplay, r->menuBar.win); r->menuBar.state = 0; return (changed);}/*** Show the menubar*//* EXTPROTO */intrxvt_menubar_show (rxvt_t* r){ int changed = 0; rxvt_dbgmsg ((DBG_DEBUG, DBG_MENUBAR, "rxvt_menubar_show()\n")); assert (IS_WIN(r->menuBar.win)); changed = !r->menuBar.state; XMapWindow(r->Xdisplay, r->menuBar.win); r->menuBar.state = 1; return (changed);}/* * Menubar expose handler *//* EXTPROTO */voidrxvt_menubar_expose(rxvt_t *r){ rxvt_dbgmsg ((DBG_DEBUG, DBG_MENUBAR, "rxvt_menubar_expose()\n")); if (!r->menuBar.state || NOT_WIN(r->menuBar.win)) return; rxvt_menu_hide_all(r); rxvt_menubar_draw_labels(r);}/* INTPROTO */voidrxvt_menubar_draw_labels( rxvt_t *r){ menu_t *menu; int x; XClearWindow(r->Xdisplay, r->menuBar.win); x = 0; for (menu = r->h->MenuBar.head; NOT_NULL(menu); menu = menu->next) { unsigned short len = menu->len; x = (menu->x + menu->len + HSPACE);# ifdef DEBUG rxvt_print_menu_descendants(menu);# endif /* if (x >= r->TermWin.ncol) len = (r->TermWin.ncol - (menu->x + HSPACE)); */ /* 2006-01-29 gi1242: Boxes in the menubar are ugly */#if 0 rxvt_drawbox_menubar(r, menu->x, len, +1);#endif CHOOSE_GC_FG (r, r->menuBar.fg);# ifdef XFT_SUPPORT /* * XXX Add multichar support. */ if (ISSET_OPTION(r, Opt_xft)) { XftFont *font = r->TermWin.xftpfont ? r->TermWin.xftpfont : r->TermWin.xftfont; XftDrawString8( r->menuBar.xftDraw, &r->menuBar.xftFore, font, (menu->x + HSPACE_PIXEL / 2), rxvt_menubar_height(r) - SHADOW - MENUBAR_MARGIN - font->descent, menu->name, len); } else# endif# ifdef USE_XIM if (r->TermWin.fontset) XmbDrawString(r->Xdisplay, r->menuBar.win, r->TermWin.fontset, r->menuBar.gc, (menu->x + HSPACE_PIXEL / 2), rxvt_menubar_height(r) - SHADOW - MENUBAR_MARGIN - r->TermWin.font->descent, (char*) menu->name, len); else# endif /* USE_XIM */ XDrawString(r->Xdisplay, r->menuBar.win, r->menuBar.gc, (menu->x + HSPACE_PIXEL / 2), rxvt_menubar_height(r) - SHADOW - MENUBAR_MARGIN - r->TermWin.font->descent, (char*) menu->name, len); if (x >= TWIN_WIDTH(r) ) break; }#if 0 rxvt_drawbox_menubar(r, x, r->TermWin.ncol, (r->h->CurrentBar ? +1 : -1));#endif /* add the menuBar title, if it exists and there's plenty of room */ r->h->Arrows_x = 0; if (x < TWIN_WIDTH(r) ) { const unsigned char *str; int npixels; /* used to be ncol */ unsigned short len; unsigned char title[256]; npixels = TWIN_WIDTH(r); if (x < (npixels - NARROWS * MENUBAR_ARROW_WIDTH - HSPACE_PIXEL)) { npixels -= NARROWS * MENUBAR_ARROW_WIDTH + HSPACE_PIXEL; r->h->Arrows_x = npixels; } rxvt_draw_arrows(r, 0, +1); str = ( r->h->MenuBar.title) ? r->h->MenuBar.title : (unsigned char*) "%n-%v"; for (len = 0; str[0] && len < sizeof(title) - 1; str++) { const char *s = NULL; switch (str[0]) { case '%': str++; switch (str[0]) { case 'n': s = r->h->rs[Rs_name]; break; /* resource name */ case 'v': s = VERSION; break; /* version number */ case '%': s = "%"; break; /* literal '%' */ } if (NOT_NULL(s)) while (*s && len < sizeof(title) - 1) title[len++] = *s++; break; default: title[len++] = str[0]; break; } } title[len] = '\0'; npixels -= x + HSPACE_PIXEL + PTEXTWIDTH( r, title, len); if (len > 0 && npixels >= 0) { CHOOSE_GC_FG (r, r->menuBar.fg);# ifdef XFT_SUPPORT /* * XXX Add multichar support. */ if (ISSET_OPTION(r, Opt_xft)) { XftFont *font = r->TermWin.xftpfont ? r->TermWin.xftpfont : r->TermWin.xftfont; XftDrawString8( r->menuBar.xftDraw, &r->menuBar.xftFore, font, x + (npixels + HSPACE_PIXEL) / 2, rxvt_menubar_height(r) - SHADOW - MENUBAR_MARGIN - font->descent, title, len); } else# endif# ifdef USE_XIM if (r->TermWin.fontset) XmbDrawString(r->Xdisplay, r->menuBar.win, r->TermWin.fontset, r->menuBar.gc, x + (npixels + HSPACE_PIXEL) / 2, rxvt_menubar_height(r) - SHADOW - MENUBAR_MARGIN - r->TermWin.font->descent, (char*) title, len); else# endif /* USE_XIM */ XDrawString(r->Xdisplay, r->menuBar.win, r->menuBar.gc, x + (npixels + HSPACE_PIXEL) / 2, rxvt_menubar_height(r) - SHADOW - MENUBAR_MARGIN - r->TermWin.font->descent, (char*) title, len); } }}/*** user interface for building/deleting and otherwise managing menus*//* EXTPROTO */voidrxvt_menubar_dispatcher(rxvt_t *r, unsigned char *str){ int n, cmd; unsigned char *path, *name, *name2; rxvt_dbgmsg ((DBG_DEBUG, DBG_MENUBAR, "rxvt_menubar_dispatcher()\n"));#if 0 if (rxvt_menubar_visible(r) && NOT_NULL(r->h->ActiveMenu)) rxvt_menubar_expose(r); else SET_NULL(r->h->ActiveMenu);#endif cmd = *str; switch (cmd) { case '.': case '/': /* absolute & relative path */ case MENUITEM_BEG: /* menuitem */ /* add `+' prefix for these cases */ cmd = '+'; break; case '+': case '-': str++; /* skip cmd character */ break; case '<': if (str[1] && str[2] == '>') /* arrow commands */ rxvt_menuarrow_add(r, str); break; case '[': /* extended command */ while (str[0] == '[') {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -