Review Request 120363: proposal to use the NOGUI switch in CMake files to set the default value for GUIenabled

René J.V. Bertin rjvbertin-Re5JQEeQqe8AvxtiuMwx3w at public.gmane.org
Fri Sep 26 16:42:35 BST 2014



> On Sept. 25, 2014, 8:07 p.m., Thomas Lübking wrote:
> > Aside Thiagos concern, what actually causes the menubar/docker item stuff?
> > 
> > Quoting QApplication (4.8):
> > > On X11, the window system is initialized if GUIenabled is true. If GUIenabled is false, the application does not connect to the X server. On Windows and Mac OS, currently the window system is always initialized, regardless of the value of GUIenabled. This may change in future versions of Qt.
> > 
> > So it's perhaps rather a statement in KApplicationPrivate::init() which causes this?
> > There aren't too many depending on GUIEnabled ... ;-)
> 
> René J.V. Bertin wrote:
>     Thiagos?
>     
>     The menubar/Dock "item stuff" is the result of `qt_mac_loadMenuNib` in `qapplication_mac.mm`, which is called when `!QApplication::testAttribute(Qt::AA_MacPluginApplication)`. Setting `GUIenabled=false` has that effect, ultimately.
> 
> Thomas Lübking wrote:
>     > Thiagos?
>     
>     By mail:
>     http://lists.kde.org/?l=kde-core-devel&m=141166670217317&w=2
>     
>     > result of qt_mac_loadMenuNib in qapplication_mac.mm
>     
>     Ok, so the API doc lied to me ;-)
>     Since the attributes are static, you could simply set it before creating the application in the relevant main funcs, could you?
>     (Though i actually don't see it set anywhere - but it's late and i'm tired...)
> 
> René J.V. Bertin wrote:
>     Ah, apparently Thiago missed the multiple recent reminders of the fact that we OS X users are going to be "stuck" in/with KDE4 for a tad longer than the average Linux user (Debian apart, maybe? ;))
>     Anyway, I guess I'm going to have to look again at how exactly `GUIenabled=false` leads to the qt_menu.nib not being loaded in Qt ...
>     
>     I don't think the API docs lied to you. Not loading the menu nib doesn't mean that the window system is not initialised ...
> 
> René J.V. Bertin wrote:
>     Taking this back to RR:
>     
>     On Friday September 26 2014 13:33:20 Thomas Lübking wrote:
>     > On Freitag, 26. September 2014 10:41:39 CEST, Ben Cooksley wrote:
>     > > Applying a solution to a single OS is inherently wrong
>     > 
>     > > On Fri, Sep 26, 2014 at 5:01 PM, Thiago Macieira <thiago-RNdGp2+chz0 at public.gmane.orgg> wrote:
>     > >> And still it needs to be studied for Qt5
>     > 
>     > Afaics there are two major issues with this patch (and actually they make everyone right in this thread ;-)
>     > 
>     > 1. It's Qt4 only
>     > 2. It's the broadsword
>     > 
>     > We can skip 1 (which is not "fixable", the API doesn't exist anymore) and should focus on 2 - and the foil may implicitly handle this as well ;-)
>     
>     You know 4.8.7 is in the making? ;)
>     Also, concerning QApplication (4.8):
>     >On X11, the window system is initialized if GUIenabled is true. If GUIenabled is false, the application does not connect to the X server
>     
>     That may be true for Qapplication, but KApplication does preciously little with GUIenabled. It's either ignored on X11, or only serves to determine whether the clipboard is initialised or not.
>     
>     > It is too broadsword as, as mentioned by Thiago, the GUIEnabled parameter has several implications on all systems (let alone that the patch attempts to control it by the so far unrelated NOGUI cmake switch).
>     
>     True, but what *does* the NOGUI switch do? Not much that I can see, until now. I'd still like to make a case that if there is such a switch, it'd best do what you'd expect it to do. It's unambiguous as can be, and removes the burden of having to remember the exact call and add it to code you're working on - actually, also the burden of knowing about the issue in the first place!
>     This is the same argument a Qt5 dev gave me for their heuristics menurole guessing feature.
>     
>     > Luckily the behavior whether there's a menubar and stuff on OSX can be controlled by a QCoreApplication attribute that *is* OSX specific:
>     > 
>     >    Qt::AA_MacPluginApplication
>     
>     [So I went on a little profiling spree :)]
>     
>     Indeed, but this is not exactly what `GUIenabled=false` leads to ultimately in Qt4, on OS X. `qt_appType` is set to `QApplication::Tty` which is in fact the default (at least in Qt4) instead of `QApplication::GuiClient`, which in turn sets the global bool variable `qt_is_gui_used=false`.
>     `qt_is_gui_used` is read in the OS X `qt_init()` function (in qapplication_mac.mm), and controls a whole lot more than what `AA_MacPluginApplication` controls. Roughly speaking, one can resume that the window system isn't initialised *at all* when `qt_is_gui_used==false`.
>     Note that `qt_init` reads out the `LSUIElement` flag (as well as `LSBackgroundOnly`) from the app's InfoDictionary (Info.plist or set programmatically). This is then used to call `TransformProcessType(&psn, kProcessTransformToForegroundApplication)`, or not. (I'm surprised to see that it'd be up to the application to take that Info.plist flag into account; I'd have guessed the window manager would take care of it.)
>     
>      *FYI*: In Qt 5.3.1, `qt_appType` is called `qapplication_type`, `qt_is_gui_used` exists, but is no longer used in `qt_init` which I've found only in `qapplication_qpa.cpp` and not in any platform-specific code. `AA_MacPluginApplication` is read out in `QCocoaIntegration::QCocoaIntegration` (qcocoaintegration.mm). That same ctor handles the readout of `LSUIElement` through a call to `qt_mac_transformProccessToForegroundApplication()` (qcocoahelpers.mm), which is called only when `qEnvironmentVariableIsEmpty("QT_MAC_DISABLE_FOREGROUND_APPLICATION_TRANSFORM")` (which just checks `getenv`, nothing more fancy).
>      Most of the window system calls made when `qt_is_gui_used==true` in Qt4.8 but independent of AA_MacPluginApplication have moved all over the place in Qt 5.3 .
>      
>     > So my very first attempt would be to set that (unconditionally, ie. on all systems - it should be idempotent outside OSX anyway) before instantiating the application in the main funcs of the problematic applications AND LEAVE THE GUIEnabled PARAMETER UNTOUCHED.
>     
>     Not sure it's not as simple as that. Reading back up on what `GUIenabled=false` makes me understand why an application like kglobabaccel crashes (aborts) when build with that setting. It tries to do things for which the window system must have been initialised.
>     I'll try to see what happens when I do `QApplication::setAttribute(AA_MacPluginApplication)` or `ditto AA_DontUseNativeMenuBar` (but without my CoreFoundation patch) in kglobalaccel.
>     
>     But supposing that it indeed has the intended effect, surely you're not proposing to make it the default, obliging every applications that does want to present a full-blown GUI to unset the attribute?!
>     
>     > Charmingly, such change would be Qt5 compatible =)
>     
>     It remains to be seen whether the attribute has the same effect. Fortunately I do have a little Qt5-only test application with which I can test such things.
>     
>     > Personally I doubt that this needs to or should be injected by a cmake parameter, but added directly (notably since this will only affect a fistful of applications in KDE anyway)
>     
>     "this" being what, the NOGUI cmake parameter? There's quite a few of those around in kde-workspace, kde-baseapps and (esp.) the kdepim packages.
> 
> René J.V. Bertin wrote:
>     OK, so I added `QApplication::setAttribute(AA_MacPluginApplication)` to kglobalaccel, as close as possible to the beginning of KDEMain (= instead of the CoreFoundation code that I pushed to HEAD earlier today). In this location, setting that attribute (or `AA_DontUseNativeMenuBar`) did NOT have the intended effect: kglobalaccel remained visible in the Dock, the AppSwitcher, and still had a menubar with the application menu. I didn't really note whether that menu had an items in it, but that's a moot point.
>     
>     When I did the same tests with the Qt5 'systray' example application, I got a very comparable result. With both attributes I still get the same presence in Dock, app switcher and menubar. With `AA_MacPluginApplication` the system tray *icon* disappears, but the menu can still be obtained by clicking in the empty spot (which of course takes up space). With `AA_MacPluginApplication`, the application menu is empty, but visible on the menu bar. That's probably unavoidable (and means the app doesn't have its own menu) when an application is visible in the dock and app switcher.
>     
>     The only way for that example app to become a true plugin is to use the aforementioned CoreFoundation code :
>     
>     `	CFBundleRef mainBundle = CFBundleGetMainBundle();
>     	if (mainBundle) {
>     	    // get the application's Info Dictionary. For app bundles this would live in the bundle's Info.plist,
>     	    // for regular executables it is obtained in another way.
>     	    CFMutableDictionaryRef infoDict = (CFMutableDictionaryRef) CFBundleGetInfoDictionary(mainBundle);
>     	    if (infoDict) {
>     		   // Add or set the "LSUIElement" key with/to value "1". This can simply be a CFString.
>     		   CFDictionarySetValue(infoDict, CFSTR("LSUIElement"), CFSTR("1"));
>     		   // That's it. We're now considered as an "agent" by the window server, and thus will have
>     		   // neither menubar nor presence in the Dock or App Switcher.
>     	    }
>     	}
>     `
>     which would be suitable for an application that lives in the systemtray or doesn't have a public interface at all unless it decides to open a dialog.
>     
>     Note also that the `QCocoaIntegration` ctor UNSETS `AA_DontUseNativeMenuBar` as one of its first actions ... and that `TransformProcessType` (see my previous post) can only make a foreground application out of a background application on OS X 10.6 and earlier.

That'd be 

```C++
	CFBundleRef mainBundle = CFBundleGetMainBundle();
	if (mainBundle) {
	    // get the application's Info Dictionary. For app bundles this would live in the bundle's Info.plist,
	    // for regular executables it is obtained in another way.
	    CFMutableDictionaryRef infoDict = (CFMutableDictionaryRef) CFBundleGetInfoDictionary(mainBundle);
	    if (infoDict) {
		   // Add or set the "LSUIElement" key with/to value "1". This can simply be a CFString.
		   CFDictionarySetValue(infoDict, CFSTR("LSUIElement"), CFSTR("1"));
		   // That's it. We're now considered as an "agent" by the window server, and thus will have
		   // neither menubar nor presence in the Dock or App Switcher.
	    }
	}
```


- René J.V.


-----------------------------------------------------------
This is an automatically generated e-mail. To reply, visit:
https://git.reviewboard.kde.org/r/120363/#review67442
-----------------------------------------------------------


On Sept. 25, 2014, 3:32 p.m., René J.V. Bertin wrote:
> 
> -----------------------------------------------------------
> This is an automatically generated e-mail. To reply, visit:
> https://git.reviewboard.kde.org/r/120363/
> -----------------------------------------------------------
> 
> (Updated Sept. 25, 2014, 3:32 p.m.)
> 
> 
> Review request for KDE Software on Mac OS X and kdelibs.
> 
> 
> Repository: kdelibs
> 
> 
> Description
> -------
> 
> Applications can be defined in their CMake file as being `NOGUI`, but until now this has had very limited effect. Especially on OS X, those applications can still construct a minimal GUI and thus have "visual presence" in the Dock and application switcher (and have a menubar as well).
> 
> This patch proposes to define a preprocessor token, `KDE_WITHOUT_GUI`, for those targets, and uses that token to set the default value for the `GUIenabled` option of the `KApplication` and `KUniqueApplication` classes.
> 
> This could potentially be combined on OS X with the CoreFoundation call that turns a running application into an "agent" (see https://git.reviewboard.kde.org/r/120354).
> 
> 
> Diffs
> -----
> 
>   cmake/modules/KDE4Macros.cmake 073d726 
>   kdeui/kernel/kapplication.h fa2ab26 
>   kdeui/kernel/kapplication.cpp b093034 
>   kdeui/kernel/kuniqueapplication.h e05dcd7 
> 
> Diff: https://git.reviewboard.kde.org/r/120363/diff/
> 
> 
> Testing
> -------
> 
> On OS X 10.6.8 with kdelibs 4.14.1 (git/kde4.14), rebuilt kdelibs, kde-workspace, kde-runtime, kde-baseapps, kdepim-runtime and nepomuk-core.
> If the documentation I read is correct, the `GUIenabled` switch has no effect on Linux, so this patch shouldn't have any either on that OS.
> 
> 
> Thanks,
> 
> René J.V. Bertin
> 
>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.kde.org/pipermail/kde-core-devel/attachments/20140926/eca2d92f/attachment.htm>


More information about the kde-core-devel mailing list