Avoid application activation and focus in when clicking buttons on it - Windows API or Qt
Asked Answered
W

2

7

Situation: A border-less QDialog stays successfully on top of other applications.

The problem is when clicking on this always-on-top application window, the following occurs:

  • The clicked always-on-top application gets activated
  • The clicked always-on-top application window steals the focus of previous active/focused app

Is there a possibility that when clicking on this always-on-top inactive and unfocused application window,

  • the current application does not loose activation and focus
  • while user being still able to interact with the always-on-top application (hitting buttons or drop-down menus, dragging the window)?

I'm working with Qt but there's no problem about using native Windows API.

I tried the following Qt windowFlag:

  • Qt::WindowDoesNotAcceptFocus but it does not work: the always-on-top application is activated, focused.
  • Qt::WindowTransparentForInput, the always-on-top application is really transparent to clicks: not activated and not focused in but buttons are unfortunately not triggered when hit.
Weingartner answered 6/9, 2013 at 16:7 Comment(0)
W
7

It is possible to make a window unactivable and unfocusable when clicking on it by using Windows flags (#include <qt_windows.h>). The following has to be used after the window is created and shown:

HWND winHandle = (HWND)winId();
ShowWindow(winHandle, SW_HIDE);
SetWindowLong(winHandle, GWL_EXSTYLE, GetWindowLong(winHandle, GWL_EXSTYLE)
    | WS_EX_NOACTIVATE | WS_EX_APPWINDOW);
ShowWindow(winHandle, SW_SHOW);
Weingartner answered 12/9, 2013 at 21:17 Comment(8)
Hm, how do you do this in Qt anyway? Override winEvents?Aryl
You can override showEvent(). For its implementation, first call the parent method then the above code.Weingartner
Not successful :) I have already success in porting the code to PyQt using PyWin libraries, overriding showEvent(), but when I click control on this suppose-to-be-nonactive-window, my main window become inactive. Any idea?Aryl
What about overriding showEvent() in the other window too?Weingartner
My case is a floating QFrame containing buttons that need to be clicked. Haven't success using the above WS_EX_NOACTIVATE. Right now, I subclass pushbutton and trapping MouseButtonPress, MouseButtonRelease and MouseButtonDblClick in eventFilter. In there, I activate the main window. It's almost perfect. Sometime still a quick flashing title bar occured. But, yeah, that's the best I can do right now :)Aryl
Does the window active when you click on its background (not on one of its button). I remember that I had to override showEvent() of menu/dropdown list of the window.Weingartner
My background is transparent. So, users must click the button in this case. I have also override showEvent() of the buttons subclass and try to set WS_EX_NOACTIVATE there. But still the focus shifted from main windowAryl
Try a new Qt simple project with one default window (no special effects, no transparent background, no buttons ...). See if it clicking the window does not activate the application, then trial/error different options (adding buttons, transparency, multiple windows ...).Weingartner
G
1

I don't know about QDialog, I'm using just a QWidget for similar purpose (displaying a Windows 8 style notification).

Try setting:

dialog->setFocusPolicy(Qt::NoFocus);
dialog->setAttribute(Qt::WA_ShowWithoutActivating); 

maybe you'll have to set focus policy on all children.

Galloot answered 7/9, 2013 at 11:41 Comment(7)
Thanks headsvk but it is overridden by the always on top flag: dialog->setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint); It seems that this flag is conflicting with the Qt::WA_ShowWithoutActivating attribute.Weingartner
In fact it doesn't work at all on Windows (even without the WindowStaysOnTopHint), while on Mac there is the conflict. I tested with a MainWindow, then a QDialog and finally with a QWidget.Weingartner
I'm also using Qt::WindowStaysOnTopHint. So I tried adding a button to my popup and when I click on it, it doesn't steal focus from my active window. How do the flags conflict?Galloot
The conflict was on Mac (sorry for the confusion). But let's go back on Windows. The application still activates and get focus in. I've created a sample Qt GUI project then added the following code in MainWindow constructor: pastebin.com/tKB2NSHzWeingartner
ok it doesn't work for me, my popup isn't stealing focus on show so I thought it also doesn't on click (I don't click on it, I close it on mouse enter), sorryGalloot
however if the window which needs to stay activated is yours, you can use a simple workaround by activating it when the user clicks on the dialogGalloot
Unfortunately it is not the case. Typically, my Qt app (to be left unactivated and unfocused) lies on top of PowerPoint.Weingartner

© 2022 - 2024 — McMap. All rights reserved.