2025-02-09 23:09:13 +01:00
/ * *
2025-02-09 23:13:53 +01:00
* V - Shell ( Vertical Workspaces )
2025-02-09 23:09:13 +01:00
* workspacesView . js
2025-02-09 23:13:53 +01:00
*
2025-02-09 23:09:13 +01:00
* @ author GdH < G - dH @ github . com >
* @ copyright 2022 - 2023
* @ license GPL - 3.0
*
* /
'use strict' ;
2025-02-09 23:16:18 +01:00
const Clutter = imports . gi . Clutter ;
const GObject = imports . gi . GObject ;
const Meta = imports . gi . Meta ;
const St = imports . gi . St ;
2025-02-09 23:09:13 +01:00
const Main = imports . ui . main ;
2025-02-09 23:16:18 +01:00
const OverviewControls = imports . ui . overviewControls ;
2025-02-09 23:09:13 +01:00
const WorkspacesView = imports . ui . workspacesView ;
2025-02-09 23:16:18 +01:00
const Util = imports . misc . util ;
2025-02-09 23:09:13 +01:00
2025-02-09 23:16:18 +01:00
let Me ;
2025-02-09 23:09:13 +01:00
let opt ;
2025-02-09 23:16:18 +01:00
const ControlsState = OverviewControls . ControlsState ;
const FitMode = WorkspacesView . FitMode ;
2025-02-09 23:09:13 +01:00
2025-02-09 23:16:18 +01:00
var WorkspacesViewModule = class {
constructor ( me ) {
// first reference to constant defined using const in other module returns undefined, the SecondaryMonitorDisplay const will remain empty and unused
this . dummy = WorkspacesView . SecondaryMonitorDisplay ;
2025-02-09 23:13:53 +01:00
2025-02-09 23:16:18 +01:00
Me = me ;
opt = Me . opt ;
this . _firstActivation = true ;
this . moduleEnabled = false ;
this . _overrides = null ;
2025-02-09 23:09:13 +01:00
}
2025-02-09 23:16:18 +01:00
cleanGlobals ( ) {
Me = null ;
2025-02-09 23:09:13 +01:00
opt = null ;
}
2025-02-09 23:16:18 +01:00
update ( reset ) {
this . moduleEnabled = true ;
const conflict = false ;
reset = reset || ! this . moduleEnabled || conflict ;
// don't touch the original code if module disabled
if ( reset && ! this . _firstActivation ) {
this . _disableModule ( ) ;
} else if ( ! reset ) {
this . _firstActivation = false ;
this . _activateModule ( ) ;
}
if ( reset && this . _firstActivation )
console . debug ( ' WorkspacesViewModule - Keeping untouched' ) ;
}
2025-02-09 23:09:13 +01:00
2025-02-09 23:16:18 +01:00
_activateModule ( ) {
if ( ! this . _overrides )
this . _overrides = new Me . Util . Overrides ( ) ;
2025-02-09 23:09:13 +01:00
2025-02-09 23:16:18 +01:00
const desktopCubeEnabled = Me . Util . getEnabledExtensions ( 'desktop-cube@schneegans.github.com' ) . length ;
const desktopCubeConflict = desktopCubeEnabled && ! opt . ORIENTATION && ! opt . OVERVIEW _MODE ;
2025-02-09 23:13:53 +01:00
2025-02-09 23:16:18 +01:00
if ( ! desktopCubeConflict )
this . _overrides . addOverride ( 'WorkspacesView' , WorkspacesView . WorkspacesView . prototype , WorkspacesViewCommon ) ;
2025-02-09 23:09:13 +01:00
2025-02-09 23:16:18 +01:00
this . _overrides . addOverride ( 'WorkspacesDisplay' , WorkspacesView . WorkspacesDisplay . prototype , WorkspacesDisplayCommon ) ;
this . _overrides . addOverride ( 'ExtraWorkspaceView' , WorkspacesView . ExtraWorkspaceView . prototype , ExtraWorkspaceViewCommon ) ;
this . _overrides . addOverride ( 'SecondaryMonitorDisplayCommon' , WorkspacesView . SecondaryMonitorDisplay . prototype , SecondaryMonitorDisplayCommon ) ;
if ( opt . ORIENTATION ) {
// switch internal workspace orientation in GS
global . workspace _manager . override _workspace _layout ( Meta . DisplayCorner . TOPLEFT , false , - 1 , 1 ) ;
this . _overrides . addOverride ( 'SecondaryMonitorDisplay' , WorkspacesView . SecondaryMonitorDisplay . prototype , SecondaryMonitorDisplayVertical ) ;
} else {
global . workspace _manager . override _workspace _layout ( Meta . DisplayCorner . TOPLEFT , false , 1 , - 1 ) ;
this . _overrides . addOverride ( 'SecondaryMonitorDisplay' , WorkspacesView . SecondaryMonitorDisplay . prototype , SecondaryMonitorDisplayHorizontal ) ;
}
console . debug ( ' WorkspacesViewModule - Activated' ) ;
2025-02-09 23:09:13 +01:00
}
2025-02-09 23:16:18 +01:00
_disableModule ( ) {
global . workspace _manager . override _workspace _layout ( Meta . DisplayCorner . TOPLEFT , false , 1 , - 1 ) ;
if ( this . _overrides )
this . _overrides . removeAll ( ) ;
this . _overrides = null ;
console . debug ( ' WorkspacesViewModule - Disabled' ) ;
}
} ;
2025-02-09 23:09:13 +01:00
2025-02-09 23:13:53 +01:00
const WorkspacesViewCommon = {
_getFirstFitSingleWorkspaceBox ( box , spacing , vertical ) {
2025-02-09 23:09:13 +01:00
let [ width , height ] = box . get _size ( ) ;
const [ workspace ] = this . _workspaces ;
const rtl = this . text _direction === Clutter . TextDirection . RTL ;
const adj = this . _scrollAdjustment ;
const currentWorkspace = vertical || ! rtl
? adj . value : adj . upper - adj . value - 1 ;
// Single fit mode implies centered too
let [ x1 , y1 ] = box . get _origin ( ) ;
2025-02-09 23:13:53 +01:00
const [ , workspaceWidth ] = workspace ? workspace . get _preferred _width ( Math . floor ( height ) ) : [ 0 , width ] ;
const [ , workspaceHeight ] = workspace ? workspace . get _preferred _height ( workspaceWidth ) : [ 0 , height ] ;
2025-02-09 23:09:13 +01:00
if ( vertical ) {
x1 += ( width - workspaceWidth ) / 2 ;
y1 -= currentWorkspace * ( workspaceHeight + spacing ) ;
} else {
x1 += ( width - workspaceWidth ) / 2 ;
x1 -= currentWorkspace * ( workspaceWidth + spacing ) ;
}
2025-02-09 23:13:53 +01:00
const fitSingleBox = new Clutter . ActorBox ( { x1 , y1 } ) ;
2025-02-09 23:09:13 +01:00
fitSingleBox . set _size ( workspaceWidth , workspaceHeight ) ;
return fitSingleBox ;
} ,
// set spacing between ws previews
2025-02-09 23:13:53 +01:00
_getSpacing ( box , fitMode , vertical ) {
2025-02-09 23:09:13 +01:00
const [ width , height ] = box . get _size ( ) ;
const [ workspace ] = this . _workspaces ;
2025-02-09 23:13:53 +01:00
if ( ! workspace )
return 0 ;
2025-02-09 23:09:13 +01:00
let availableSpace ;
let workspaceSize ;
if ( vertical ) {
[ , workspaceSize ] = workspace . get _preferred _height ( width ) ;
availableSpace = height ;
} else {
[ , workspaceSize ] = workspace . get _preferred _width ( height ) ;
availableSpace = width ;
}
const spacing = ( availableSpace - workspaceSize * 0.4 ) * ( 1 - fitMode ) ;
const { scaleFactor } = St . ThemeContext . get _for _stage ( global . stage ) ;
return Math . clamp ( spacing ,
opt . WORKSPACE _MIN _SPACING * scaleFactor ,
opt . WORKSPACE _MAX _SPACING * scaleFactor ) ;
} ,
// this function has duplicate in OverviewControls so we use one function for both to avoid issues with syncing them
2025-02-09 23:13:53 +01:00
_getFitModeForState ( state ) {
2025-02-09 23:09:13 +01:00
return _getFitModeForState ( state ) ;
} ,
// normal view 0, spread windows 1
2025-02-09 23:13:53 +01:00
_getWorkspaceModeForOverviewState ( state ) {
2025-02-09 23:09:13 +01:00
switch ( state ) {
case ControlsState . HIDDEN :
return 0 ;
case ControlsState . WINDOW _PICKER :
return opt . WORKSPACE _MODE ;
case ControlsState . APP _GRID :
2025-02-09 23:13:53 +01:00
return ( this . _monitorIndex !== global . display . get _primary _monitor ( ) || ! opt . WS _ANIMATION ) && ! opt . OVERVIEW _MODE ? 1 : 0 ;
2025-02-09 23:09:13 +01:00
}
return 0 ;
} ,
2025-02-09 23:13:53 +01:00
_updateVisibility ( ) {
2025-02-09 23:16:18 +01:00
// visibility handles _updateWorkspacesState()
2025-02-09 23:09:13 +01:00
} ,
// disable scaling and hide inactive workspaces
2025-02-09 23:13:53 +01:00
_updateWorkspacesState ( ) {
2025-02-09 23:09:13 +01:00
const adj = this . _scrollAdjustment ;
const fitMode = this . _fitModeAdjustment . value ;
let { initialState , finalState , progress , currentState } =
this . _overviewAdjustment . getStateTransitionParams ( ) ;
const workspaceMode = ( 1 - fitMode ) * Util . lerp (
this . _getWorkspaceModeForOverviewState ( initialState ) ,
this . _getWorkspaceModeForOverviewState ( finalState ) ,
progress ) ;
2025-02-09 23:13:53 +01:00
const primaryMonitor = Main . layoutManager . primaryMonitor . index ;
2025-02-09 23:09:13 +01:00
2025-02-09 23:13:53 +01:00
const wsScrollProgress = adj . value % 1 ;
2025-02-09 23:09:13 +01:00
const secondaryMonitor = this . _monitorIndex !== global . display . get _primary _monitor ( ) ;
2025-02-09 23:13:53 +01:00
const blockSecondaryAppGrid = opt . OVERVIEW _MODE && currentState > 1 ;
2025-02-09 23:16:18 +01:00
2025-02-09 23:09:13 +01:00
// Hide inactive workspaces
this . _workspaces . forEach ( ( w , index ) => {
if ( ! ( blockSecondaryAppGrid && secondaryMonitor ) )
w . stateAdjustment . value = workspaceMode ;
2025-02-09 23:16:18 +01:00
let distance = adj . value - index ;
const distanceToCurrentWorkspace = Math . abs ( distance ) ;
2025-02-09 23:09:13 +01:00
const scaleProgress = 1 - Math . clamp ( distanceToCurrentWorkspace , 0 , 1 ) ;
2025-02-09 23:16:18 +01:00
// const scale = Util.lerp(0.94, 1, scaleProgress);
// w.set_scale(scale, scale);
2025-02-09 23:09:13 +01:00
// if we disable workspaces that we can't or don't need to see, transition animations will be noticeably smoother
// only the current ws needs to be visible during overview transition animations
// and only current and adjacent ws when switching ws
2025-02-09 23:13:53 +01:00
w . visible = ( this . _animating && wsScrollProgress && distanceToCurrentWorkspace <= ( opt . NUMBER _OF _VISIBLE _NEIGHBORS + 1 ) ) || scaleProgress === 1 ||
( opt . WORKSPACE _MAX _SPACING > 340 && distanceToCurrentWorkspace <= opt . NUMBER _OF _VISIBLE _NEIGHBORS && currentState === ControlsState . WINDOW _PICKER ) ||
( this . _monitorIndex !== primaryMonitor && distanceToCurrentWorkspace <= opt . NUMBER _OF _VISIBLE _NEIGHBORS ) || ( ! opt . WS _ANIMATION && distanceToCurrentWorkspace < opt . NUMBER _OF _VISIBLE _NEIGHBORS ) ||
( opt . WORKSPACE _MAX _SPACING < 340 && distanceToCurrentWorkspace <= opt . NUMBER _OF _VISIBLE _NEIGHBORS && currentState <= ControlsState . WINDOW _PICKER &&
( ( initialState < ControlsState . APP _GRID && finalState < ControlsState . APP _GRID ) )
) ;
// after transition from APP_GRID to WINDOW_PICKER state,
// adjacent workspaces are hidden and we need them to show up
// make them visible during animation can impact smoothness of the animation
2025-02-09 23:16:18 +01:00
// so we show them after the animation finished, move them to their position from outside of the monitor
2025-02-09 23:13:53 +01:00
if ( ! w . visible && distanceToCurrentWorkspace === 1 && initialState === ControlsState . APP _GRID && currentState === ControlsState . WINDOW _PICKER ) {
w . visible = true ;
2025-02-09 23:16:18 +01:00
const directionNext = distance > 0 ;
if ( ! opt . ORIENTATION ) {
const width = w . width * 0.6 * opt . WS _PREVIEW _SCALE ;
w . translation _x = directionNext ? - width : width ;
}
if ( opt . ORIENTATION ) {
const height = w . height * 0.6 * opt . WS _PREVIEW _SCALE ;
w . translation _y = directionNext ? - height : height ;
}
w . opacity = 10 ;
w . get _parent ( ) . set _child _below _sibling ( w , null ) ;
2025-02-09 23:13:53 +01:00
w . ease ( {
2025-02-09 23:16:18 +01:00
duration : 300 ,
translation _x : 0 ,
translation _y : 0 ,
opacity : 255 ,
2025-02-09 23:13:53 +01:00
mode : Clutter . AnimationMode . EASE _OUT _QUAD ,
} ) ;
2025-02-09 23:09:13 +01:00
}
// force ws preview bg corner radiuses where GS doesn't do it
2025-02-09 23:13:53 +01:00
if ( opt . SHOW _WS _PREVIEW _BG && opt . OVERVIEW _MODE === 1 && distanceToCurrentWorkspace < 2 )
2025-02-09 23:09:13 +01:00
w . _background . _updateBorderRadius ( Math . min ( 1 , w . _overviewAdjustment . value ) ) ;
2025-02-09 23:13:53 +01:00
2025-02-09 23:09:13 +01:00
// hide workspace background
2025-02-09 23:13:53 +01:00
if ( ! opt . SHOW _WS _PREVIEW _BG && w . _background . opacity )
2025-02-09 23:09:13 +01:00
w . _background . opacity = 0 ;
} ) ;
2025-02-09 23:13:53 +01:00
} ,
2025-02-09 23:16:18 +01:00
exposeWindows ( workspaceIndex = null , callback ) {
let adjustments = [ ] ;
if ( workspaceIndex === null ) {
this . _workspaces . forEach ( ws => {
adjustments . push ( ws . _background . _stateAdjustment ) ;
} ) ;
} else {
adjustments . push ( this . _workspaces [ workspaceIndex ] . _background . _stateAdjustment ) ;
}
adjustments . forEach ( adj => {
if ( adj . value === 0 ) {
adj . value = 0 ;
adj . ease ( 1 , {
duration : 200 ,
mode : Clutter . AnimationMode . EASE _OUT _QUAD ,
onComplete : ( ) => {
opt . WORKSPACE _MODE = 1 ;
if ( callback )
callback ( ) ;
} ,
} ) ;
}
} ) ;
} ,
} ;
const SecondaryMonitorDisplayCommon = {
exposeWindows ( ... args ) {
this . _workspacesView . exposeWindows ( ... args ) ;
} ,
2025-02-09 23:13:53 +01:00
} ;
2025-02-09 23:09:13 +01:00
2025-02-09 23:13:53 +01:00
const SecondaryMonitorDisplayVertical = {
_getThumbnailParamsForState ( state ) {
2025-02-09 23:09:13 +01:00
2025-02-09 23:13:53 +01:00
let opacity , scale , translationX ;
2025-02-09 23:09:13 +01:00
switch ( state ) {
case ControlsState . HIDDEN :
opacity = 255 ;
scale = 1 ;
2025-02-09 23:13:53 +01:00
translationX = 0 ;
if ( ! Main . layoutManager . _startingUp && ( ! opt . SHOW _WS _PREVIEW _BG || opt . OVERVIEW _MODE2 ) )
translationX = this . _thumbnails . width * ( opt . SEC _WS _TMB _LEFT ? - 1 : 1 ) ;
2025-02-09 23:09:13 +01:00
break ;
case ControlsState . WINDOW _PICKER :
case ControlsState . APP _GRID :
opacity = 255 ;
scale = 1 ;
2025-02-09 23:13:53 +01:00
translationX = 0 ;
2025-02-09 23:09:13 +01:00
break ;
default :
opacity = 255 ;
scale = 1 ;
2025-02-09 23:13:53 +01:00
translationX = 0 ;
2025-02-09 23:09:13 +01:00
break ;
}
2025-02-09 23:13:53 +01:00
return { opacity , scale , translationX } ;
2025-02-09 23:09:13 +01:00
} ,
2025-02-09 23:13:53 +01:00
_getWorkspacesBoxForState ( state , box , padding , thumbnailsWidth , spacing ) {
// const { ControlsState } = OverviewControls;
2025-02-09 23:09:13 +01:00
const workspaceBox = box . copy ( ) ;
const [ width , height ] = workspaceBox . get _size ( ) ;
2025-02-09 23:13:53 +01:00
let wWidth , wHeight , wsbX , wsbY , offset , yShift ;
2025-02-09 23:09:13 +01:00
switch ( state ) {
case ControlsState . HIDDEN :
break ;
case ControlsState . WINDOW _PICKER :
case ControlsState . APP _GRID :
2025-02-09 23:13:53 +01:00
if ( opt . OVERVIEW _MODE2 && ! opt . WORKSPACE _MODE )
2025-02-09 23:09:13 +01:00
break ;
2025-02-09 23:13:53 +01:00
yShift = 0 ;
2025-02-09 23:16:18 +01:00
if ( opt . SEC _WS _PREVIEW _SHIFT && Main . panel . visible ) {
2025-02-09 23:13:53 +01:00
if ( opt . PANEL _POSITION _TOP )
yShift = Main . panel . height ;
else
yShift = - Main . panel . height ;
2025-02-09 23:09:13 +01:00
}
2025-02-09 23:13:53 +01:00
wWidth = width - thumbnailsWidth - 5 * spacing ;
wHeight = Math . min ( wWidth / ( width / height ) - Math . abs ( yShift ) , height - 4 * spacing ) ;
wWidth = Math . round ( wWidth * opt . SEC _WS _PREVIEW _SCALE ) ;
wHeight = Math . round ( wHeight * opt . SEC _WS _PREVIEW _SCALE ) ;
2025-02-09 23:09:13 +01:00
2025-02-09 23:13:53 +01:00
offset = Math . round ( width - thumbnailsWidth - wWidth ) / 2 ;
if ( opt . SEC _WS _TMB _LEFT )
2025-02-09 23:09:13 +01:00
wsbX = thumbnailsWidth + offset ;
2025-02-09 23:13:53 +01:00
else
2025-02-09 23:09:13 +01:00
wsbX = offset ;
2025-02-09 23:13:53 +01:00
wsbY = Math . round ( ( height - wHeight - Math . abs ( yShift ) ) / 2 + yShift ) ;
2025-02-09 23:09:13 +01:00
workspaceBox . set _origin ( wsbX , wsbY ) ;
workspaceBox . set _size ( wWidth , wHeight ) ;
break ;
}
return workspaceBox ;
} ,
2025-02-09 23:13:53 +01:00
vfunc _allocate ( box ) {
2025-02-09 23:09:13 +01:00
this . set _allocation ( box ) ;
const themeNode = this . get _theme _node ( ) ;
const contentBox = themeNode . get _content _box ( box ) ;
const [ width , height ] = contentBox . get _size ( ) ;
const { expandFraction } = this . _thumbnails ;
const spacing = themeNode . get _length ( 'spacing' ) * expandFraction ;
const padding = Math . round ( 0.1 * height ) ;
2025-02-09 23:16:18 +01:00
let thumbnailsWidth = 0 ;
let thumbnailsHeight = 0 ;
2025-02-09 23:13:53 +01:00
this . _thumbnails . visible = ! opt . SEC _WS _TMB _HIDDEN ;
2025-02-09 23:09:13 +01:00
if ( this . _thumbnails . visible ) {
2025-02-09 23:16:18 +01:00
const reduceBoxHeight = opt . SEC _WS _PREVIEW _SHIFT && Main . panel . visible ? Main . panel . height : 0 ;
thumbnailsWidth = width * opt . SEC _MAX _THUMBNAIL _SCALE ;
let totalTmbSpacing ;
[ totalTmbSpacing , thumbnailsHeight ] = this . _thumbnails . get _preferred _height ( thumbnailsWidth ) ;
thumbnailsHeight = Math . round ( thumbnailsHeight + totalTmbSpacing ) ;
const thumbnailsHeightMax = height - spacing - reduceBoxHeight ;
if ( thumbnailsHeight > thumbnailsHeightMax ) {
thumbnailsHeight = thumbnailsHeightMax ;
thumbnailsWidth = Math . round ( this . _thumbnails . get _preferred _width ( thumbnailsHeight ) [ 1 ] ) ;
}
2025-02-09 23:09:13 +01:00
let wsTmbX ;
if ( opt . SEC _WS _TMB _LEFT ) { // left
2025-02-09 23:16:18 +01:00
wsTmbX = spacing / 2 ;
2025-02-09 23:09:13 +01:00
this . _thumbnails . _positionLeft = true ;
} else {
2025-02-09 23:16:18 +01:00
wsTmbX = width - spacing / 2 - thumbnailsWidth ;
2025-02-09 23:09:13 +01:00
this . _thumbnails . _positionLeft = false ;
}
const childBox = new Clutter . ActorBox ( ) ;
2025-02-09 23:16:18 +01:00
const availSpace = height - thumbnailsHeight ;
2025-02-09 23:09:13 +01:00
let wsTmbY = availSpace / 2 ;
2025-02-09 23:16:18 +01:00
wsTmbY -= opt . SEC _WS _TMB _POSITION _ADJUSTMENT * wsTmbY ;
wsTmbY += opt . SEC _WS _PREVIEW _SHIFT && Main . panel . visible ? Main . panel . height : 0 ;
2025-02-09 23:09:13 +01:00
childBox . set _origin ( Math . round ( wsTmbX ) , Math . round ( wsTmbY ) ) ;
childBox . set _size ( thumbnailsWidth , thumbnailsHeight ) ;
this . _thumbnails . allocate ( childBox ) ;
}
const {
currentState , initialState , finalState , transitioning , progress ,
} = this . _overviewAdjustment . getStateTransitionParams ( ) ;
let workspacesBox ;
const workspaceParams = [ contentBox , padding , thumbnailsWidth , spacing ] ;
if ( ! transitioning ) {
workspacesBox =
this . _getWorkspacesBoxForState ( currentState , ... workspaceParams ) ;
} else {
const initialBox =
this . _getWorkspacesBoxForState ( initialState , ... workspaceParams ) ;
const finalBox =
this . _getWorkspacesBoxForState ( finalState , ... workspaceParams ) ;
workspacesBox = initialBox . interpolate ( finalBox , progress ) ;
}
this . _workspacesView . allocate ( workspacesBox ) ;
} ,
2025-02-09 23:13:53 +01:00
_updateThumbnailVisibility ( ) {
if ( opt . OVERVIEW _MODE2 )
2025-02-09 23:09:13 +01:00
this . set _child _above _sibling ( this . _thumbnails , null ) ;
2025-02-09 23:13:53 +01:00
const visible = ! opt . SEC _WS _TMB _HIDDEN ;
2025-02-09 23:09:13 +01:00
if ( this . _thumbnails . visible === visible )
return ;
this . _thumbnails . show ( ) ;
2025-02-09 23:16:18 +01:00
this . _thumbnails . visible = visible ;
2025-02-09 23:09:13 +01:00
this . _updateThumbnailParams ( ) ;
} ,
2025-02-09 23:13:53 +01:00
_updateThumbnailParams ( ) {
if ( opt . SEC _WS _TMB _HIDDEN )
return ;
2025-02-09 23:09:13 +01:00
// workaround for upstream bug - secondary thumbnails boxes don't catch 'showing' signal on the shell startup and don't populate the box with thumbnails
// the tmbBox contents is also destroyed when overview state adjustment gets above 1 when swiping gesture from window picker to app grid
2025-02-09 23:13:53 +01:00
if ( ! this . _thumbnails . _thumbnails . length )
2025-02-09 23:09:13 +01:00
this . _thumbnails . _createThumbnails ( ) ;
const { initialState , finalState , progress } =
this . _overviewAdjustment . getStateTransitionParams ( ) ;
const initialParams = this . _getThumbnailParamsForState ( initialState ) ;
const finalParams = this . _getThumbnailParamsForState ( finalState ) ;
2025-02-09 23:13:53 +01:00
/ * c o n s t o p a c i t y =
2025-02-09 23:09:13 +01:00
Util . lerp ( initialParams . opacity , finalParams . opacity , progress ) ;
const scale =
Util . lerp ( initialParams . scale , finalParams . scale , progress ) ; * /
// OVERVIEW_MODE 2 should animate dash and wsTmbBox only if WORKSPACE_MODE === 0 (windows not spread)
const animateOverviewMode2 = opt . OVERVIEW _MODE2 && ! ( finalState === 1 && opt . WORKSPACE _MODE ) ;
2025-02-09 23:13:53 +01:00
const translationX = ! Main . layoutManager . _startingUp && ( ( ! opt . SHOW _WS _PREVIEW _BG && ! opt . OVERVIEW _MODE2 ) || animateOverviewMode2 )
? Util . lerp ( initialParams . translationX , finalParams . translationX , progress )
2025-02-09 23:09:13 +01:00
: 0 ;
this . _thumbnails . set ( {
opacity : 255 ,
2025-02-09 23:13:53 +01:00
// scale_x: scale,
// scale_y: scale,
translation _x : translationX ,
2025-02-09 23:09:13 +01:00
} ) ;
} ,
2025-02-09 23:13:53 +01:00
_updateWorkspacesView ( ) {
2025-02-09 23:09:13 +01:00
if ( this . _workspacesView )
this . _workspacesView . destroy ( ) ;
if ( this . _settings . get _boolean ( 'workspaces-only-on-primary' ) ) {
2025-02-09 23:13:53 +01:00
opt . SEC _WS _TMB _HIDDEN = true ;
2025-02-09 23:09:13 +01:00
this . _workspacesView = new WorkspacesView . ExtraWorkspaceView (
this . _monitorIndex ,
this . _overviewAdjustment ) ;
} else {
2025-02-09 23:13:53 +01:00
opt . SEC _WS _TMB _HIDDEN = ! opt . SHOW _SEC _WS _TMB ;
2025-02-09 23:09:13 +01:00
this . _workspacesView = new WorkspacesView . WorkspacesView (
this . _monitorIndex ,
this . _controls ,
this . _scrollAdjustment ,
// Secondary monitors don't need FitMode.ALL since there is workspace switcher always visible
2025-02-09 23:13:53 +01:00
// this._fitModeAdjustment,
2025-02-09 23:09:13 +01:00
new St . Adjustment ( {
actor : this ,
2025-02-09 23:13:53 +01:00
value : 0 , // FitMode.SINGLE,
lower : 0 , // FitMode.SINGLE,
upper : 0 , // FitMode.SINGLE,
2025-02-09 23:09:13 +01:00
} ) ,
2025-02-09 23:13:53 +01:00
// secondaryOverviewAdjustment);
2025-02-09 23:09:13 +01:00
this . _overviewAdjustment ) ;
}
this . add _child ( this . _workspacesView ) ;
this . _thumbnails . opacity = 0 ;
2025-02-09 23:13:53 +01:00
} ,
} ;
2025-02-09 23:09:13 +01:00
2025-02-09 23:13:53 +01:00
const SecondaryMonitorDisplayHorizontal = {
_getThumbnailParamsForState ( state ) {
// const { ControlsState } = OverviewControls;
2025-02-09 23:09:13 +01:00
2025-02-09 23:13:53 +01:00
let opacity , scale , translationY ;
2025-02-09 23:09:13 +01:00
switch ( state ) {
case ControlsState . HIDDEN :
opacity = 255 ;
scale = 1 ;
2025-02-09 23:13:53 +01:00
translationY = 0 ;
if ( ! Main . layoutManager . _startingUp && ( ! opt . SHOW _WS _PREVIEW _BG || opt . OVERVIEW _MODE2 ) )
translationY = this . _thumbnails . height * ( opt . SEC _WS _TMB _TOP ? - 1 : 1 ) ;
2025-02-09 23:09:13 +01:00
break ;
case ControlsState . WINDOW _PICKER :
case ControlsState . APP _GRID :
opacity = 255 ;
scale = 1 ;
2025-02-09 23:13:53 +01:00
translationY = 0 ;
2025-02-09 23:09:13 +01:00
break ;
default :
opacity = 255 ;
scale = 1 ;
2025-02-09 23:13:53 +01:00
translationY = 0 ;
2025-02-09 23:09:13 +01:00
break ;
}
2025-02-09 23:13:53 +01:00
return { opacity , scale , translationY } ;
2025-02-09 23:09:13 +01:00
} ,
2025-02-09 23:13:53 +01:00
_getWorkspacesBoxForState ( state , box , padding , thumbnailsHeight , spacing ) {
// const { ControlsState } = OverviewControls;
2025-02-09 23:09:13 +01:00
const workspaceBox = box . copy ( ) ;
const [ width , height ] = workspaceBox . get _size ( ) ;
2025-02-09 23:13:53 +01:00
let wWidth , wHeight , wsbX , wsbY , offset , yShift ;
2025-02-09 23:09:13 +01:00
switch ( state ) {
case ControlsState . HIDDEN :
break ;
case ControlsState . WINDOW _PICKER :
case ControlsState . APP _GRID :
2025-02-09 23:13:53 +01:00
if ( opt . OVERVIEW _MODE2 && ! opt . WORKSPACE _MODE )
2025-02-09 23:09:13 +01:00
break ;
2025-02-09 23:13:53 +01:00
yShift = 0 ;
2025-02-09 23:16:18 +01:00
if ( opt . SEC _WS _PREVIEW _SHIFT && Main . panel . visible ) {
2025-02-09 23:13:53 +01:00
if ( opt . PANEL _POSITION _TOP )
yShift = Main . panel . height ;
else
yShift = - Main . panel . height ;
2025-02-09 23:09:13 +01:00
}
2025-02-09 23:13:53 +01:00
wHeight = height - Math . abs ( yShift ) - ( thumbnailsHeight ? thumbnailsHeight + 4 * spacing : padding ) ;
wWidth = Math . min ( wHeight * ( width / height ) , width - 5 * spacing ) ;
wWidth = Math . round ( wWidth * opt . SEC _WS _PREVIEW _SCALE ) ;
wHeight = Math . round ( wHeight * opt . SEC _WS _PREVIEW _SCALE ) ;
2025-02-09 23:09:13 +01:00
2025-02-09 23:13:53 +01:00
offset = Math . round ( ( height - thumbnailsHeight - wHeight - Math . abs ( yShift ) ) / 2 ) ;
if ( opt . SEC _WS _TMB _TOP )
2025-02-09 23:09:13 +01:00
wsbY = thumbnailsHeight + offset ;
2025-02-09 23:13:53 +01:00
else
2025-02-09 23:09:13 +01:00
wsbY = offset ;
2025-02-09 23:13:53 +01:00
wsbY += yShift ;
wsbX = Math . round ( ( width - wWidth ) / 2 ) ;
2025-02-09 23:09:13 +01:00
workspaceBox . set _origin ( wsbX , wsbY ) ;
workspaceBox . set _size ( wWidth , wHeight ) ;
break ;
}
return workspaceBox ;
} ,
2025-02-09 23:13:53 +01:00
_getThumbnailsHeight ( box ) {
if ( opt . SEC _WS _TMB _HIDDEN )
2025-02-09 23:09:13 +01:00
return 0 ;
const [ width , height ] = box . get _size ( ) ;
const { expandFraction } = this . _thumbnails ;
const [ thumbnailsHeight ] = this . _thumbnails . get _preferred _height ( width ) ;
return Math . min (
thumbnailsHeight * expandFraction ,
2025-02-09 23:13:53 +01:00
height * opt . SEC _MAX _THUMBNAIL _SCALE ) ;
2025-02-09 23:09:13 +01:00
} ,
2025-02-09 23:13:53 +01:00
vfunc _allocate ( box ) {
2025-02-09 23:09:13 +01:00
this . set _allocation ( box ) ;
const themeNode = this . get _theme _node ( ) ;
const contentBox = themeNode . get _content _box ( box ) ;
const [ width , height ] = contentBox . get _size ( ) ;
const { expandFraction } = this . _thumbnails ;
const spacing = themeNode . get _length ( 'spacing' ) * expandFraction ;
const padding = Math . round ( 0.1 * height ) ;
2025-02-09 23:16:18 +01:00
let thumbnailsWidth = 0 ;
let thumbnailsHeight = 0 ;
2025-02-09 23:13:53 +01:00
this . _thumbnails . visible = ! opt . SEC _WS _TMB _HIDDEN ;
2025-02-09 23:09:13 +01:00
if ( this . _thumbnails . visible ) {
2025-02-09 23:16:18 +01:00
const reservedHeight = opt . SEC _WS _PREVIEW _SHIFT && Main . panel . visible ? Main . panel . height : 0 ;
thumbnailsHeight = height * opt . SEC _MAX _THUMBNAIL _SCALE ;
let totalTmbSpacing ;
[ totalTmbSpacing , thumbnailsWidth ] = this . _thumbnails . get _preferred _width ( thumbnailsHeight ) ;
thumbnailsWidth = Math . round ( thumbnailsWidth + totalTmbSpacing ) ;
const thumbnailsWidthMax = width - spacing ;
if ( thumbnailsWidth > thumbnailsWidthMax ) {
thumbnailsWidth = thumbnailsWidthMax ;
thumbnailsHeight = Math . round ( this . _thumbnails . get _preferred _height ( thumbnailsWidth ) [ 1 ] ) ;
}
2025-02-09 23:09:13 +01:00
let wsTmbY ;
2025-02-09 23:13:53 +01:00
if ( opt . SEC _WS _TMB _TOP )
2025-02-09 23:16:18 +01:00
wsTmbY = spacing / 2 + reservedHeight ;
2025-02-09 23:13:53 +01:00
else
2025-02-09 23:16:18 +01:00
wsTmbY = height - spacing / 2 - thumbnailsHeight ;
2025-02-09 23:09:13 +01:00
const childBox = new Clutter . ActorBox ( ) ;
2025-02-09 23:16:18 +01:00
const availSpace = width - thumbnailsWidth ;
2025-02-09 23:09:13 +01:00
let wsTmbX = availSpace / 2 ;
2025-02-09 23:16:18 +01:00
wsTmbX -= opt . SEC _WS _TMB _POSITION _ADJUSTMENT * wsTmbX ;
2025-02-09 23:09:13 +01:00
childBox . set _origin ( Math . round ( wsTmbX ) , Math . round ( wsTmbY ) ) ;
childBox . set _size ( thumbnailsWidth , thumbnailsHeight ) ;
this . _thumbnails . allocate ( childBox ) ;
}
const {
currentState , initialState , finalState , transitioning , progress ,
} = this . _overviewAdjustment . getStateTransitionParams ( ) ;
let workspacesBox ;
const workspaceParams = [ contentBox , padding , thumbnailsHeight , spacing ] ;
if ( ! transitioning ) {
workspacesBox =
this . _getWorkspacesBoxForState ( currentState , ... workspaceParams ) ;
} else {
const initialBox =
this . _getWorkspacesBoxForState ( initialState , ... workspaceParams ) ;
const finalBox =
this . _getWorkspacesBoxForState ( finalState , ... workspaceParams ) ;
workspacesBox = initialBox . interpolate ( finalBox , progress ) ;
}
this . _workspacesView . allocate ( workspacesBox ) ;
} ,
_updateThumbnailVisibility : SecondaryMonitorDisplayVertical . _updateThumbnailVisibility ,
2025-02-09 23:13:53 +01:00
_updateThumbnailParams ( ) {
if ( opt . SEC _WS _TMB _HIDDEN )
return ;
2025-02-09 23:09:13 +01:00
// workaround for upstream bug - secondary thumbnails boxes don't catch 'showing' signal on the shell startup and don't populate the box with thumbnails
// the tmbBox contents is also destroyed when overview state adjustment gets above 1 when swiping gesture from window picker to app grid
2025-02-09 23:13:53 +01:00
if ( ! this . _thumbnails . _thumbnails . length )
2025-02-09 23:09:13 +01:00
this . _thumbnails . _createThumbnails ( ) ;
const { initialState , finalState , progress } =
this . _overviewAdjustment . getStateTransitionParams ( ) ;
const initialParams = this . _getThumbnailParamsForState ( initialState ) ;
const finalParams = this . _getThumbnailParamsForState ( finalState ) ;
2025-02-09 23:13:53 +01:00
/ * c o n s t o p a c i t y =
2025-02-09 23:09:13 +01:00
Util . lerp ( initialParams . opacity , finalParams . opacity , progress ) ;
const scale =
Util . lerp ( initialParams . scale , finalParams . scale , progress ) ; * /
// OVERVIEW_MODE 2 should animate dash and wsTmbBox only if WORKSPACE_MODE === 0 (windows not spread)
const animateOverviewMode2 = opt . OVERVIEW _MODE2 && ! ( finalState === 1 && opt . WORKSPACE _MODE ) ;
2025-02-09 23:13:53 +01:00
const translationY = ! Main . layoutManager . _startingUp && ( ( ! opt . SHOW _WS _PREVIEW _BG && ! opt . OVERVIEW _MODE2 ) || animateOverviewMode2 )
? Util . lerp ( initialParams . translationY , finalParams . translationY , progress )
2025-02-09 23:09:13 +01:00
: 0 ;
this . _thumbnails . set ( {
opacity : 255 ,
2025-02-09 23:13:53 +01:00
// scale_x: scale,
// scale_y: scale,
translation _y : translationY ,
2025-02-09 23:09:13 +01:00
} ) ;
} ,
2025-02-09 23:13:53 +01:00
_updateWorkspacesView ( ) {
2025-02-09 23:09:13 +01:00
if ( this . _workspacesView )
this . _workspacesView . destroy ( ) ;
if ( this . _settings . get _boolean ( 'workspaces-only-on-primary' ) ) {
2025-02-09 23:13:53 +01:00
opt . SEC _WS _TMB _HIDDEN = true ;
2025-02-09 23:09:13 +01:00
this . _workspacesView = new WorkspacesView . ExtraWorkspaceView (
this . _monitorIndex ,
this . _overviewAdjustment ) ;
} else {
2025-02-09 23:13:53 +01:00
opt . SEC _WS _TMB _HIDDEN = ! opt . SHOW _SEC _WS _TMB ;
2025-02-09 23:09:13 +01:00
this . _workspacesView = new WorkspacesView . WorkspacesView (
this . _monitorIndex ,
this . _controls ,
this . _scrollAdjustment ,
// Secondary monitors don't need FitMode.ALL since there is workspace switcher always visible
2025-02-09 23:13:53 +01:00
// this._fitModeAdjustment,
2025-02-09 23:09:13 +01:00
new St . Adjustment ( {
actor : this ,
2025-02-09 23:13:53 +01:00
value : 0 , // FitMode.SINGLE,
lower : 0 , // FitMode.SINGLE,
upper : 0 , // FitMode.SINGLE,
2025-02-09 23:09:13 +01:00
} ) ,
2025-02-09 23:13:53 +01:00
// secondaryOverviewAdjustment);
2025-02-09 23:09:13 +01:00
this . _overviewAdjustment ) ;
}
this . add _child ( this . _workspacesView ) ;
this . _thumbnails . opacity = 0 ;
2025-02-09 23:13:53 +01:00
} ,
} ;
2025-02-09 23:16:18 +01:00
const ExtraWorkspaceViewCommon = {
2025-02-09 23:13:53 +01:00
_updateWorkspaceMode ( ) {
const overviewState = this . _overviewAdjustment . value ;
2025-02-09 23:09:13 +01:00
2025-02-09 23:13:53 +01:00
const progress = Math . clamp ( overviewState ,
ControlsState . HIDDEN ,
opt . OVERVIEW _MODE && ! opt . WORKSPACE _MODE ? ControlsState . HIDDEN : ControlsState . WINDOW _PICKER ) ;
this . _workspace . stateAdjustment . value = progress ;
// force ws preview bg corner radiuses where GS doesn't do it
if ( opt . SHOW _WS _PREVIEW _BG && opt . OVERVIEW _MODE === 1 )
this . _workspace . _background . _updateBorderRadius ( Math . min ( 1 , this . _workspace . _overviewAdjustment . value ) ) ;
// hide workspace background
if ( ! opt . SHOW _WS _PREVIEW _BG && this . _workspace . _background . opacity )
this . _workspace . _background . opacity = 0 ;
} ,
2025-02-09 23:16:18 +01:00
exposeWindows ( ) {
const adjustment = this . _workspace . _background . _stateAdjustment ;
if ( adjustment . value === 0 ) {
adjustment . value = 0 ;
adjustment . ease ( 1 , {
duration : 200 ,
mode : Clutter . AnimationMode . EASE _OUT _QUAD ,
onComplete : ( ) => {
opt . WORKSPACE _MODE = 1 ;
} ,
} ) ;
}
} ,
2025-02-09 23:13:53 +01:00
} ;
2025-02-09 23:16:18 +01:00
const WorkspacesDisplayCommon = {
2025-02-09 23:13:53 +01:00
_updateWorkspacesViews ( ) {
2025-02-09 23:09:13 +01:00
for ( let i = 0 ; i < this . _workspacesViews . length ; i ++ )
this . _workspacesViews [ i ] . destroy ( ) ;
this . _primaryIndex = Main . layoutManager . primaryIndex ;
this . _workspacesViews = [ ] ;
let monitors = Main . layoutManager . monitors ;
for ( let i = 0 ; i < monitors . length ; i ++ ) {
let view ;
if ( i === this . _primaryIndex ) {
view = new WorkspacesView . WorkspacesView ( i ,
this . _controls ,
this . _scrollAdjustment ,
this . _fitModeAdjustment ,
this . _overviewAdjustment ) ;
view . visible = this . _primaryVisible ;
this . bind _property ( 'opacity' , view , 'opacity' , GObject . BindingFlags . SYNC _CREATE ) ;
this . add _child ( view ) ;
} else {
view = new WorkspacesView . SecondaryMonitorDisplay ( i ,
this . _controls ,
this . _scrollAdjustment ,
// Secondary monitors don't need FitMode.ALL since there is workspace switcher always visible
2025-02-09 23:13:53 +01:00
// this._fitModeAdjustment,
2025-02-09 23:09:13 +01:00
new St . Adjustment ( {
actor : this ,
2025-02-09 23:13:53 +01:00
value : 0 , // FitMode.SINGLE,
lower : 0 , // FitMode.SINGLE,
upper : 0 , // FitMode.SINGLE,
2025-02-09 23:09:13 +01:00
} ) ,
this . _overviewAdjustment ) ;
Main . layoutManager . overviewGroup . add _actor ( view ) ;
}
this . _workspacesViews . push ( view ) ;
}
} ,
2025-02-09 23:13:53 +01:00
_onScrollEvent ( actor , event ) {
2025-02-09 23:09:13 +01:00
if ( this . _swipeTracker . canHandleScrollEvent ( event ) )
return Clutter . EVENT _PROPAGATE ;
if ( ! this . mapped )
return Clutter . EVENT _PROPAGATE ;
if ( this . _workspacesOnlyOnPrimary &&
2025-02-09 23:13:53 +01:00
this . _getMonitorIndexForEvent ( event ) !== this . _primaryIndex )
2025-02-09 23:09:13 +01:00
return Clutter . EVENT _PROPAGATE ;
2025-02-09 23:13:53 +01:00
if ( opt . PANEL _MODE === 1 ) {
const panelBox = Main . layoutManager . panelBox ;
const [ , y ] = global . get _pointer ( ) ;
if ( y > panelBox . allocation . y1 && y < panelBox . allocation . y2 )
return Clutter . EVENT _STOP ;
}
2025-02-09 23:09:13 +01:00
2025-02-09 23:16:18 +01:00
if ( Me . Util . isShiftPressed ( ) ) {
let direction = Me . Util . getScrollDirection ( event ) ;
2025-02-09 23:13:53 +01:00
if ( direction === null || ( Date . now ( ) - this . _lastScrollTime ) < 150 )
return Clutter . EVENT _STOP ;
this . _lastScrollTime = Date . now ( ) ;
2025-02-09 23:09:13 +01:00
2025-02-09 23:13:53 +01:00
if ( direction === Clutter . ScrollDirection . UP )
2025-02-09 23:09:13 +01:00
direction = - 1 ;
2025-02-09 23:13:53 +01:00
else if ( direction === Clutter . ScrollDirection . DOWN )
2025-02-09 23:09:13 +01:00
direction = 1 ;
2025-02-09 23:13:53 +01:00
else
2025-02-09 23:09:13 +01:00
direction = 0 ;
2025-02-09 23:13:53 +01:00
2025-02-09 23:09:13 +01:00
if ( direction ) {
2025-02-09 23:16:18 +01:00
Me . Util . reorderWorkspace ( direction ) ;
2025-02-09 23:09:13 +01:00
// make all workspaces on primary monitor visible for case the new position is hidden
2025-02-09 23:16:18 +01:00
const primaryMonitorIndex = global . display . get _primary _monitor ( ) ;
Main . overview . _overview . _controls . _workspacesDisplay . _workspacesViews [ primaryMonitorIndex ] . _workspaces . forEach ( w => {
2025-02-09 23:13:53 +01:00
w . visible = true ;
} ) ;
2025-02-09 23:09:13 +01:00
return Clutter . EVENT _STOP ;
}
}
return Main . wm . handleWorkspaceScroll ( event ) ;
} ,
2025-02-09 23:13:53 +01:00
_onKeyPressEvent ( actor , event ) {
2025-02-09 23:09:13 +01:00
const symbol = event . get _key _symbol ( ) ;
2025-02-09 23:13:53 +01:00
/ * c o n s t { C o n t r o l s S t a t e } = O v e r v i e w C o n t r o l s ;
2025-02-09 23:09:13 +01:00
if ( this . _overviewAdjustment . value !== ControlsState . WINDOW _PICKER && symbol !== Clutter . KEY _space )
return Clutter . EVENT _PROPAGATE ; * /
2025-02-09 23:13:53 +01:00
/ * i f ( ! t h i s . r e a c t i v e )
return Clutter . EVENT _PROPAGATE ; * /
2025-02-09 23:09:13 +01:00
const { workspaceManager } = global ;
const vertical = workspaceManager . layout _rows === - 1 ;
const rtl = this . get _text _direction ( ) === Clutter . TextDirection . RTL ;
2025-02-09 23:13:53 +01:00
const state = this . _overviewAdjustment . value ;
2025-02-09 23:09:13 +01:00
let which ;
switch ( symbol ) {
2025-02-09 23:13:53 +01:00
case Clutter . KEY _Return :
case Clutter . KEY _KP _Enter :
2025-02-09 23:16:18 +01:00
if ( Me . Util . isCtrlPressed ( ) ) {
2025-02-09 23:13:53 +01:00
Main . ctrlAltTabManager . _items . forEach ( i => {
if ( i . sortGroup === 1 && i . name === 'Dash' )
Main . ctrlAltTabManager . focusGroup ( i ) ;
} ) ;
}
return Clutter . EVENT _STOP ;
2025-02-09 23:09:13 +01:00
case Clutter . KEY _Page _Up :
if ( vertical )
which = Meta . MotionDirection . UP ;
else if ( rtl )
which = Meta . MotionDirection . RIGHT ;
else
which = Meta . MotionDirection . LEFT ;
break ;
case Clutter . KEY _Page _Down :
if ( vertical )
which = Meta . MotionDirection . DOWN ;
else if ( rtl )
which = Meta . MotionDirection . LEFT ;
else
which = Meta . MotionDirection . RIGHT ;
break ;
case Clutter . KEY _Home :
which = 0 ;
break ;
case Clutter . KEY _End :
which = workspaceManager . n _workspaces - 1 ;
break ;
case Clutter . KEY _space :
2025-02-09 23:16:18 +01:00
if ( Me . Util . isCtrlPressed ( ) && Me . Util . isShiftPressed ( ) ) {
Me . Util . activateSearchProvider ( Me . ESP _PREFIX ) ;
} else if ( Me . Util . isAltPressed ( ) ) {
2025-02-09 23:13:53 +01:00
Main . ctrlAltTabManager . _items . forEach ( i => {
if ( i . sortGroup === 1 && i . name === 'Dash' )
Main . ctrlAltTabManager . focusGroup ( i ) ;
} ) ;
2025-02-09 23:16:18 +01:00
} else if ( opt . get ( 'recentFilesSearchProviderModule' ) && Me . Util . isCtrlPressed ( ) ) {
Me . Util . activateSearchProvider ( Me . RFSP _PREFIX ) ;
} else if ( opt . get ( 'windowSearchProviderModule' ) ) {
Me . Util . activateSearchProvider ( Me . WSP _PREFIX ) ;
2025-02-09 23:09:13 +01:00
}
2025-02-09 23:13:53 +01:00
2025-02-09 23:09:13 +01:00
return Clutter . EVENT _STOP ;
case Clutter . KEY _Down :
case Clutter . KEY _Left :
case Clutter . KEY _Right :
case Clutter . KEY _Up :
2025-02-09 23:13:53 +01:00
case Clutter . KEY _Tab :
2025-02-09 23:09:13 +01:00
if ( Main . overview . _overview . _controls . _searchController . searchActive ) {
Main . overview . searchEntry . grab _key _focus ( ) ;
2025-02-09 23:13:53 +01:00
} else if ( opt . OVERVIEW _MODE2 && ! opt . WORKSPACE _MODE && state === 1 ) {
// expose windows by "clicking" on ws thumbnail
// in this case overview stateAdjustment will be used for transition
Main . overview . _overview . controls . _thumbnailsBox . _activateThumbnailAtPoint ( 0 , 0 , global . get _current _time ( ) , true ) ;
Main . ctrlAltTabManager . _items . forEach ( i => {
if ( i . sortGroup === 1 && i . name === 'Windows' )
Main . ctrlAltTabManager . focusGroup ( i ) ;
} ) ;
} else if ( opt . OVERVIEW _MODE && ! opt . WORKSPACE _MODE && state === 1 ) {
// expose windows for OVERVIEW_MODE 1
2025-02-09 23:16:18 +01:00
const wsIndex = global . workspace _manager . get _active _workspace ( ) . index ( ) ;
// after expose animation activate keyboard for window selection
const callback = Me . Util . activateKeyboardForWorkspaceView ;
this . _workspacesViews . forEach (
view => {
view . exposeWindows ( wsIndex , callback ) ;
}
) ;
2025-02-09 23:13:53 +01:00
} else {
if ( state === 2 )
return Clutter . EVENT _PROPAGATE ;
2025-02-09 23:16:18 +01:00
Me . Util . activateKeyboardForWorkspaceView ( ) ;
2025-02-09 23:09:13 +01:00
}
2025-02-09 23:13:53 +01:00
2025-02-09 23:09:13 +01:00
return Clutter . EVENT _STOP ;
default :
return Clutter . EVENT _PROPAGATE ;
}
2025-02-09 23:13:53 +01:00
if ( state === 2 )
return Clutter . EVENT _PROPAGATE ;
2025-02-09 23:09:13 +01:00
let ws ;
if ( which < 0 )
// Negative workspace numbers are directions
ws = workspaceManager . get _active _workspace ( ) . get _neighbor ( which ) ;
else
// Otherwise it is a workspace index
ws = workspaceManager . get _workspace _by _index ( which ) ;
2025-02-09 23:16:18 +01:00
if ( Me . Util . isShiftPressed ( ) ) {
2025-02-09 23:09:13 +01:00
let direction ;
if ( which === Meta . MotionDirection . UP || which === Meta . MotionDirection . LEFT )
direction = - 1 ;
else if ( which === Meta . MotionDirection . DOWN || which === Meta . MotionDirection . RIGHT )
direction = 1 ;
if ( direction )
2025-02-09 23:16:18 +01:00
Me . Util . reorderWorkspace ( direction ) ;
2025-02-09 23:09:13 +01:00
// make all workspaces on primary monitor visible for case the new position is hidden
2025-02-09 23:13:53 +01:00
Main . overview . _overview . _controls . _workspacesDisplay . _workspacesViews [ 0 ] . _workspaces . forEach ( w => {
w . visible = true ;
} ) ;
return Clutter . EVENT _STOP ;
2025-02-09 23:09:13 +01:00
}
if ( ws )
Main . wm . actionMoveWorkspace ( ws ) ;
return Clutter . EVENT _STOP ;
} ,
2025-02-09 23:13:53 +01:00
} ;
2025-02-09 23:09:13 +01:00
// same copy of this function should be available in OverviewControls and WorkspacesView
function _getFitModeForState ( state ) {
switch ( state ) {
case ControlsState . HIDDEN :
case ControlsState . WINDOW _PICKER :
return FitMode . SINGLE ;
case ControlsState . APP _GRID :
if ( opt . WS _ANIMATION && opt . SHOW _WS _TMB )
return FitMode . ALL ;
else
return FitMode . SINGLE ;
default :
return FitMode . SINGLE ;
}
}