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
* workspace . 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:13:53 +01:00
const { St , Graphene } = imports . gi ;
2025-02-09 23:09:13 +01:00
const Main = imports . ui . main ;
const Util = imports . misc . util ;
const Workspace = imports . ui . workspace ;
const ExtensionUtils = imports . misc . extensionUtils ;
const Me = ExtensionUtils . getCurrentExtension ( ) ;
2025-02-09 23:13:53 +01:00
const _Util = Me . imports . lib . util ;
2025-02-09 23:09:13 +01:00
2025-02-09 23:13:53 +01:00
let _overrides ;
2025-02-09 23:09:13 +01:00
let opt ;
2025-02-09 23:13:53 +01:00
let _firstRun = true ;
2025-02-09 23:09:13 +01:00
2025-02-09 23:13:53 +01:00
function update ( reset = false ) {
opt = Me . imports . lib . settings . opt ;
const moduleEnabled = opt . get ( 'workspaceModule' , true ) ;
reset = reset || ! moduleEnabled ;
2025-02-09 23:09:13 +01:00
2025-02-09 23:13:53 +01:00
// don't even touch this module if disabled
if ( _firstRun && reset )
return ;
2025-02-09 23:09:13 +01:00
2025-02-09 23:13:53 +01:00
_firstRun = false ;
if ( _overrides )
2025-02-09 23:09:13 +01:00
_overrides . removeAll ( ) ;
2025-02-09 23:13:53 +01:00
2025-02-09 23:09:13 +01:00
if ( reset ) {
2025-02-09 23:13:53 +01:00
Workspace . WINDOW _PREVIEW _MAXIMUM _SCALE = 0.95 ;
2025-02-09 23:09:13 +01:00
_overrides = null ;
opt = null ;
return ;
}
_overrides = new _Util . Overrides ( ) ;
_overrides . addOverride ( 'WorkspaceBackground' , Workspace . WorkspaceBackground . prototype , WorkspaceBackground ) ;
// fix overlay base for Vertical Workspaces
_overrides . addOverride ( 'WorkspaceLayout' , Workspace . WorkspaceLayout . prototype , WorkspaceLayout ) ;
}
// workaround for upstream bug (that is not that invisible in default shell)
// smaller window cannot be scaled below 0.95 (WINDOW_PREVIEW_MAXIMUM_SCALE)
2025-02-09 23:13:53 +01:00
// when its target scale for exposed windows view (workspace state 1) is bigger than the scale needed for ws state 0.
2025-02-09 23:09:13 +01:00
// in workspace state 0 where windows are not spread and window scale should follow workspace scale,
// this window follows proper top left corner position, but doesn't scale with the workspace
// so it looks bad and the window can exceed border of the workspace
// extremely annoying in OVERVIEW_MODE 1 with single smaller window on the workspace, also affects appGrid transition animation
2025-02-09 23:13:53 +01:00
// disadvantage of following workaround - the WINDOW_PREVIEW_MAXIMUM_SCALE value is common for every workspace,
// on multi-monitor system can be visible unwanted scaling of windows on workspace in WORKSPACE_MODE 0 (windows not spread)
// when leaving overview while any other workspace is in the WORKSPACE_MODE 1.
const WorkspaceLayout = {
// injection to _init()
after _ _init ( ) {
if ( opt . OVERVIEW _MODE === 1 ) {
this . _stateAdjustment . connect ( 'notify::value' , ( ) => {
// scale 0.1 for window state 0 just needs to be smaller then possible scale of any window in spread view
const scale = this . _stateAdjustment . value ? 0.95 : 0.1 ;
if ( scale !== this . WINDOW _PREVIEW _MAXIMUM _SCALE ) {
this . WINDOW _PREVIEW _MAXIMUM _SCALE = scale ;
// when transition to ws state 1 (WINDOW_PICKER) begins, replace the constant with the original one
Workspace . WINDOW _PREVIEW _MAXIMUM _SCALE = scale ;
// and force recalculation of the target layout, so the transition will be smooth
this . _needsLayout = true ;
}
} ) ;
}
} ,
2025-02-09 23:09:13 +01:00
// this fixes wrong size and position calculation of window clones while moving overview to the next (+1) workspace if vertical ws orientation is enabled in GS
2025-02-09 23:13:53 +01:00
_adjustSpacingAndPadding ( rowSpacing , colSpacing , containerBox ) {
2025-02-09 23:09:13 +01:00
if ( this . _sortedWindows . length === 0 )
return [ rowSpacing , colSpacing , containerBox ] ;
// All of the overlays have the same chrome sizes,
// so just pick the first one.
const window = this . _sortedWindows [ 0 ] ;
const [ topOversize , bottomOversize ] = window . chromeHeights ( ) ;
const [ leftOversize , rightOversize ] = window . chromeWidths ( ) ;
const oversize = Math . max ( topOversize , bottomOversize , leftOversize , rightOversize ) ;
if ( rowSpacing !== null )
rowSpacing += oversize ;
if ( colSpacing !== null )
colSpacing += oversize ;
if ( containerBox ) {
const vertical = global . workspaceManager . layout _rows === - 1 ;
const monitor = Main . layoutManager . monitors [ this . _monitorIndex ] ;
const bottomPoint = new Graphene . Point3D ( ) ;
2025-02-09 23:13:53 +01:00
if ( vertical )
2025-02-09 23:09:13 +01:00
bottomPoint . x = containerBox . x2 ;
2025-02-09 23:13:53 +01:00
else
2025-02-09 23:09:13 +01:00
bottomPoint . y = containerBox . y2 ;
2025-02-09 23:13:53 +01:00
2025-02-09 23:09:13 +01:00
const transformedBottomPoint =
this . _container . apply _transform _to _point ( bottomPoint ) ;
const bottomFreeSpace = vertical
? ( monitor . x + monitor . height ) - transformedBottomPoint . x
: ( monitor . y + monitor . height ) - transformedBottomPoint . y ;
const [ , bottomOverlap ] = window . overlapHeights ( ) ;
2025-02-09 23:13:53 +01:00
if ( ( bottomOverlap + oversize ) > bottomFreeSpace && ! vertical )
2025-02-09 23:09:13 +01:00
containerBox . y2 -= ( bottomOverlap + oversize ) - bottomFreeSpace ;
}
return [ rowSpacing , colSpacing , containerBox ] ;
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 WorkspaceBackground = {
_updateBorderRadius ( value = false ) {
2025-02-09 23:09:13 +01:00
// don't round already rounded corners during exposing windows
2025-02-09 23:13:53 +01:00
if ( value === false && opt . OVERVIEW _MODE === 1 )
2025-02-09 23:09:13 +01:00
return ;
2025-02-09 23:13:53 +01:00
2025-02-09 23:09:13 +01:00
const { scaleFactor } = St . ThemeContext . get _for _stage ( global . stage ) ;
2025-02-09 23:13:53 +01:00
const cornerRadius = scaleFactor * opt . WS _PREVIEW _BG _RADIUS ;
2025-02-09 23:09:13 +01:00
const backgroundContent = this . _bgManager . backgroundActor . content ;
2025-02-09 23:13:53 +01:00
value = value !== false
? value
: this . _stateAdjustment . value ;
2025-02-09 23:09:13 +01:00
backgroundContent . rounded _clip _radius =
Util . lerp ( 0 , cornerRadius , value ) ;
2025-02-09 23:13:53 +01:00
} ,
} ;