📄 transparent.c
字号:
}# endif /* HAVE_MENUBAR */ if (ISSET_OPTION(r, Opt_transparent_tabbar)) {# ifdef BACKGROUND_IMAGE if (r->tabBar.hasPixmap) { 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); } else r->tabBar.hasPixmap = False; } else# endif /* BACKGROUND_IMAGE */ XSetWindowBackground (r->Xdisplay, r->tabBar.win, r->tabBar.ibg); } } else { rxvt_dbgmsg ((DBG_VERBOSE, DBG_TRANSPARENT, "set background transparency\n")); SET_OPTION(r, Opt_transparent); XSetWindowBackgroundPixmap (r->Xdisplay, r->TermWin.parent, ParentRelative); for (i = 0; i <= LTAB(r); i ++) { XSetWindowBackgroundPixmap (r->Xdisplay, PVTS(r, i)->vt, ParentRelative); }# ifdef HAVE_SCROLLBARS if (IS_WIN(r->scrollBar.win) && ISSET_OPTION(r, Opt_transparent_scrollbar)) XSetWindowBackgroundPixmap (r->Xdisplay, r->scrollBar.win, ParentRelative);# endif# ifdef HAVE_MENUBAR if (IS_WIN(r->menuBar.win) && ISSET_OPTION(r, Opt_transparent_menubar)) XSetWindowBackgroundPixmap (r->Xdisplay, r->menuBar.win, ParentRelative);# endif if (ISSET_OPTION(r, Opt_transparent_tabbar)) XSetWindowBackgroundPixmap (r->Xdisplay, r->tabBar.win, ParentRelative); XSelectInput(r->Xdisplay, XROOT, PropertyChangeMask); rxvt_check_our_parents (r); } /* Clear all windows */ XClearWindow (r->Xdisplay, r->TermWin.parent);# ifdef HAVE_SCROLLBARS rxvt_scrollbar_update (r, 0);# endif# ifdef HAVE_MENUBAR rxvt_menubar_expose (r);# endif rxvt_tabbar_expose (r, NULL); rxvt_scr_clear (r, ATAB(r)); rxvt_scr_touch (r, ATAB(r), True);}/* refreshRootBGVars(r) {{{2 * * Refresh our information about the root pixmap and it's geometry etc. This * should be called every time the desktop changes. *//* EXTPROTO */voidrefreshRootBGVars(rxvt_t *r ){ unsigned long nitems, bytes_after; Atom atype; int aformat; unsigned char *prop = NULL; r->h->allowedxerror = 1; r->h->xerror_return = Success; /* Get new root pixmap ID in h->rootPixmap*/ if ( IS_ATOM(r->h->xa[XA_XROOTPMAPID]) && XGetWindowProperty( r->Xdisplay, XROOT, r->h->xa[XA_XROOTPMAPID], 0L, 1L, False, XA_PIXMAP, &atype, &aformat, &nitems, &bytes_after, &prop) == Success && prop != NULL ) { int u_rootx, u_rooty; /* u_ variables are unused */ unsigned u_bw, u_depth; Window u_cr; r->h->rootPixmap = *( (Pixmap *) prop ); r->h->bgGrabbed = False; XFree( prop); /* Get root pixmap geometry */ XGetGeometry( r->Xdisplay, r->h->rootPixmap, &u_cr, &u_rootx, &u_rooty, &r->h->rpWidth, &r->h->rpHeight, &u_bw, &u_depth); } else /* Failed. */ UNSET_PIXMAP(r->h->rootPixmap); r->h->allowedxerror = 0; if( r->h->xerror_return != Success ) /* Set by xerror handler */ UNSET_PIXMAP(r->h->rootPixmap); rxvt_dbgmsg ((DBG_VERBOSE, DBG_TRANSPARENT, "Got %snull root pixmap %lx\n", NOT_PIXMAP(r->h->rootPixmap) ? "" : "non-", r->h->rootPixmap));}/* {{{2 rxvt_check_our_parents(r) * * Check our parents are still who we think they are. Do transparency updates if * required. *//* EXTPROTO */intrxvt_check_our_parents(rxvt_t *r){ int have_changed = 0, rootdepth; XWindowAttributes wattr, wrootattr; Window u_cr; /* * We dont' really have to check our parents if we're not transparent :) */ if (NOTSET_OPTION(r, Opt_transparent)) return have_changed; rxvt_dbgmsg ((DBG_DEBUG, DBG_TRANSPARENT, "rxvt_check_our_parent ()\n")); /* * Don't try transparency if window depth is not the same as the root depth. */ XGetWindowAttributes(r->Xdisplay, XROOT, &wrootattr); rootdepth = wrootattr.depth; XGetWindowAttributes(r->Xdisplay, r->TermWin.parent, &wattr); if (rootdepth != wattr.depth ) { /* * Oops. We can't be transparent (or pixmap_transparent). */ assert (-1 != LTAB(r)); /* should't happen */ rxvt_dbgmsg ((DBG_VERBOSE, DBG_TRANSPARENT, "Bad depth, transparency failed: (%u, %u)\n", rootdepth, wattr.depth)); rxvt_msg (DBG_ERROR, DBG_TRANSPARENT, "Root window has different depth. Disabling transparency"); r->h->am_pixmap_trans = 0; UNSET_OPTION(r, (Opt_forceTransparent | Opt_transparent)); return tempDisableTransparent( r ); } /* * r->szHint should contain the correct location of this window if we got * here from a configure notify event. If we got here from reparent_notify, * then we need to set it ourselves to offset WM decorations */ XTranslateCoordinates( r->Xdisplay, r->TermWin.parent, XROOT, 0, 0, &r->szHint.x, &r->szHint.y, &u_cr); /* * Don't try refreshing our background if we're completely off screen. */ if ( r->szHint.x + r->szHint.width <= 0 || r->szHint.x >= (int) wrootattr.width || r->szHint.y + r->szHint.height <= 0 || r->szHint.y >= (int) wrootattr.height ) return 0; XSync(r->Xdisplay, False); r->h->allowedxerror = 1; r->h->xerror_return = Success; /* * Use "do" instead of "if" so we can break out if transparency updates * don't need to be performed. */ do /* while( 0 ) */ { /* * Copy XROOT pixmap transparency */ int retvt = 0; if (NOT_PIXMAP(r->h->rootPixmap)) { have_changed = tempDisableTransparent( r); break; } retvt = resetParentPixmap( r, wrootattr.width, wrootattr.height, wrootattr.depth); if (retvt ) { /* All good. */ r->h->bgGrabbed = True; r->h->prevPos.x = r->szHint.x; r->h->prevPos.y = r->szHint.y; r->h->prevPos.width = r->szHint.width; r->h->prevPos.height = r->szHint.height; have_changed = 1; r->h->am_transparent = 1; r->h->am_pixmap_trans = 0; expose_transparent_subwin( r ); rxvt_dbgmsg ((DBG_VERBOSE, DBG_TRANSPARENT, "Enabled XROOT pseudo-transparency\n")); } else have_changed = tempDisableTransparent( r); } while( 0 ); /* * Disable transparency if something went wrong above. */ r->h->allowedxerror = 0; if( r->h->xerror_return != Success && r->h->am_transparent ) /* Only call if we're still transparent (otherwise we might call * tempDisableTransparent twice). */ have_changed = tempDisableTransparent( r ); /* * 2006-01-07 gi1242: This code doesn't work too well. The problem is that * if the user sets the desktop with say xsetroot, and we recieve an expose * event, then we only refresh part of our window. This causes really ugly * effects. */ if( !r->h->am_transparent && ISSET_OPTION(r, Opt_forceTransparent) ) { /* * Try "transparent transparency" legacy code. */ Window root, oldp, *list; unsigned int i, n; /* * Make the frame window set by the window manager that have the root * background. Some window managers put multiple nested frame windows for * each client, so we have to take care about that. */ rxvt_dbgmsg ((DBG_VERBOSE, DBG_TRANSPARENT, "Transparent Seeking to %08lx\n", XROOT)); for (i = 1; i < PARENT_NUMBER; i++) { /* * Check if any of our "parents" have changed. */ oldp = r->TermWin.parenttree[i]; XQueryTree(r->Xdisplay, r->TermWin.parenttree[i - 1], &root, &r->TermWin.parenttree[i], &list, &n); XFree(list); rxvt_dbgmsg ((DBG_VERBOSE, DBG_TRANSPARENT, "Transparent Parent[%d] = %08lx\n", i, r->TermWin.parenttree[i] )); if (r->TermWin.parenttree[i] == XROOT) { if (IS_WIN(oldp)) have_changed = 1; break; } if (oldp != r->TermWin.parenttree[i]) have_changed = 1; } n = 0; /* * Now set background of all windows in this tree to ParentRelative. */ for (; n < (unsigned int)i; n++) { /* * Make sure we don't have any input only (or different depth) * windows. */ XGetWindowAttributes(r->Xdisplay, r->TermWin.parenttree[n], &wattr); rxvt_dbgmsg ((DBG_VERBOSE, DBG_TRANSPARENT, "Transparent Checking Parent[%d]: %s\n", n, (wattr.depth == rootdepth && wattr.class != InputOnly) ? "OK" : "FAIL")); if (wattr.depth != rootdepth || wattr.class == InputOnly) { n = PARENT_NUMBER + 1; break; } } if (n > PARENT_NUMBER) { /* * Bummer. We got an inputonly (or bad depth) window. Fail. */ rxvt_dbgmsg ((DBG_VERBOSE, DBG_TRANSPARENT, "Transparent Turning off\n")); if( r->h->am_pixmap_trans ) { r->h->am_pixmap_trans = 0; r->h->want_full_refresh = 1; have_changed = 1; XSetWindowBackground(r->Xdisplay, r->TermWin.parent, VTBG(r, 0) ); expose_transparent_subwin( r ); } } else { rxvt_dbgmsg ((DBG_VERBOSE, DBG_TRANSPARENT, "Transparent Turning on (%d parents). Geometry %ux%u+%d+%d\n", i - 1, r->szHint.width, r->szHint.height, r->szHint.x, r->szHint.y)); for (n = 0; n < i; n ++) XSetWindowBackgroundPixmap(r->Xdisplay, r->TermWin.parenttree[n], ParentRelative); r->h->am_pixmap_trans = 1; have_changed = 1; expose_transparent_subwin( r ); } /* * Set the tail portion of our tree to None for future calls */ for (; i < PARENT_NUMBER; i++) UNSET_WIN(r->TermWin.parenttree[i]); } rxvt_dbgmsg ((DBG_VERBOSE, DBG_TRANSPARENT, "am_transparent: %hhu am_pixmap_trans: %hhu have_changed %d\n", r->h->am_transparent, r->h->am_pixmap_trans, have_changed)); return have_changed;}#endif /* TRANSPARENT *//* {{{1 Background image + Transparent functions */#if defined(BACKGROUND_IMAGE) || defined(TRANSPARENT)/* {{{2 rxvt_refresh_bg_image( r, page, imediate) *//* EXTPROTO */voidrxvt_refresh_bg_image (rxvt_t* r, int page, Bool imediate){ rxvt_dbgmsg ((DBG_VERBOSE, DBG_TRANSPARENT, "rxvt_refresh_bg_image\n"));# ifdef TRANSPARENT if (ISSET_OPTION(r, Opt_transparent)) { if( imediate || !r->h->bgRefreshInterval ) { /* reset background NOW */ rxvt_check_our_parents (r); rxvt_scr_clear (r, page); rxvt_scr_touch (r, page, imediate); } else { /* Generate a timeout to refresh the bg image. TODO lastCNotify * should be called something else */ gettimeofday( &r->h->lastCNotify, NULL); r->h->bgGrabbed = False; /* So timeout will force refresh */ } } else# endif /* TRANSPARENT */ {# ifdef BACKGROUND_IMAGE /* Reset background image */ register int i; for (i = 0; i <= LTAB(r); i ++) rxvt_resize_pixmap (r, i);# endif /* BACKGROUND_IMAGE */ rxvt_scr_clear (r, page); rxvt_scr_touch (r, page, imediate); }}#endif /* BACKGROUND_IMAGE || TRANSPARENT *//* {{{1 Tinting functions */#ifdef TINTING_SUPPORT# ifdef HAVE_LIBXRENDER/* {{{2 XRender tinting functions *//* {{{3 xrenderShadeParentPixmap( r, pmap, nx, ny, nw, nh, shadeSubwin) * * Shade the pixmap as though it were the parent window's pixmap. The * coordinates nx, ny, nw, nh determine the location in pmap that needs to be * shaded (e.g. if the window is partially off screen, we only need to shade the * portion of pmap that's on screen). * * If shadeSubwin is true, then areas corresponding to the tab / scroll / menu * bar are tinted with their respective background colors. * * pmap should have dimensions equal to the parent window. *//* EXTPROTO */voidxrenderShadeParentPixmap( rxvt_t *r, Pixmap pmap, int nx, int ny, unsigned nw, unsigned nh, Bool shadeSubwin){ int rx = 0, ry = 0; /* coords of tabbar etc */ unsigned rw = TWIN_WIDTH (r), /* dims of tabbar etc */ rh = TWIN_HEIGHT (r); Picture pic; XRenderPictFormat *format; XRenderPictureAttributes attrs; format = XRenderFindVisualFormat( r->Xdisplay, XVISUAL); pic = XRenderCreatePicture( r->Xdisplay, pmap, format, 0, &attrs);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -