3

Using electron 16.9.1, I have built an app whose window is not allowed to minimize and whose alwaysOnTop property is set to false. To put it another way, the idea is to have a window that cannot be minimized and which is always "underneath" other windows.

The configuration of the window looks like this:

const win = new BrowserWindow({
    resizable: false,
    movable: false,
    minimizable: false,
    maximizable: false,
    alwaysOnTop: true,
    fullscreenable: false,
    show: false,
    frame: false,
    backgroundColor: "#00FFFFFF",
    transparent: true,
    webPreferences: {
        nodeIntegration: true,
        contextIsolation: false
    }
});

It works fine, the functions of the app function as I have planned, with but one tiny flaw: once I use the Win + D shortcut, the window is minimized. I am aware that many apps behave this way, but what I really want to know is whether there is a way to avoid this.

[Update] I realized the impossibility of what I am trying to ask for, and instead, I am now trying another approach: to listen to a "show the desktop" event in electron. Every time that event is triggered, I will show the window again. And so, the problem has now changed to: how do I monitor such an event?

  • Can you add some native code and trap `WM_SYSCOMMAND`? Is that possible from Electron apps? See also: https://stackoverflow.com/a/36113798/362536 – Brad Jan 01 '22 at 07:45
  • 2
    First up, `Win + D` does more than just minimize windows (see [What is the difference between Minimize All and Show Desktop?](https://devblogs.microsoft.com/oldnewthing/20040527-00/?p=39153)). The real issue you're trying to solve doesn't have a solution. It fails to answer the question: [What if two programs did this?](https://devblogs.microsoft.com/oldnewthing/20050607-00/?p=35413) – IInspectable Jan 01 '22 at 11:56
  • 1
    @Brad Seems that I have met a dead end here. Electron appears to be able to track such events as minimize and maximize, but as IInspectable here points out, showing the desktop does more than minimizing the window, and electron does not seem to be able to respond to this event. So yeah, this does seem to be an issue without a solution so far. What I am trying instead to find out is how to listen to this showing-the-desktop event in electron now. – Shaobin Jiang Jan 02 '22 at 02:43
  • @ShaobinJiang Can you edit your question to include that as an alternative, you're looking for a way to know when show-the-desktop occurs? And then, I'll add a bounty to your question if it isn't solved by tomorrow, and maybe that will help. I'm not sure there's a solution, but it seems like at least knowing when the desktop is shown should be doable. And if not, perhaps someone can prove that with documentation. :-) – Brad Jan 02 '22 at 02:48
  • 1
    It doesn't have a solution for a different reason: You want a window that's underneath every other window (except for the desktop window). This fails the *"What if two programs did this?"* test. – IInspectable Jan 02 '22 at 09:46
  • @IInspectable When I first wrote down this question, I was actually thinking of a way to better describe what I expected from my codes, and it turns out that my expression made a poor description of it. What I really want to achieve is allowing any window to get over it, but not the desktop. – Shaobin Jiang Jan 02 '22 at 12:39
  • @Brad Just did that! – Shaobin Jiang Jan 02 '22 at 12:43
  • Exactly. You want to make a window bottom-most window (ignoring the desktop window). What if two windows wanted to be bottom-most? That problem has no solution. – IInspectable Jan 02 '22 at 16:50
  • @IInspectable I understand what you're saying, and the way the question is updated still makes sense. The answer to your question is simply that one window wins. All Shaobin wants to do now is notice when the desktop is shown, and then do something. The edge case of two windows being bottom-most won't work of course, but that doesn't mean that they can't handle the show-the-desktop event (assuming such an event exists and is catchable by an Electron application, which is what is trying to be determined now). – Brad Jan 02 '22 at 22:33
  • @bra No. What the OP *really* wants is to establish an [owner-owned window relationship](https://learn.microsoft.com/en-us/windows/win32/winmsg/window-features#owned-windows) with the desktop window and their own. There's no API to do that. In fact, you cannot even create a window hierarchy across threads [unless you control all threads](https://devblogs.microsoft.com/oldnewthing/20130412-00/?p=4683). – IInspectable Jan 02 '22 at 22:47
  • [I bet you are hoping for a really nice bonus for this feature.](https://devblogs.microsoft.com/oldnewthing/20061101-03/?p=29153) – user3840170 Jan 03 '22 at 10:22

2 Answers2

0

What I really want to achieve is allowing any window to get over it, but not the desktop.

Every time that event is triggered, I will show the window again. And so, the problem has now changed to: how do I monitor such an event?

When minimizable: true is set, the BrowserWindow does fire minimize event when Win+D and Win+M are pressed. So, we can set minimizable: true and listen to those, including user minimize, events and restore the window. As frame:false is set user won't see minimize button only option of clicking on taskbar icon will be available.

let mainWindow;
let counter = 0;

function createWindow() {
 mainWindow = new BrowserWindow({
  width: 600,
  height: 300,
  show: false,
  resizable: false,
  movable: false,
  minimizable: true,   /* keep it true */
  maximizable: false,
  alwaysOnTop: false,
  fullscreenable: false,
  frame: false,
  backgroundColor: '#00FFFFFF',
  webPreferences: {
   preload: path.join(__dirname, 'preload.js'),
   contextIsolation: true,
   enableRemoteModule: false,
   nodeIntegration: false,
  },
 });

 mainWindow.loadURL(indexPath);
 
 //try to restore window on minimize
 mainWindow.on('minimize', (e) => {
  e.preventDefault();
  console.log('minimize', ++counter);
  //try changing delay value
  setTimeout(() => mainWindow.restore(), 200);
 });

 mainWindow.on('restore', () => {
  console.log('restore', counter);
 });

 mainWindow.once('ready-to-show', () => {
  mainWindow.show();
  if (dev) {
   mainWindow.webContents.openDevTools();
  }
 });

 mainWindow.on('closed', function () {
  mainWindow = null;
 });
}


Desktop doesn't come infront immediately it takes time so we can't keep delay too low to restore our window. I've deliberately kept the delay high in the code for the demo. Once you call restore, next restore calls have no effect. Drawback is user will be able click on the application icon in taskbar and the application will bounce back.

the Hutt
  • 16,980
  • 2
  • 14
  • 44
  • I followed your advice, and it still does not work. I do not think the problem even lies within the delay value, because when I modified the code and then called `Win + D`, nothing is logged into the console, which I take to mean that the `minimize` event is not triggered? This is kind of weird. – Shaobin Jiang Jan 04 '22 at 10:54
  • Could you share minimal reproducible like [this](https://github.com/OnkarRuikar/electron-react-to-print-demo)? Cos in my environment I do see log messages. And also the window does bounces back on win+D, and win+m key press. – the Hutt Jan 04 '22 at 11:32
  • I put the code [here](https://github.com/Shaobin-Jiang/Daily-Toolkit). – Shaobin Jiang Jan 05 '22 at 00:03
-3

Now We have to deal with disabling keyboard shortcut Win-D,
so we use globalShortcut module.

const { app, globalShortcut } = require('electron')
globalShortcut.unregister('Super+D')

try these keys INSTEAD of Super:

  • Meta

Also try Capital D and small d

PLEASE ALSO TRY:

globalShortcut.register('Super+D', function() {
        console.log('Blocked');
        return false;
    })

Don't get confused that I am asking you to register the key that you actually asked to unregister, THIS IDEA OF REGISTERING KEY CAME AS someone in GitHub said

Registering key in electron app makes it not to work anywhere.

Refer documentation:https://www.electronjs.org/docs/latest/api/global-shortcut#globalshortcutregisteraccelerator-callback

P. S I am sure this won't mostly work as windows owns the right of Win key but try it, I ask you to try many times as I have not tried it


See
https://stackoverflow.com/a/44308648/14862885
It introduces you to a new module electronLocalshortcut
try:

const {app, globalShortcut} = require('electron');

win = new BrowserWindow();

electronLocalshortcut.register(win, 'Super+D', () => {//Even this uses the same REGISTER method to disable shortcut
    console.log('Windows Button pressed');
    return false;
});
Neptotech -vishnu
  • 1,096
  • 8
  • 23
  • The code `globalShortcut.register('CmdOrCtrl+C', () => false);` does disable the copy shortcut in other programs as well!! But `Super` and `Meta` [accelerators](https://www.electronjs.org/docs/latest/api/accelerator) are not working, they do not even log the `Blocked` message. – the Hutt Jan 03 '22 at 14:20
  • there are other examples i mentioned: `electronLocalshortcut`module, `unregistering` but I think its not possible to block win key in `js` BUT THEY ARE BLOCKED EASILY IN `C`(Except certain exception) like powertoys keyboard manager can block/remap a key – Neptotech -vishnu Jan 03 '22 at 14:36
  • 1
    *"Now We have to deal with disabling keyboard shortcut Win-D"* - That's not what the question is asking for. – IInspectable Jan 03 '22 at 19:05
  • no, if we disable win-d it will solve the problem as win-d won't work, and app can't minimize and other apps can overlay on it.IF YOU DO NOT DISABLE WIN-D WE CAN PRESS WIN-D TO VIEW DESKTOP right? – Neptotech -vishnu Jan 04 '22 at 02:57
  • 2
    Breaking a user's system is not a solution to *any* problem. – IInspectable Jan 04 '22 at 08:19