import bindings from './bindings' ; import { BrowserWindow , WindowConfig } from './browserWindow' ; import debug from './debug' ; import { isRS4OrGreater } from './os' ; import * as electron from 'electron' ; function getHwnd ( win ) { if ( ! win ) throw new TypeError ( 'WINDOW_NOT_GIVEN' ) ; try { return win . getNativeWindowHandle ( ) . readInt32LE ( 0 ) ; } catch ( e ) { throw new TypeError ( 'NOT_VALID_WINDOW' ) ; } } const supportedType = [ 'light' , 'dark' , 'appearance-based' ] ; const _lightThemeColor = [ 221 , 221 , 221 , 136 ] ; const _darkThemeColor = [ 34 , 34 , 34 , 136 ] ; /**
 * Red, green, blue and alpha
 */ export interface RGBA extends RGB { a : number ; } /**
 * Red, green and blue
 */ export interface RGB { r : number ; g : number ; b : number ; } export interface VibrancyConfig { colors : RGBA & { base ? : RGBA ; } ; effect : 0 | 1 ; useCustomWindowRefreshMethod ? : boolean ; maximumRefreshRate ? : number ; disableOnBlur ? : boolean ; currentOpacity : number ; } export function hexTo255 ( hex ) { const result = /^#?([a-f\d]{2})$/i . exec ( hex ) ; return result ? parseInt ( result [ 1 ] , 16 ) : undefined ; } export function _8bitToHex ( c ) { var hex = c . toString ( 16 ) ; return hex . length == 1 ? '0' + hex : hex ; } export function rgbToHex ( rgb ) { return '#' + _8bitToHex ( rgb . r ) + _8bitToHex ( rgb . g ) + _8bitToHex ( rgb . b ) ; } function getColorsFromTheme ( theme ) { const dark = { r : _darkThemeColor [ 0 ] , g : _darkThemeColor [ 1 ] , b : _darkThemeColor [ 2 ] , a : _darkThemeColor [ 3 ] , } ; const light = { r : _lightThemeColor [ 0 ] , g : _lightThemeColor [ 1 ] , b : _lightThemeColor [ 2 ] , a : _lightThemeColor [ 3 ] , } ; if ( theme === 'light' ) return light ; if ( theme === 'dark' ) return dark ; if ( typeof theme === 'string' ) { const r = hexTo255 ( theme . slice ( 1 , 3 ) ) ; const g = hexTo255 ( theme . slice ( 3 , 5 ) ) ; const b = hexTo255 ( theme . slice ( 5 , 7 ) ) ; const a = hexTo255 ( theme . slice ( 7 , 9 ) ) ; if ( r === undefined || g === undefined || b === undefined || a === undefined ) return light ; return { r : r , g : g , b : b , a : a } ; } if ( electron . nativeTheme . shouldUseDarkColors ) return dark ; else return light ; } /**
 * The theme to apply to the vibrancy. Can be 'light',
 * 'dark', 'appearance-based' or a custom HEX color
 * with alpha.
 */ export type VibrancyTheme = 'light' | 'dark' | 'appearance-based' | string ; /**
 * The effect to apply. Can be 'acrylic' or 'blur'.
 */ export type VibrancyEffect = 'acrylic' | 'blur' ; /**
 * Options to apply to the vibrancy
 */ export interface VibrancyOptions { /**
     * The theme to use.
     */ theme ? : VibrancyTheme ; /**
     * The effect to use.
     */ effect ? : VibrancyEffect ; /**
     * If enabled, we use a custom window resize/move
     * handler for performance.
     */ useCustomWindowRefreshMethod ? : boolean ; /**
     * Maximum value to refresh application screen
     * in seconds.
     */ maximumRefreshRate ? : number ; /**
     * If true, acrylic effect will be disabled whe
     * window lost focus.
     */ disableOnBlur ? : boolean ; /**
     * If true, log will be printed to console.
     */ debug ? : boolean ; } export type Vibrancy = VibrancyTheme | VibrancyOptions ; export function getConfigFromOptions ( vibrancyOptions ) { const defaultSettings = { theme : undefined , effect : 'acrylic' , useCustomWindowRefreshMethod : true , maximumRefreshRate : 60 , disableOnBlur : true , } ; const options = Object . assign ( defaultSettings , typeof vibrancyOptions === 'object' ? vibrancyOptions : { theme : vibrancyOptions } ) ; let config = { disableOnBlur : options . disableOnBlur , effect : 0 , maximumRefreshRate : options . maximumRefreshRate , useCustomWindowRefreshMethod : options . useCustomWindowRefreshMethod , colors : getColorsFromTheme ( options . theme ) , currentOpacity : 0 , } ; if ( options . effect === 'acrylic' && isRS4OrGreater ) config . effect = 1 ; return config ; } export function _setVibrancy ( win , config ? ) { if ( config && config . colors ) { debug ( 'Vibrancy On' , config ) ; bindings ( ) . setVibrancy ( getHwnd ( win ) , config . effect , config . colors . r , config . colors . g , config . colors . b , win . __electron_acrylic_window__ . vibrnacyConfig . currentOpacity ) ; win . __electron_acrylic_window__ . vibrancyActivated = true ; setTimeout ( ( ) => { try { if ( win . __electron_acrylic_window__ . vibrancyActivated ) win . setBackgroundColor ( '#00000000' ) ; } catch ( e ) { } } , 50 ) ; } else { debug ( 'Vibrancy Off' , config , win . __electron_acrylic_window__ . vibrnacyConfig ) ; win . __electron_acrylic_window__ . vibrancyActivated = false ; if ( win . __electron_acrylic_window__ . vibrnacyConfig ) { win . setBackgroundColor ( win . __electron_acrylic_window__ . vibrnacyConfig && win . __electron_acrylic_window__ . vibrnacyConfig . colors ? '#FE' + win . __electron_acrylic_window__ . vibrnacyConfig . colors . r + win . __electron_acrylic_window__ . vibrnacyConfig . colors . g + win . __electron_acrylic_window__ . vibrnacyConfig . colors . b : '#000000' ) ; } setTimeout ( ( ) => { try { if ( ! win . __electron_acrylic_window__ . vibrancyActivated ) bindings ( ) . disableVibrancy ( getHwnd ( win ) ) ; } catch ( e ) { } } , 10 ) ; } } param options export function setVibrancy ( win , vibrancy = 'appearance-based' ) { win . __electron_acrylic_window__ = win . __electron_acrylic_window__ || ( { } as WindowConfig ) ; if ( vibrancy ) { win . __electron_acrylic_window__ . vibrnacyConfig = getConfigFromOptions ( vibrancy ) ; _setVibrancy ( win , win . __electron_acrylic_window__ . vibrnacyConfig ) ; } else { _setVibrancy ( win ) ; win . __electron_acrylic_window__ . vibrnacyConfig = getConfigFromOptions ( undefined ) ; } }