javascript - 如何设置 X 属性以使用 Electron 创建桌面状态栏?

标签 javascript node.js electron x11 xmonad

我希望我的窗口管理器(xmonad)将我的 Electron 应用程序作为桌面状态栏来管理:它必须在任何工作区都可用,并且在屏幕上保留一个位置(例如在顶部)

为了实现这一点,我创建了一个这样的 BrowserWindows:

mainWindow = new BrowserWindow({
    x:0,
    y:0,
    width:1024,
    height: 30,
    frame: false,
    title: 'electron-status-bar',
    type: 'dock'
});

我的栏在任何工作区和另一个窗口上方都可见。
但它仍然没有预留位置,因此与其他窗口有重叠。

我用了xprop与 dzen2 (完美工作的实际状态栏)进行比较,dzen2 具有以下属性:
_NET_WM_STRUT(CARDINAL) = 0, 0, 0, 34
_NET_WM_STRUT_PARTIAL(CARDINAL) = 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 899

事实上,管理重叠的xmonad插件(ManageDock)就是观察这两个属性来计算窗口位置。

有没有办法在我的 Electron 应用程序中设置这些属性?

最佳答案

这是一个解决方案,它说明了如何实现这一点,结构很不漂亮。

这个库将被使用:https://github.com/sidorares/node-x11

const x11 = require( 'x11' );
var X;

使用 Electron ,我们创建了一个带有任意窗口标题的浏览器窗口。
mainWindow = new BrowserWindow(
    x: 0,
    y: 0,
    frame: false,
    type: 'dock',
    title: 'myTitle'
}

这里有一个限制:此窗口名称必须是唯一的,因为它将用于检索窗口 ID(将用于应用属性)

将需要两个函数:使用其 id 检索窗口名称和使用其名称检索窗口 id:
var getWindowName = function( wid ) {
    return new Promise( function( resolve, reject ) {
        X.InternAtom(false, '_NET_WM_NAME', function (wmNameErr, wmNameAtom) {
            X.InternAtom(false, 'UTF8_STRING', function (utf8Err, utf8Atom) {
                X.GetProperty(0, wid, wmNameAtom, utf8Atom, 0, 10000000, function(err, nameProp) {
                    if( err ) {
                      reject( err );
                    }
                    resolve( nameProp.data.toString() );
                });
            });
        });
    });
}


var getWindowId = function (name) {

    return new Promise( function( resolve, reject ) {
        x11.createClient(function( err, display ) {
          X = display.client;
          var root = display.screen[0].root;
          X.QueryTree(root, function(err, tree) {
              tree.children.map( function( id ) {
                  let prop = getWindowName( id ).then( function( n ) {
                      if( n === name ) {
                          resolve( id );
                      }
                  })
              } );
          }) 
        });
    });
}

要获取窗口 id,我们必须从根目录检索所有窗口并循环它们。对于每一个,该函数将它们的名称与搜索到的名称进行比较。

我们假设 getWindowId函数将在起点调用一次,因此我们在内部实例化 X 客户端,但在实际应用中不应该这样。

最后,我们需要一个函数来设置 _NET_WM_STRUT_PARTIAL属性(property) :
  var setStrutValues = function (wid, 
    left, right, top, bottom, 
    left_start_y, left_end_y, right_start_y, right_end_y, 
    top_start_x, top_end_x, bottom_start_x, bottom_end_x ) {

    var values = new Buffer( 4 * 12 );
    values.writeUInt32LE(left           ,0*4 );
    values.writeUInt32LE(right          ,1*4 );
    values.writeUInt32LE(top            ,2*4 );
    values.writeUInt32LE(bottom         ,3*4 );
    values.writeUInt32LE(left_start_y   ,4*4 );
    values.writeUInt32LE(left_end_y     ,5*4 );
    values.writeUInt32LE(right_start_y  ,6*4 );
    values.writeUInt32LE(right_end_y    ,7*4 );
    values.writeUInt32LE(top_start_x    ,8*4 );
    values.writeUInt32LE(top_end_x      ,9*4 );
    values.writeUInt32LE(bottom_start_x ,10*4 );
    values.writeUInt32LE(bottom_end_x   ,11*4 );

    X.InternAtom( false, '_NET_WM_STRUT_PARTIAL', function( err, strutAtom ) {
        X.ChangeProperty(0, wid, strutAtom, X.atoms.CARDINAL, 32, values) ;
    } );
  }

使用所有这些,我们可以做到:
getWindowId( 'myTitle' ).then( function( wid ) {
    setStrutValues( wid, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0 );
} )

关于javascript - 如何设置 X 属性以使用 Electron 创建桌面状态栏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43888114/

相关文章:

javascript - Jquery Flot 不实时更新 x 轴

javascript - 访问JavaScript中的对象问题

mysql - 如何将数组传递给mysql查询

r - 如何使用 r-script 从 Node 中的 R 脚本获取输出数据

node.js - Electron.JS占用大量CPU,我无法确定我的代码出了什么问题

java - 从 jQuery 或 Ajax 调用带参数的方法

javascript - jquery,将元素包装在div中

node.js - 如何修复 Brain.js 中的 NaN 训练错误?

node.js - Angular 5 Electron-Packager在 'npm prune --production'失败

javascript - 适用于Electron JS的WinRT API “Windows.UI.ViewManagement”?