jarcode-foss / glava

GLava - OpenGL audio spectrum visualizer
GNU General Public License v3.0
1.18k stars 59 forks source link

Plasma/KDE - stacking order and position issues #4

Open jpope777 opened 6 years ago

jpope777 commented 6 years ago

Setting the xwintype to 'desktop', glava only shows on the active workspace when the program is initially run. Also, clicking on the desktop outside of the glava 'window' causes it to disappear. It'll still be running just not visible.

OS: Arch KDE Plasma: 5.11.5 Running glfw-x11-git out of the AUR.

jarcode-foss commented 6 years ago

Setting the xwintype to 'desktop', glava only shows on the active workspace when the program is initially run.

This is seemingly just how KDE Plasma handles desktop windows, they belong to a workspace (which might be an EWMH compliance issue, but the spec isn't clear on this). Do separate workspaces in KDE also have their own desktop icons?

Also, you can try to play around with window types other than "desktop" in GLava, as a temporary fix. I will research a way to get it to persist across workspaces later, when I get around to installing KDE.

Also, clicking on the desktop outside of the glava 'window' causes it to disappear. It'll still be running just not visible.

This is strange. This is almost certainly the desktop windows that KDE provides being reordered when you click them (ie. you are focusing the desktop background and it gets stacked over GLava), as if they are operating in their own layer for stacking windows -- but this makes no sense for desktop features!

A solution for KDE might just be to add code in GLava to make it run (optionally) as an actual KDE widget, since it looks like Plasma behaves weird in general.

jarcode-foss commented 6 years ago

I added a #request addxwinstate <state> directive that can be used to further tweak how the GLava window behaves. See https://standards.freedesktop.org/wm-spec/wm-spec-1.3.html#idm140130317598336 for details of what this (should) tell your WM.

Specifically for KDE Plasma, try:

#request addxwinstate "above"
#request addxwinstate "sticky"

As an attempt to solve both of your issues.

In the future, I may add an #request embed option (and command line flag) that automatically detects the WM in use and adds the specific state/type xwin requests behind the scenes, but I need to play around with other WMs a bit first.

jarcode-foss commented 6 years ago

Also, see this issue, as it may be related. I changed the default values for setfloating and setfocused to false in the default copy of rc.glsl, as it's unessecary and seemed to cause issues with some WMs.

jarcode-foss commented 6 years ago

I am unable to install KDE in a systemd-nspawn container, preventing me from testing this myself. If someone else could play with addxwinstate values and other requests on KDE, it would help me address this issue.

baduhai commented 6 years ago

I have the same problem @jpope777 described. I tried every single option from addxwinstate and some combinations of the options, including the suggested, but to no success. problem persists in the exact same manner as the original problem. I have also tried setting setxwintype to other options, but still nothing.

jarcode-foss commented 6 years ago

It looks like I will have to write GLava as an actual KDE widget to get it to work correctly.

flying-sheep commented 6 years ago

probably better would be a wallpaper engine, because i don’t think you can maximize widgets. like widgets, the engines work by writing QML and usually a DataSource. QML also has a few ways to include custom OpenGL code

another way would be to create widgets from the modules, which would forego the glava config in favor of the config GUI that KDE users are accustomed to.

a third option is to get in touch with the KDE devs. they’re friendly, responsive, and helpful, and will try to help you to get your approach to work (or give you a friendly and well-reasoned explanation why it can’t)

jarcode-foss commented 6 years ago

@flying-sheep thanks for your input. I will start with trying to get in touch with people that work more closely with KWin on IRC (or mailing lists).

jarcode-foss commented 6 years ago

Note: KDE 5.12+ supports Wayland -- if you are using Wayland instead of X11, you will run into numerous issues with transparency, window hints, etc. Try to avoid using the Plasma (Wayland) session when providing details on this issue, the aforementioned problems are separate from the problems mentioned here.

jarcode-foss commented 6 years ago

17 (recently fixed) may be related to the issues described here. Let me know if any of the fixes in unstable or for the 1.3 release are fixed with the relevant commit.

mmhobi7 commented 6 years ago

I had issues with plasma too but they're a bit unrelated: https://github.com/varlesh/xwinwrap/issues/1 Anyways, if it's still broken, one fix is to parent glava under the Plasma window (which contains wallpaper and clock) An example of this is here: https://github.com/Aaahh/xwinwrap/blob/master/xwinwrap.c#L245 sadly xwinwrap won't work on glava, as it creates a window that glava would have to output to, instead of editing glava's window, i'm working on it

jarcode-foss commented 6 years ago

@Aaahh that is extremely helpful. I will just implement this in GLava itself, see xwin.c for how GLava handles most X11-related tasks (other X11 code can be found in glx_wcb.c, but that is mostly for creating the OpenGL context).

xwinwrap probably doesn't work because you would need to perform some (possibly terrifying) hacks to redirect the GLX context to the new window it creates. I wouldn't worry about it not working with GLava.

Unfortunately this will have to wait until at least Monday, though.

mmhobi7 commented 6 years ago

Well I use it with mpv for example, as I can set the WID with a flag on mpv

I’m tweaking the code to modify the existing window rather than create one that is then passed. I already have code to modify an existing window and with XReparentWindow I can easily move it to the place I want

jarcode-foss commented 6 years ago

@Aaahh GLava (by default) will attempt to create a direct GLX context. This is probably why it's not working with xwinwrap. See the documentation from Khronos for ARB_create_context:

    Direct rendering is requested if <direct> is True, and indirect
    rendering if <direct> is False. If <direct> is True, the
    implementation may nonetheless create an indirect rendering context
    if any of the following conditions hold:

      * The implementation does not support direct rendering.
      * <display> is not a local X server.
      * Implementation-dependent limits on the number of direct
        rendering contexts that can be supported simultaneously are
        exceeded.

    Use glXIsDirect (see below) to determine whether or not a request
    for a direct rendering context succeeded.

Ultimately, GLava should be able to position itself accordingly without xwinwrap, so it's best if you either look to implement a solution in xwin.c or wait until I do so.

mmhobi7 commented 6 years ago

Try https://github.com/Aaahh/glava/commit/d0fcb3512d6325f9a68ffabe5af999c24573ae80

jarcode-foss commented 6 years ago

If anyone can comment on whether @Aaahh's fork fixes the issue, it would help me decide whether to keep poking at this issue or to just close it.

ephemient commented 6 years ago

image

Doesn't seem to do much for me.

mmhobi7 commented 6 years ago

set the window type to desktop

ephemient commented 6 years ago

image No visible difference with @Aaahh's branch or not.

jarcode-foss commented 6 years ago

@ephemient and workspaces are still broken with GLava on the desktop (the topic of this issue)?

jarcode-foss commented 6 years ago

If @Aaahh's attempted fix using XReparentWindow doesn't actually seem to fix the problem here, I will probably omit that code for 1.5. Calling XReparentWindow might confuse some window managers anyway, as the window will already be reparented once to the associated frame window created by the WM.

jpope777 commented 6 years ago

I just tried @Aaahh's branch and GLava still disappears whenever I left click on the desktop on the setxwintype set to desktop.

mmhobi7 commented 6 years ago

@jpope777 For the sake of experimentation https://github.com/Aaahh/xwinwrap Download that and run it with xwinwrap -ovr -s mpv https://www.youtube.com/watch?v=TV1767i8X4Q

r00tdaemon commented 6 years ago

Also, clicking on the desktop outside of the glava 'window' causes it to disappear. It'll still be running just not visible

I was having a similar problem with a terminal visualizer. Setting window_type to "utility" using devilspie seemed to work for me

Setting the xwintype to 'desktop', glava only shows on the active workspace when the program is initially run.

This was fixed for me using devilspie's (pin)

mmhobi7 commented 6 years ago

@ujjwal96 This is great, I'll load Plasma over the weekend or some time and try implementing a proper fix into glava Glava also suffers with multiple displays on ubuntu

jarcode-foss commented 6 years ago

I was having a similar problem with a terminal visualizer. Setting window_type to "utility" using devilspie seemed to work for me

@ujjwal96 does setting the window type to "utility" within GLava also fix the issue? These should affect the same property.

This was fixed for me using devilspie's (pin)

Looking into how devilspie pins windows, I finally found a solution for issues with multiple workspaces via the EWMH standards! Apparently, I missed this portion of the specification:

_NET_WM_DESKTOP desktop, CARDINAL/32

Cardinal to determine the desktop the window is in (or wants to be) starting with 0 for the first desktop. A Client MAY choose not to set this property, in which case the Window Manager SHOULD place it as it wishes. 0xFFFFFFFF indicates that the window SHOULD appear on all desktops.

So a simple client message may fix a wide range of workspace-related bugs. Apparently wmctrl can do this as well if you move a client to desktop of ID -1 (underflow).

r00tdaemon commented 6 years ago

@wacossusca34 Yes, setting window type to utility fixes the first issue.

For pinning you can see https://github.com/GNOME/devilspie/blob/e3431f18c11a1a80fd846c899a3f16aa5ee91de0/src/actions.c#L380-L384

It uses libwnck

jarcode-foss commented 6 years ago

The above commit allows the following line to pin GLava to all desktops:

#request addxwinstate "pinned"

The changes are non-breaking and don't affect anyone not using this option so I made the changes immediately to master, but they are untested. If @ujjwal96 or @jpope777 could report if this issue is fixed by the above commit, I can finally close this issue and look at creating an option in GLava that automatically sets all the needed X11 atoms and window types for the underlying WM.

jarcode-foss commented 6 years ago

Stacking order issues may be solved with #request addxwinstate "below", as mentioned in #54, due to the hint sometimes placing desktop windows in the same stacking order as other normal clients. If this works for kwin, then this issue can be finally closed!

mmhobi7 commented 6 years ago

I thought I didn't have a problem with this so it might be my install but "below" does literally nothing. I used to use it and it used to work but I can't be certain. My xwinwrap works perfect with below so I'm blaming glava. Using any window type

mmhobi7 commented 6 years ago

Haha jokes my WM is broken, I remember it working before but again I don't remember window.window = XCreateWindow(display, window.root, window.x, window.y, window.width, window.height, 0, depth, InputOutput, visual, flags, &attrs); if the parent is set to the root window it works.

jarcode-foss commented 6 years ago

Pinning issues should be fixed in master. Stacking order issues are going to be hard to address since KDE just plainly handles desktop windows strangely. I have created a new branch called kde_fixes with two new approaches to fix GLava hiding behind the desktop when the background (or icons) are selected:

I'm not sure how these approaches will actually effect KDE and need testing. The first might do nothing, or further confuse the WM. The second will definitely keep GLava above desktop windows, but I'm not sure if it will also be placed above regular windows as well.

@ujjwal96 @jpope777 @ephemient @flying-sheep please report if the kde_fixes branch improves the situation.

jarcode-foss commented 6 years ago

I finally got KDE running in a container (after a jumping through a few hoops). I found a solution, but the above attempts just make the problem worse because:

I discovered some strange things:

All this crazy nonsense when it comes to how the WM behaves with desktop windows in order to get the plasma shell to behave the way KDE developers want. Ideally, only the plasma shell should be subject to this treatment, probably with a KDE-specific property set on the window.

So I thought I should try "normal" windows, with the "below" state set (don't forget to disable borders and use native transparency). Turns out that works! No changes to GLava needed, but you can't click through to the desktop. @Aaahh provided a fix for this in other DEs, going to try applying that here on normal windows.

jarcode-foss commented 6 years ago

And it turns out the fix for click-through that @Aaahh provided works like a charm on KDE! I think I'm going to enable clickthrough by default. At the moment, you will want the following options for KDE (in addition to defaults):

#request setdecorated false
#request setxwintype "normal"
#request addxwinstate "below"
#request addxwinstate "skip_taskbar"
#request addxwinstate "skip_pager"
#request addxwinstate "pinned"

This should finally conclude this issue. Don't use real "desktop" windows on KDE. Also, the kde_fixes branch is garbage, don't use it.

jarcode-foss commented 6 years ago

The latest changes to master provide the above fix built into GLava. Just run with the --desktop flag now.

jarcode-foss commented 6 years ago

Testing this further, it looks like "Show Desktop" (Ctrl + F12 by default) will still hide the GLava window, although it restores itself when you select normal clients afterwards. Not a major issue, but I intend to fix it.

Turns out KDE has some (undocumented?) protocols: _KDE_NET_WM_TEMPORARY_RULES can be used to send non-standard rules to the window manager, including a 'force' below/above rule that strongly asserts the stacking order in KWin itself. For some reason the default EWMH below state is weaker, and only verifies the stacking order when regular clients are selected.

I had to dive into the source of KWin and kstart5 to figure this out. All of this insanity should just be default for desktop windows (like in other window managers!). Fun fact: conky suffers from these same issues and requires users to manually set window rules in KDE's "Window Management" settings menu.

scar45 commented 6 years ago

Continuing the troubleshooting we've been doing on Reddit, I have more information after testing the latest master. Upon running it for the first time, this was returned:

$> glava --desktop
Using backend: 'glx'
No presets for current desktop environment ("KWin"), using default presets for embedding
Failed to load default presets at '/home/scar45/.config/glava/env_default.glsl': No such file or directory

I copied the env_default.glsl from the source shaders directory into my ~/.config/glava directory, and then ran GLava with the --desktop flag. Everything started up fine, but when I clicked my desktop, GLava disappeared again. I'm not sure if I've done something wrong, or if there are no sane defaults for KWin per the message in stdout? Even after I copied the env_default.glsl file under .config/glava, I still get the "No presets for current desktop..." warning, though maybe this is safe to ignore.

I've also used the following params at the bottom of rc.glsl:

#request setdecorated false
#request setxwintype "normal"
#request addxwinstate "below"
#request addxwinstate "skip_taskbar"
#request addxwinstate "skip_pager"
#request addxwinstate "pinned"

Happy to help troubleshoot more when possible, and I hope I am not doing something wrong myself either. I've also recorded a quick video demo which shows the behaviour with these latest tests. Note that I am using KWin with compositing on, in a VM with a GeForce 1050Ti host GPU, and latte-dock is what blurs GLava.

jarcode-foss commented 6 years ago

@scar45 see my reply to you on reddit:

Yeah, you need to copy over env_KWin.glsl, as those are the settings for your window manager. Normally glava --copy-config will do this for you, but if you update with an older config, then you need to either run that again (will overwrite files) or copy over the files you want yourself.

Alternatively you can build GLava with make INSTALL=standalone and then run it in-place with ./glava, to use the configuration files in the shaders directory of the repository.

Also, note:

I've also used the following params at the bottom of rc.glsl [...]

Setting these flags with the --desktop flag in your rc.glsl will have poor results, since the --desktop flag *looks for presets in `env_.glslfiles** and ignoresaddxwinstateoptions inrc.glsl` to prevent conflicts. Additionally, the default presets will override to desktop window types, which are horribly broken on KDE (outdated).

RaitaroH commented 6 years ago

I had to dive into the source of KWin and kstart5 to figure this out. All of this insanity should just be default for desktop windows (like in other window managers!). Fun fact: conky suffers from these same issues and requires users to manually set window rules in KDE's "Window Management" settings menu.

I am quite sure I didn't do that. I just edited the conky file according to this.

own_window_type normal
own_window_hints undecorated,below,sticky,skip_taskbar,skip_pager

Window type set to desktop actually makes conky not transparent for me.

Back to Glava... I took this to wmctrl (not to say the #requests doesn't work, but even if I set the exact stuff as conky has... doesn't cut it).

wmctrl -r KWrite -b add,skip_taskbar,skip_pager - works as expected - kwrite disappeared from the taskbar. wmctrl -r KWrite -b add,below - works as expected.

Now, I did the same in glava, after I commented out the requests in my rc file. I even recopied the configs. I noticed that whatever I do, wmctrl doesn't do anything to glava.

jarcode-foss commented 6 years ago

@RaitaroH

I am quite sure I didn't do that. I just edited the conky file according to this.

The conky config you linked is precisely what GLava does/allows, look at the hints themselves.

Now, I did the same in glava, after I commented out the requests in my rc file.

Note that if you are using --desktop, it will prioritize options from env_KWin.glsl. If you updated an existing older install, you will need to copy over the new configs/shaders. You shouldn't really need to set anything yourself, as I'm trying to provide defaults for each WM that handles these issues gracefully.

You didn't really specify what the problem with GLava's window was. Is it not visible, or is it just stacking issues again (ie. stuck under wallpaper)? If it's not visible to do off-screen placement, I have noticed that KDE saves window positions and will happily ignore where applications initially map their windows to. You can work around this at the moment with #request setforcegeometry true.

I noticed that whatever I do, wmctrl doesn't do anything to glava.

That's weird. You should verify it's setting the atoms properly with xprop -- if it's not, it could be a bug with wmctrl. Otherwise, it could be the window manager just not reading changes due to some strange combination of GLava's hints and wmctrl.

RaitaroH commented 6 years ago

@wacossusca34 well again, seems to me that GLava is treated a bit differently. wmctrl -r ignores it but wmctrl -l finds it. "above" in kde plasma doesn't also mean above fullscreen thus glava is not also above fullscreen apps, and the taskbar is skipped and all but the alt+tab is not (though conky is).

Glava shows fine for me. I can click through, it is above (not fullscreen stuff). I just pointed out that wmctrl doesn't apply rules to it.

jarcode-foss commented 6 years ago

@RaitaroH you might want to try "above" with other window types, like "dock" or "splash". Also, KDE doesn't list desktop windows in its client list, which wmctrl reads from, so that's where your issue is.

RaitaroH commented 6 years ago

@wacossusca34 Ok so I will post here my kwin config:

#request setdecorated false
#request setxwintype "normal"
#request addxwinstate "undecorated"
#request addxwinstate "above"
// #request addxwinstate "below"
#request addxwinstate "skip_taskbar"
#request addxwinstate "skip_pager"
#request addxwinstate "pinned"
#request addxwinstate "sticky"
#request setclickthrough true

Keeping everything the same.... but changing window typing:

So after all that I can say that... dock is the least intrusive but if you want glava to stay on top of fullscreen stuff you need to have it appear in the alt-tab switcher and focus it. if #65 would be fixed then awesome.

jarcode-foss commented 6 years ago

@RaitaroH unfortunately "above" windows are going to have X11 and/or WM limitations, especially with fullscreen windows that use the override_redirect attribute. Windows that use _NET_WM_STATE_FULLSCREEN seem to have similar restrictions on many WMs, including my own.

If you want anything to be visible above fullscreen windows it will need to maintain focus in most (if not all) WMs. To do this, you will need to use a less-than-optimal solution, but I have already written it into GLava since I expected some people would want forced focus:

#request setfullscreencheck false
#request setforceraised true

setforceraised is unusable on my WM and I predict it will cause problems on KDE. It's deprecated because it essentially steals focus repetitively (edit: outdated):

static void raise(struct glxwin* w) {
    XClientMessageEvent ev = {
        .type = ClientMessage,
        .serial = 0,
        .send_event = true,
        .display = display,
        .window = w->w,
        .message_type = ATOM__NET_ACTIVE_WINDOW,
        .format = 32,
        .data = { .l = {
                [0] = 1, /* source indication -- `1` when coming from an application */
                [1] = 0, /* timestamp -- `0` to (attempt to) ignore */
                [2] = w->w  /* requestor's currently active window -- `0` for none */
            }
        }
    };
    /* Send the client message as defined by EWMH standards (usually works) */
    XSendEvent(display, DefaultRootWindow(display), false, StructureNotifyMask, (XEvent*) &ev);
    /* Raise the client in the X11 stacking order (sometimes works, can be blocked by the WM) */
    XRaiseWindow(display, w->w);
    XFlush(display);
}

So unless you want to juggle window focus around, you are not going to be able to see GLava on top of fullscreen windows. It's possible to write a better focus-grabbing implementation that works only when windows are fullscreen, but it gets complicated when you want to interact with the fullscreen window since that will cause the WM to restack the window -- I would then need to listen to visibility notify X11 events to raise immediately after, which still might briefly cause GLava to lose visibility.

At this point I'll make two final suggestions for your issue (#65):

The latter suggestion is undeniably the best option here, but it's something better suited to external utilities (wmctrl) to accomplish that.

edit: also see added "!+" unmanaged window type

jarcode-foss commented 6 years ago

It's worth noting some users have ran into placement issues on KDE when KWin tries to re-position GLava when its window is mapped, probably from some saved position. This is fixable via setforcegeometry, however, that is not an optimal solution due to using periodic X11 calls. Unfortunately this may also require usage of non-standard protocols for KWin.

irgendwr commented 4 years ago

Is there a way to get transparency working on KDE (KWin)? With setopacity "native" the background stays black and with setopacity "xroot" weird things happen (backgroud filled with previous window content but not cleared).

qqpp4130 commented 4 years ago

@wacossusca34 Ok so I will post here my kwin config:

#request setdecorated false
#request setxwintype "normal"
#request addxwinstate "undecorated"
#request addxwinstate "above"
// #request addxwinstate "below"
#request addxwinstate "skip_taskbar"
#request addxwinstate "skip_pager"
#request addxwinstate "pinned"
#request addxwinstate "sticky"
#request setclickthrough true

Keeping everything the same.... but changing window typing:

  • normal [x] minimize all will minimeze glava [x] glava appears in alt+tab [x] stays above other windows [ ] stays above fullscreen applications
  • splash [x] minimize all will minimize glava [ ] glava appears in alt+tab > thus I cannot focus it in order to stay above fullscreen [ ] stays above other windows [ ] stays above fullscreen applications
  • dock/utility [ ] minimize all will minimize glava [ ] glava appears in alt+tab [x] stays above other windows [ ] stays above fullscreen applications Also #request addxwinstate "skip_taskbar"; #request addxwinstate "skip_pager" doesn't matter here.
  • desktop [x] takes over the desktop entirely: no wallpaper, icons; after a click it dies... [ ] minimize all will minimize glava [ ] glava appears in alt+tab [ ] stays above other windows [ ] stays above fullscreen applications

So after all that I can say that... dock is the least intrusive but if you want glava to stay on top of fullscreen stuff you need to have it appear in the alt-tab switcher and focus it. if #65 would be fixed then awesome.

Your config is totaly working, I got some workaround though. If using KDE, there is a section in KDE settings called Window Rules. Try to make changes there and set the window type to ! in rc.glsl and set the window type there, it shall fix the problem. I setted to dock(pannel), it works perfectly except above all desktop icons. for my condition.

jnishwanth commented 3 years ago

Hello, I don't know if this is useful enough, but setting a new window rule like given in the image below seems to solve this problem image I have set the window type for glava to be a dock

Doing the same in the config file doesn't seem to have the same effect of fixing this issue.

danbulant commented 3 years ago

Doing the above does work, but glava then won't correctly detect when it's fully obscured, so performance may suffer in that case.