gconf-settings/skel/.local/share/gnome-shell/extensions/unite@hardpixel.eu/modules/windowDecoration.js

197 lines
5.1 KiB
JavaScript

const ByteArray = imports.byteArray
const GLib = imports.gi.GLib
const Meta = imports.gi.Meta
const Util = imports.misc.util
const Unite = imports.misc.extensionUtils.getCurrentExtension()
const Base = Unite.imports.module.BaseModule
const getWindowXID = Unite.imports.helpers.getWindowXID
const isWindow = Unite.imports.helpers.isWindow
const isMaximized = Unite.imports.helpers.isMaximized
const loadUserStyles = Unite.imports.helpers.loadUserStyles
var WindowDecoration = class WindowDecoration extends Base {
_onSetup() {
this._enableKey = 'hide-window-titlebars'
this._disableValue = 'never'
}
_onInitialize() {
this.monitorManager = Meta.MonitorManager.get()
}
_onActivate() {
this._signals.connect(global.display, 'notify::focus-window', 'updateTitlebar')
this._signals.connect(global.window_manager, 'size-change', 'updateTitlebar')
this._signals.connect(this.monitorManager, 'monitors-changed', 'undecorateWindows')
this._settings.connect('hide-window-titlebars', 'updateUserStyles')
this._settings.connect('button-layout', 'updateUserStyles')
this._settings.connect('restrict-to-primary-screen', 'undecorateWindows')
this._updateUserStyles()
this._undecorateWindows()
}
_onDeactivate() {
this._removeUserStyles()
this._decorateWindows()
}
_onReset() {
this._removeUserStyles()
this._updateUserStyles()
this._undecorateWindows()
}
_getWindowXID(win) {
win._windowXID = win._windowXID || getWindowXID(win)
return win._windowXID
}
_getHintValue(win, hint) {
let winId = this._getWindowXID(win)
if (!winId) return
let result = GLib.spawn_command_line_sync(`xprop -id ${winId} ${hint}`)
let string = ByteArray.toString(result[1])
if (!string.match(/=/)) return
string = string.split('=')[1].trim().split(',').map(part => {
part = part.trim()
return part.match(/\dx/) ? part : `0x${part}`
})
return string
}
_setHintValue(win, hint, value) {
let winId = this._getWindowXID(win)
if (!winId) return
Util.spawn(['xprop', '-id', winId, '-f', hint, '32c', '-set', hint, value])
}
_getMotifHints(win) {
if (!win._uniteOriginalState) {
let state = this._getHintValue(win, '_UNITE_ORIGINAL_STATE')
if (!state) {
state = this._getHintValue(win, '_MOTIF_WM_HINTS')
state = state || ['0x2', '0x0', '0x1', '0x0', '0x0']
this._setHintValue(win, '_UNITE_ORIGINAL_STATE', state.join(', '))
}
win._uniteOriginalState = state
}
return win._uniteOriginalState
}
_getAllWindows() {
let windows = global.get_window_actors().map(win => win.meta_window)
return windows.filter(win => this._handleWindow(win))
}
_handleWindow(win) {
let handleWin = false
if (!isWindow(win)) return
let state = this._getMotifHints(win)
handleWin = !win.is_client_decorated()
handleWin = handleWin && (state[2] != '0x2' && state[2] != '0x0')
return handleWin
}
_toggleDecorations(win, hide) {
let winId = this._getWindowXID(win)
if (!winId) return
let prop = '_MOTIF_WM_HINTS'
let flag = '0x2, 0x0, %s, 0x0, 0x0'
let value = hide ? flag.format('0x2') : flag.format('0x1')
Util.spawn(['xprop', '-id', winId, '-f', prop, '32c', '-set', prop, value])
}
_resetDecorations(win) {
if (!this._handleWindow(win))
return
this._toggleDecorations(win, false)
delete win._decorationOFF
delete win._windowXID
}
_updateTitlebar() {
let focusWindow = global.display.focus_window
if (!focusWindow) return
this._toggleTitlebar(focusWindow)
}
_showTitlebar(win) {
if (!win._decorationOFF) return
win._decorationOFF = false
this._toggleDecorations(win, false)
}
_hideTitlebar(win) {
if (win._decorationOFF) return
win._decorationOFF = true
this._toggleDecorations(win, true)
}
_toggleTitlebar(win) {
if (!this._handleWindow(win))
return
let maxed = isMaximized(win, this._setting)
let always = this._setting == 'always'
if (always || maxed)
this._hideTitlebar(win)
else
this._showTitlebar(win)
}
_getCssImports() {
let position = this._settings.get('window-buttons-position')
let filePath = `${Unite.path}/styles/buttons-${position}`
let maximized = `@import url('${filePath}.css');\n`
let tiled = `@import url('${filePath}-tiled.css');\n`
let always = `@import url('${filePath}-always.css');\n`
switch (this._setting) {
case 'both': return maximized + tiled
case 'maximized': return maximized
case 'tiled': return tiled
case 'always': return always
}
}
_updateUserStyles() {
let styles = this._getCssImports()
loadUserStyles(styles || '')
}
_removeUserStyles() {
loadUserStyles('')
}
_undecorateWindows() {
let windows = this._getAllWindows()
windows.forEach(win => { this._toggleTitlebar(win) })
}
_decorateWindows() {
let windows = this._getAllWindows()
windows.forEach(win => { this._resetDecorations(win) })
}
}