Hacking in PrettyOSD positioning on KDE Wayland
-
I've been using strawberry on KDE for a few years now.
From the start I've loved the "pretty OSD" style of notifications. They're just so much better than native ones.
They work great under X11, but ever since I've moved to Wayland, the rough edges of that display protocol were apparent every time the OSD appeared... the OSD would always spawn in the middle of the screen, which is just sad.Now while I understand that this is a shortcoming of the Wayland protocols, that probably won't be resolved anytime soon (even though it should) and that the strawberry project can do nothing to resolve the issue for every Wayland user out there... this doesn't stop individual users (like myself) from hacking in solutions for their own use cases.
So KDE has this neat feature called "window rules". It basically allows me to create sets rules for specific windows, provided that there's a way to select the desired window. These rules may include forcing a specific positioning of a window, which would be quite helpful in this case.There's only one issue. I couldn't find a way to distinguish the main strawberry player window from the OSD "window". Having the whole player be stuck to the top right corner of my screen wouldn't be ideal.
That's why I've been running a patched version of strawberry for the past few months. One with literally just a one line patch that simply sets the title of the OSD window to "PrettyOSD". This makes it possible to match the OSD window by its new title.Now while this is a change that I made only to enable a DE-specific hack, I think it's quite a sensible change to make outside of this hack context.
I'll attach the patch I use below as a reference, but keep in mind that I've got almost no C++ experience and this might be the worst way to implement my general idea. I didn't use any AI "help" though, if that makes anyone more confident about the quality of that hacky patch.diff --git a/src/osd/osdpretty.cpp b/src/osd/osdpretty.cpp index c89a8504..00cd24c7 100644 --- a/src/osd/osdpretty.cpp +++ b/src/osd/osdpretty.cpp @@ -100,6 +100,7 @@ OSDPretty::OSDPretty(Mode mode, QWidget *parent) Qt::WindowFlags flags = Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::X11BypassWindowManagerHint; setWindowFlags(flags); + setWindowTitle(QString::fromUtf8("PrettyOSD", -1)); setAttribute(Qt::WA_TranslucentBackground, true); setAttribute(Qt::WA_X11NetWmWindowTypeNotification, true); setAttribute(Qt::WA_ShowWithoutActivating, true);
-
I use the OSD pretty too, but I use X11 on all my machines. But I've noticed that the OSD pretty window can not be positioned under Wayland, have only looked into it briefly a while ago.
Setting the title shouldn't cause any issues as far as I know, so that can be done.
UsingQString::fromUtf8
isn't necessary there,QStringLiteral()
(and can be simplified tou""_s
) should be used there instead to avoid string conversions at runtime since the function takesQString
. -
Adding
Qt::Popup
to window flags has some affect, I'm able to position the window on some parts of the screen, but it's still very buggy. I use nvidia, so wayland is buggy in general. Maybe you can try. -
QWidget::move
doesn't have any affect under Wayland when dragging the widget, but it works if I removeQt::FramelessWindowHint
and drag by the window title. SettingQt::Popup
I can drag the widget itself, but that makes it a modal window, and it's pretty flaky. -
@jonas
I expected there to be a much simpler way to create a literal QString, but as I've said, I've got almost no C++ (let alone Qt) experience. That's one reason why I created a forum post rather than a pull request on the repo. Thanks for the insight though.As for wayland on nvidia: I myself also use an nvidia system and wayland on nvidia has been stable for some time now on the latest drivers. I wouldn't have been using it otherwise.
I haven't done any extensive or exhaustive research, but I'm pretty sure there isn't a real way to position windows programmatically on wayland yet. There simply isn't a protocol in the suite to support this. And if there was, you'd expect the framework to implement it. I wouldn't have settled on this hack if I saw a viable way to properly implement this.
I've also just tried forcing strawberry to run through xwayland (by settingQT_QPA_PLATFORM=xcb
) and the pretty OSD appears to just™
work™
there without any hacks needed