Skip to content

Commit

Permalink
expose combined context menu in tab header and add visual context men…
Browse files Browse the repository at this point in the history
…u button - fixes #6966
  • Loading branch information
Eugeny committed Sep 4, 2022
1 parent 3226a3d commit fbea7db
Show file tree
Hide file tree
Showing 8 changed files with 88 additions and 44 deletions.
8 changes: 6 additions & 2 deletions tabby-core/src/components/tabHeader.component.pug
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,17 @@ profile-icon(

.name(
[title]='tab.customTitle || tab.title',
[class.no-hover]='config.store.terminal.hideCloseButton'
[class.no-hover]='config.store.terminal.hideCloseButton && config.store.terminal.hideTabOptionsButton'
cdkDrag,
cdkDragRootElement='tab-header',
[cdkDragData]='tab',
(cdkDragStarted)='onTabDragStart(tab)',
(cdkDragEnded)='onTabDragEnd()',
) {{tab.customTitle || tab.title}}
button(*ngIf='!config.store.terminal.hideCloseButton',(click)='app.closeTab(tab, true)') ×

.buttons
button(*ngIf='!config.store.terminal.hideTabOptionsButton',(click)='onContextMenu($event)') !{require('../icons/tab-options.svg')}

button(*ngIf='!config.store.terminal.hideCloseButton',(click)='app.closeTab(tab, true)') ×

ng-content
50 changes: 29 additions & 21 deletions tabby-core/src/components/tabHeader.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -59,41 +59,49 @@ $tabs-height: 38px;
margin-left: 10px;
}

button {
display: block;
flex: none;
background: transparent;
.buttons {
display: flex;
position: absolute;
align-items: center;
height: 100%;
top: 2px;
right: 3px;
opacity: 0;
-webkit-app-region: no-drag;

position: absolute;
right: 0;
button {
display: flex;
align-items: center;
flex: none;
justify-content: center;

$button-size: 26px;
width: $button-size;
height: $button-size;
border-radius: $button-size / 6;
line-height: $button-size;
align-self: center;
background: transparent;
-webkit-app-region: no-drag;

text-align: center;
font-size: 20px;
$button-size: 26px;
width: $button-size;
height: $button-size;
border-radius: $button-size / 6;
line-height: $button-size;
align-self: center;

text-align: center;
font-size: 20px;

&:focus {
outline: 0;
&:focus {
outline: 0;
}
}
}

&:hover .name:not(.no-hover) {
-webkit-mask-image: linear-gradient(black 0 0), linear-gradient(to left, transparent 0%, black 100%);
-webkit-mask-size: calc(100% - 60px) auto, 60px auto;
-webkit-mask-image: linear-gradient(black 0 0), linear-gradient(to left, transparent 0%, transparent 50%, black 100%);
-webkit-mask-size: calc(100% - 80px) auto, 80px auto;
-webkit-mask-repeat: no-repeat;
-webkit-mask-position: left, right;
}

&:hover button {
&:hover .buttons {
transition: 0.25s opacity;
display: block;
opacity: 1;
}

Expand Down
15 changes: 15 additions & 0 deletions tabby-core/src/components/tabHeader.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { auditTime } from 'rxjs'
import { TabContextMenuItemProvider } from '../api/tabContextMenuProvider'
import { BaseTabComponent } from './baseTab.component'
import { RenameTabModalComponent } from './renameTabModal.component'
import { SplitTabComponent } from './splitTab.component'
import { HotkeysService } from '../services/hotkeys.service'
import { AppService } from '../services/app.service'
import { HostAppService, Platform } from '../api/hostApp'
Expand Down Expand Up @@ -69,10 +70,24 @@ export class TabHeaderComponent extends BaseComponent {

async buildContextMenu (): Promise<MenuItemOptions[]> {
let items: MenuItemOptions[] = []
// Top-level tab menu
for (const section of await Promise.all(this.contextMenuProviders.map(x => x.getItems(this.tab, this)))) {
items.push({ type: 'separator' })
items = items.concat(section)
}
if (this.tab instanceof SplitTabComponent) {
const tab = this.tab.getFocusedTab()
if (tab) {
for (let section of await Promise.all(this.contextMenuProviders.map(x => x.getItems(tab, this)))) {
// eslint-disable-next-line @typescript-eslint/no-loop-func
section = section.filter(item => !items.some(ex => ex.label === item.label))
if (section.length) {
items.push({ type: 'separator' })
items = items.concat(section)
}
}
}
}
return items.slice(1)
}

Expand Down
1 change: 1 addition & 0 deletions tabby-core/src/icons/tab-options.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
40 changes: 19 additions & 21 deletions tabby-core/src/tabContextMenu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export class TabManagementContextMenu extends TabContextMenuItemProvider {
},
},
]
if (tabHeader) {
if (!tab.parent) {
items = [
...items,
{
Expand Down Expand Up @@ -69,24 +69,22 @@ export class TabManagementContextMenu extends TabContextMenuItemProvider {
},
},
]
} else {
if (tab.parent instanceof SplitTabComponent) {
const directions: SplitDirection[] = ['r', 'b', 'l', 't']
items.push({
label: this.translate.instant('Split'),
submenu: directions.map(dir => ({
label: {
r: this.translate.instant('Right'),
b: this.translate.instant('Down'),
l: this.translate.instant('Left'),
t: this.translate.instant('Up'),
}[dir],
click: () => {
(tab.parent as SplitTabComponent).splitTab(tab, dir)
},
})) as MenuItemOptions[],
})
}
} else if (tab.parent instanceof SplitTabComponent) {
const directions: SplitDirection[] = ['r', 'b', 'l', 't']
items.push({
label: this.translate.instant('Split'),
submenu: directions.map(dir => ({
label: {
r: this.translate.instant('Right'),
b: this.translate.instant('Down'),
l: this.translate.instant('Left'),
t: this.translate.instant('Up'),
}[dir],
click: () => {
(tab.parent as SplitTabComponent).splitTab(tab, dir)
},
})) as MenuItemOptions[],
})
}
return items
}
Expand Down Expand Up @@ -273,9 +271,9 @@ export class ProfilesContextMenu extends TabContextMenuItemProvider {
tab.destroy()
}

async getItems (tab: BaseTabComponent, tabHeader?: TabHeaderComponent): Promise<MenuItemOptions[]> {
async getItems (tab: BaseTabComponent): Promise<MenuItemOptions[]> {

if (!tabHeader && tab.parent instanceof SplitTabComponent && tab.parent.getAllTabs().length > 1) {
if (tab.parent instanceof SplitTabComponent && tab.parent.getAllTabs().length > 1) {
return [
{
label: this.translate.instant('Switch profile'),
Expand Down
9 changes: 9 additions & 0 deletions tabby-settings/src/components/windowSettingsTab.component.pug
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,15 @@ h3.mt-4(translate) Tabs
(ngModelChange)='config.save();',
)

.form-line
.header
.title(translate) Hide tab options button

toggle(
[(ngModel)]='config.store.terminal.hideTabOptionsButton',
(ngModelChange)='config.save();',
)

.form-line
.header
.title(translate) Hide tab close button
Expand Down
1 change: 1 addition & 0 deletions tabby-terminal/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export class TerminalConfigProvider extends ConfigProvider {
hideTabIndex: false,
showTabProfileIcon: false,
hideCloseButton: false,
hideTabOptionsButton: false,
rightClick: 'menu',
pasteOnMiddleClick: true,
copyOnSelect: false,
Expand Down
8 changes: 8 additions & 0 deletions tabby-terminal/src/tabContextMenu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,14 @@ export class MiscContextMenu extends TabContextMenuItemProvider {
constructor (private translate: TranslateService) { super() }

async getItems (tab: BaseTabComponent): Promise<MenuItemOptions[]> {
if (tab instanceof BaseTerminalTabComponent && tab.enableToolbar && !tab.pinToolbar) {
return [{
label: this.translate.instant('Show toolbar'),
click: () => {
tab.pinToolbar = true
},
}]
}
if (tab instanceof BaseTerminalTabComponent && tab.session?.supportsWorkingDirectory()) {
return [{
label: this.translate.instant('Copy current path'),
Expand Down

0 comments on commit fbea7db

Please sign in to comment.