⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tabbar.c

📁 Mrxvt是一个小巧
💻 C
📖 第 1 页 / 共 4 页
字号:
			LVTS(r)->cmd_fd =				rxvt_run_command( r, LTAB(r), (const char**) argv );			/* Restore old working directory. */			chdir( cwd );		}		else		{			/* Exec command in original directory. */			DBG_MSG( 2, ( stderr, "Running child in original directory\n"));			LVTS(r)->cmd_fd =				rxvt_run_command( r, LTAB(r), (const char**) argv );		}		/* Glibc extension to getcwd: When passed a null pointer it allocates		 * memory for the path. So we need to free it now. */		free( cwd );	}	else		LVTS(r)->cmd_fd = rxvt_run_command (r, LTAB(r), (const char**) argv);	/*	 * In case we allocated memory for argv using rxvt_string_to_argv (because a	 * command was specified), then free it.	 */	if( num_cmd_args > 0)	{		char **s;		for( s = argv; *s != NULL; s++) free(*s);		free( argv );	}	/*	 * If run command failed, rollback	 */	assert( -1 != LVTS(r)->cmd_fd );	if (-1 == LVTS(r)->cmd_fd)	{		rxvt_destroy_termwin (r, LTAB(r));		LTAB(r) --;		return;	}	DBG_MSG(2,(stderr,"page %d's cmd_fd is %d\n", LTAB(r), LVTS(r)->cmd_fd));	/*	 * Reduce r->num_fds so that select() is more efficient	 */	num_fds = max( STDERR_FILENO, LVTS(r)->cmd_fd );	MAX_IT( num_fds, r->Xfd );	MAX_IT( num_fds, r->num_fds-1 );/* #ifdef __sgi */#ifdef OS_IRIX	/* Alex Coventry says we need 4 & 7 too */	MAX_IT( num_fds, 7 );#endif	r->num_fds = num_fds + 1;	/* counts from 0 */	DBG_MSG(1, (stderr, "Adjust num_fds to %d\n", r->num_fds));	/*	 * Initialize the screen data structures	 */	rxvt_scr_reset (r, LTAB(r));	rxvt_scr_refresh (r, LTAB(r), FAST_REFRESH);	/*	 * Now we actually execute the command after executing shell, but we need	 * careful check first.	 */	if( command != NULL && *command == '!' )	{		command++;	/* Skip leading '!' */		rxvt_tt_write( r, LTAB(r), (const unsigned char*) command,				STRLEN(command) );		rxvt_tt_write( r, LTAB(r), (const unsigned char*) "\n", 1 );	}	/*	 * Now update active page information	 */	PTAB(r) = ATAB(r); /* set last previous tab */	ATAB(r) = LTAB(r); /* set the active tab */	/* update mapped flag */	AVTS(r)->mapped = 1;	/* first tab is special since ptab = atab now */	if (PTAB(r) != ATAB(r))		PVTS(r, r->tabBar.ptab)->mapped = 0;	/* Adjust visible tabs */	rxvt_tabbar_set_visible_tabs (r, True);	/* Send expose events to tabbar */	refresh_tabbar_tab( r, PTAB(r));		/* PTAB will need to be drawn as											   inactive */	/*	 * Auto show tabbar if we have exactly two tabs.	 */	if(		 !r->tabBar.state && LTAB(r) == 1		 && (r->Options2 & Opt2_autohideTabbar)		 && rxvt_tabbar_show( r )	  )		rxvt_resize_on_subwin( r, SHOW_TABBAR);	/* synchronize terminal title with tab title */	if (r->Options2 & Opt2_syncTabTitle)		rxvt_set_term_title (r,				(const unsigned char*) PVTS(r, ATAB(r))->tab_title);	/* synchronize icon name to tab title */	if (r->Options2 & Opt2_syncTabIcon)		rxvt_set_icon_name (r,				(const unsigned char*) PVTS(r, ATAB(r))->tab_title);}/* * Called by the handler of SIGCHLD; destroy the terminal and its tab *//* EXTPROTO */voidrxvt_remove_page (rxvt_t* r, short page){	register int	i;	DBG_MSG(1, (stderr,"remove_page(%d)\n", page));	/* clean utmp/wtmp entry */#ifdef UTMP_SUPPORT	rxvt_privileges (RESTORE);	rxvt_cleanutent (r, page); 	rxvt_privileges (IGNORE);#endif	/* free virtual terminal related resources */	assert (PVTS(r, page)->ttydev);	free (PVTS(r, page)->ttydev);	assert (PVTS(r, page)->cmd_fd >= 0);	close (PVTS(r, page)->cmd_fd);	if (PVTS(r, page)->v_buffer)	{		free (PVTS(r, page)->v_buffer);		PVTS(r, page)->v_buffer = NULL;	}	/* to adjust num_fds if necessary */	if (PVTS(r, page)->cmd_fd == r->num_fds-1)	{		r->num_fds --;		DBG_MSG(1, (stderr, "Adjust num_fds to %d\n", r->num_fds));	}	/* free screen structure */	rxvt_scr_release (r, page);	/* destroy the virtual terminal window */	rxvt_destroy_termwin (r, page);	/* quit the last the terminal, exit the application */	if (LTAB(r) == 0)	{		rxvt_clean_exit (r);	}	/* update TermWin and tab_widths */	for (i = page; i < LTAB(r); i++)	{		PVTS(r, i) = PVTS(r, i+1);		refresh_tabbar_tab( r, i);	}	/* update total number of tabs */	LTAB(r)--;	/* update selection */	if (page == r->selection.vt)		rxvt_process_selectionclear (r, page);	else if (r->selection.vt > page)		r->selection.vt --;	/*	 * Now we try to set correct atab, ptab, fvtab, and lvtab	 * Must be careful here!!!	 */	/* update previous active tab */	if (PTAB(r) > page) PTAB(r)--;	/* in case PTAB is invalid */	if (PTAB(r) > LTAB(r)) PTAB(r) = LTAB(r);	/* update active tab */	if( ATAB(r) == page )	{		/* Fall back to previous active */		ATAB(r) = PTAB(r);		/* Make the previous active tab the previous / next tab if possible. */		if( PTAB(r) > 0 ) PTAB(r)--;		else if (PTAB(r) < LTAB(r) ) PTAB(r)++;	}	else if( ATAB(r) > page) ATAB(r)--;	/* always set mapped flag */	AVTS(r)->mapped = 1;	/* adjust visible tabs */	rxvt_tabbar_set_visible_tabs (r, True);	refresh_tabbar_tab( r, ATAB(r));	/* Active tab has changed */	/* redraw the tabs and buttons */	if (r->tabBar.state)	{		if( LTAB(r) == 0 && (r->Options2 & Opt2_autohideTabbar) 				&& rxvt_tabbar_hide( r ))			/*			 * Only one tab left. Auto hide tabbar.			 */			rxvt_resize_on_subwin (r, HIDE_TABBAR);	}	/* Switch fg/bg colors */	rxvt_switch_fgbg_color (r, ATAB(r));	XMapRaised  (r->Xdisplay, AVTS(r)->vt);	/*	 * We don't need to touch the screen here. XMapRaised will generate a	 * MapNotify and Expose events, which will refresh the screen as needed.	 * Touching the screen unnecessarily causes a flicker (and is *horrible*	 * under slow connections).	 */	/* rxvt_scr_touch (r, ATAB(r), True); */	/* synchronize terminal title with tab title */	if (r->Options2 & Opt2_syncTabTitle)		rxvt_set_term_title (r, (const unsigned char*) PVTS(r, ATAB(r))->tab_title);	/* synchronize icon name to tab title */	if (r->Options2 & Opt2_syncTabIcon)		rxvt_set_icon_name(r, (const unsigned char*) PVTS(r, ATAB(r))->tab_title);}/* * Set new title for a tab *//* EXTPROTO */voidrxvt_tabbar_set_title (rxvt_t* r, short page, const unsigned char TAINTED * str){	char UNTAINTED *		n_title;	assert (str);	assert (page >= 0 && page <= LTAB(r));	assert (PVTS(r, page)->tab_title);	n_title = STRNDUP (str, MAX_TAB_TXT);	/*	 * If strdup succeeds, set new title	 */	if (NULL != n_title)	{		free (PVTS(r, page)->tab_title);		PVTS(r, page)->tab_title = n_title;		/* Compute the new width of the tab */		PVTS(r, page)->tab_width = rxvt_tab_width (r, n_title);	}	/*	 * If visible tab's title is changed, refresh tab bar	 */	if (page >= FVTAB(r) && page <= LVTAB(r))	{		/* adjust visible tabs */		rxvt_tabbar_set_visible_tabs (r, True);		refresh_tabbar_tab(r, page);	}	/* synchronize terminal title with active tab title */	if ((r->Options2 & Opt2_syncTabTitle) &&		(page == ATAB(r)))		rxvt_set_term_title (r, (const unsigned char*) PVTS(r, ATAB(r))->tab_title);	/* synchronize icon name to tab title */	if ((r->Options2 & Opt2_syncTabIcon) &&		(page == ATAB(r)))		rxvt_set_icon_name(r, (const unsigned char*) PVTS(r, ATAB(r))->tab_title);}/* * Activate a page terminal *//* EXTPROTO */voidrxvt_activate_page (rxvt_t* r, short index){	/* shortcut */	if (/* !r->tabBar.state ||		None == r->tabBar.win || */		index == ATAB(r))		return;	AVTS(r)->mapped = 0;	r->tabBar.ptab = ATAB(r);	ATAB(r) = index;	AVTS(r)->mapped = 1;	AVTS(r)->highlight = 0;	/* clear highlight flag */		/*	 * Now the visible tabs may be changed, recompute the visible	 * tabs before redrawing.	 */	if (index < FVTAB(r) || index > LVTAB(r))	{		/* adjust visible tabs */		rxvt_tabbar_set_visible_tabs (r, True);	}	refresh_tabbar_tab( r, ATAB(r));	refresh_tabbar_tab( r, PTAB(r));	/* Switch VT fg/bg colors */	rxvt_switch_fgbg_color (r, ATAB(r));	XMapRaised  (r->Xdisplay, AVTS(r)->vt);	/*	 * We don't need to touch the screen here. XMapRaised will generate a	 * MapNotify and Expose events, which will refresh the screen as needed.	 * Touching the screen unnecessarily causes a flicker (and is *horrible*	 * under slow connections).	 */	/* rxvt_scr_touch (r, ATAB(r), True); */	DBG_MSG(1,(stderr,"active page is %d\n",ATAB(r)));	/* synchronize terminal title with tab title */	if (r->Options2 & Opt2_syncTabTitle)		rxvt_set_term_title (r, (const unsigned char*) PVTS(r, ATAB(r))->tab_title);	/* synchronize icon name to tab title */	if (r->Options2 & Opt2_syncTabIcon)		rxvt_set_icon_name(r, (const unsigned char*) PVTS(r, ATAB(r))->tab_title);}/* * Change the width of the tab bar *//* EXTPROTO */voidrxvt_tabbar_resize (rxvt_t* r){	register int	i;	int				sx, sy;	sx = 0;	sy = 0;#ifdef HAVE_MENUBAR	sy += rxvt_menubar_height (r);#endif	if (r->Options2 & Opt2_bottomTabbar)		sy += VT_HEIGHT(r);	XMoveResizeWindow  (r->Xdisplay, r->tabBar.win,		sx, sy, TWIN_WIDTH(r), rxvt_tabbar_rheight (r));	/* recompute width of each tab */	for (i = 0; i <= LTAB(r); i ++)		PVTS(r, i)->tab_width = rxvt_tab_width (r, PVTS(r, i)->tab_title);	/* adjust visible tabs */	rxvt_tabbar_set_visible_tabs (r, False);	/* redraw the tabs and buttons */	XClearArea( r->Xdisplay, r->tabBar.win,			0, 0, 0, 0, True);}/* * Determine the position of pointer click and dispatch the event *//* EXTPROTO */voidrxvt_tabbar_dispatcher (rxvt_t* r, XButtonEvent* ev){	register int	x, y, z, but;	x = ev->x;	y = ev->y;	but = -1;	DBG_MSG( 2, ( stderr, "click in (%d,%d)\n", x, y));	/* Button4 and Button5 of wheel mouse activate the left/right tab */	switch ( ev->button )	{#ifdef HAVE_MENUBAR		case Button3:			if( r->h->popupMenu[0] )			{				int		x, y;				Window	unused_cr;				r->h->showingMenu |= POPUP_MENU;				XTranslateCoordinates( r->Xdisplay, ev->window,						r->TermWin.parent, ev->x, ev->y, &x, &y, &unused_cr);				r->h->ActiveMenu = r->h->popupMenu[0];				r->h->ActiveMenu->x = x;				r->h->ActiveMenu->y = y;				XDefineCursor(r->Xdisplay, AVTS(r)->vt, r->h->bar_pointer);				rxvt_menu_show(r);				return;			}			break;#endif		case Button4: /* scroll-up -> activate right tab */			if( ATAB(r) != LTAB(r) )				rxvt_activate_page( r, ATAB(r) + 1 );			else if( 0 != LTAB(r) )				rxvt_activate_page( r, 0 );			return;		case Button5: /* scroll-down -> activate left tab */			if (0 != ATAB(r))				rxvt_activate_page (r, ATAB(r)-1);			else if (0 != LTAB(r))				rxvt_activate_page (r, LTAB(r));			return;		default:			break;	}	/* let's decode where the user click */	z = TWIN_WIDTH(r) - x;	if (			!(r->Options2 & Opt2_hideButtons)			&& z < 4*(BTN_WIDTH+BTN_SPACE)			&& (z%(BTN_WIDTH+BTN_SPACE)) > BTN_SPACE	   )	{		but = z/(BTN_WIDTH+BTN_SPACE);		/* we should only handle left-mouse-button clicks */		if ( ev->button != Button1 )		{			DBG_MSG(1,(stderr,"skip non-left-mouse-button click\n"));			return;		}		DBG_MSG(1,(stderr,"click on button %d\n",but));		switch(but)		{			case 0 : /* right shift */				if (r->tabBar.atab < LTAB(r))					rxvt_activate_page (r, r->tabBar.atab+1);				break;			case 1 : /* left shift */				if (r->tabBar.atab > 0)					rxvt_activate_page (r, r->tabBar.atab-1);				break;			case 2 : /* delete the active vt if it's in primary screen */				if(						!(r->Options2 & Opt2_protectSecondary)						|| ( (r->Options2 & Opt2_protectSecondary)								&& (PRIMARY == AVTS(r)->current_screen) )				  )					rxvt_kill_page (r, ATAB(r));				break;			case 3 : /* create a new vt*/				rxvt_append_page (r, 0, NULL, NULL);				break;			default :				break;		}	}	else if ( x < TAB_SPACE && LTAB(r) >= 0)	{		register int	w = 0;		register int	i;		for ( i = FVTAB(r); w < x && i <= LVTAB(r); i++)			w += TAB_WIDTH(i);		if( w - TAB_BORDER >= x )		{			but = i - 1;			DBG_MSG( 2, ( stderr,"click on tab %d\n", but));			switch( ev->button )			{				case Button1:					/* activate the selected tab */					rxvt_activate_page (r, but);					r->tabClicked = but;					break;				case Button2:					/* change tab title on middle click */					if (NULL != r->selection.text)						rxvt_tabbar_set_title (r, but, r->selection.text);					break;			}		}		else		{			/* change tab title of active tab on middle click */			if ((Button2 == ev->button) && (NULL != r->selection.text))				rxvt_tabbar_set_title (r, ATAB(r), r->selection.text);		}	}}/* * Check if we're dragging a tab. If yes, then move the tab. * * TODO: Set a different cursor when dragging a tab. *//* EXTPROTO */voidrxvt_tabbar_button_release( rxvt_t *r, XButtonEvent *ev){	int		w, droppedTab;	do	/* while( 0 ) */	{		if (				ev->button != Button1				/* Ignore everything except													   left clicks */				|| r->tabClicked == -1				/* If we're not dragging a													   tab then nothing to do */				|| ev->y < 0				|| ev->y > rxvt_tabbar_rheight( r ) /* If we drag off the													   tabbar. (Coordinates in													   ev are relative to the													   tabbar window) */		   )			break;		/* Figure out where the user released the mouse */		for (				droppedTab = FVTAB(r), w=0;				w < ev->x && droppedTab <= LVTAB(r);				droppedTab++			)			w += TAB_WIDTH( droppedTab );		DBG_MSG( 2, ( stderr, "Dragged tab %d to %d (%d, %d)\n",				r->tabClicked, droppedTab - 1, ev->x, ev->y) );		/* Move active tab there */		rxvt_tabbar_move_tab( r, droppedTab - 1 );	} while( 0 );	r->tabClicked = -1;}/* * Is the tabbar visible *//* EXTPROTO */intrxvt_tabbar_visible (rxvt_t* r){	return (None != r->tabBar.win && r->tabBar.state);}/* * Expose handler for tabbar *//* EXTPROTO */voidrxvt_tabbar_expose (rxvt_t* r, XEvent *ev){	Region region = None;	if( ev && ev->type == Expose)	{		region = XCreateRegion();		do		{			XRectangle rect;			rect.x		= ev->xexpose.x;			rect.y		= ev->xexpose.y;			rect.width	= ev->xexpose.width;			rect.height	= ev->xexpose.height;			XUnionRectWithRegion( &rect, region, region);		} while( XCheckTypedWindowEvent( r->Xdisplay, r->tabBar.win,					Expose, ev));	}	else XClearWindow (r->Xdisplay, r->tabBar.win);	/* draw the tabs and blank space*/	rxvt_draw_tabs(r, region);	/* draw the buttons */	rxvt_tabbar_draw_buttons (r);	if( region != None) XDestroyRegion( region );}/* * Hide the tabbar *//* EXTPROTO */intrxvt_tabbar_hide (rxvt_t* r){	int		changed = 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -