flightlessmango / MangoHud

A Vulkan and OpenGL overlay for monitoring FPS, temperatures, CPU/GPU load and more. Discord: https://discordapp.com/invite/Gj5YmBb
MIT License
6.35k stars 281 forks source link

Display currently running display server (X11/XWayland or Wayland) #542

Open Faalagorn opened 3 years ago

Faalagorn commented 3 years ago

Would it be possible to show whether an app is running with X11 or Wayland? I use xeyes for that currently, but maybe there's some more clever way for it? It could be displayed next to the architecture in the same line, as there's quite some space here. screenshot_2021-06-13-111847

dpanter commented 3 years ago

Something like this for a quick workaround?

custom_text=Session:
exec=printf $XDG_SESSION_TYPE

Screenshot_20210613_143632

Faalagorn commented 3 years ago

custom_text=Session: exec=printf $XDG_SESSION_TYPE

While handy, this sadly only displays the whole session you are in, not whether or not application is running natively or not. Might not be as easy to do I guess, but since xeyes running as regular application can interact with xwayland programs but not the native wayland ones, I think it should somehow be possible to implement? (plus it would be especially interesting to see if/when more native Wayland apps, including Wine gets more popular as it seems to be the case now)

screenshot_2021-06-13-151544

rhysperry111 commented 2 years ago

Xorg has added an extension to check whether an application is running though normal X11 or through Xwayland. Maybe this feature can finally be looked at?

There is also this shell program provided by them which implements the protocol.

Lassebq commented 2 months ago

bump

flightlessmango commented 2 months ago

Patch for display session, needs testers

index 41e3f4e..8890d74 100644
--- a/src/hud_elements.cpp
+++ b/src/hud_elements.cpp
@@ -1475,6 +1475,20 @@ void HudElements::network() {
 #endif
 }

+void HudElements::_display_session() {
+    ImGui::PushFont(HUDElements.sw_stats->font1);
+    ImguiNextColumnFirstItem();
+    HUDElements.TextColored(HUDElements.colors.engine, "%s", "session");
+    ImguiNextColumnOrNewRow();
+    static std::map<display_sessions, std::string> sessions {
+        {WAYLAND, {"WAYLAND"}},
+        {XWAYLAND, {"XWAYLAND"}},
+        {XORG, {"XORG"}}
+    };
+    right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%s", sessions[HUDElements.display_session].c_str());
+    ImGui::PopFont();
+}
+
 void HudElements::sort_elements(const std::pair<std::string, std::string>& option) {
     const auto& param = option.first;
     const auto& value = option.second;
@@ -1522,7 +1536,8 @@ void HudElements::sort_elements(const std::pair<std::string, std::string>& optio
         {"refresh_rate", {refresh_rate}},
         {"winesync", {winesync}},
         {"present_mode", {present_mode}},
-        {"network", {network}}
+        {"network", {network}},
+        {"display_session", {_display_session}}

     };

@@ -1650,6 +1665,8 @@ void HudElements::legacy_elements(){
         ordered_functions.push_back({present_mode, "present_mode", value});
     if (params->enabled[OVERLAY_PARAM_ENABLED_refresh_rate])
         ordered_functions.push_back({refresh_rate, "refresh_rate", value});
+    if (params->enabled[OVERLAY_PARAM_ENABLED_display_session])
+        ordered_functions.push_back({_display_session, "display_session", value});
 }

 void HudElements::update_exec(){
diff --git a/src/hud_elements.h b/src/hud_elements.h
index 08c3b7e..321d96e 100644
--- a/src/hud_elements.h
+++ b/src/hud_elements.h
@@ -11,6 +11,7 @@
 #include "net.h"
 #include "overlay_params.h"
 #include "shell.h"
+#include "shared_x11.h"

 struct Function {
     std::function<void()> run;  // Using std::function instead of a raw function pointer for more flexibility
@@ -53,6 +54,7 @@ class HudElements{
         int hdr_status = 0;
         int refresh = 0;
         unsigned int vsync = 10;
+        display_sessions display_session = WAYLAND;
         std::unique_ptr<WineSync> winesync_ptr = nullptr;
         std::unique_ptr<Net> net = nullptr;
 #ifdef __linux__
@@ -104,6 +106,7 @@ class HudElements{
         static void winesync();
         static void present_mode();
         static void network();
+        static void _display_session();

         void convert_colors(const struct overlay_params& params);
         void convert_colors(bool do_conv, const struct overlay_params& params);
diff --git a/src/loaders/loader_x11.cpp b/src/loaders/loader_x11.cpp
index dc59927..214fd50 100644
--- a/src/loaders/loader_x11.cpp
+++ b/src/loaders/loader_x11.cpp
@@ -77,6 +77,14 @@ bool libx11_loader::Load(const std::string& library_name) {
     return false;
   }

+  XQueryExtension =
+      reinterpret_cast<decltype(this->XQueryExtension)>(
+          dlsym(library_, "XQueryExtension"));
+  if (!XQueryExtension) {
+    CleanUp(true);
+    return false;
+  }
+
   loaded_ = true;
   return true;
 }
@@ -94,6 +102,7 @@ void libx11_loader::CleanUp(bool unload) {
   XKeysymToKeycode = NULL;
   XStringToKeysym = NULL;
   XGetGeometry = NULL;
+  XQueryExtension = NULL;

 }

diff --git a/src/loaders/loader_x11.h b/src/loaders/loader_x11.h
index 8861985..c6e2054 100644
--- a/src/loaders/loader_x11.h
+++ b/src/loaders/loader_x11.h
@@ -21,6 +21,7 @@ class libx11_loader {
   decltype(&::XKeysymToKeycode) XKeysymToKeycode;
   decltype(&::XStringToKeysym) XStringToKeysym;
   decltype(&::XGetGeometry) XGetGeometry;
+  decltype(&::XQueryExtension) XQueryExtension;

  private:
diff --git a/src/shared_x11.cpp b/src/shared_x11.cpp
index 2122310..49b2969 100644
--- a/src/shared_x11.cpp
+++ b/src/shared_x11.cpp
@@ -5,6 +5,7 @@
 #include <spdlog/spdlog.h>
 #include "shared_x11.h"
 #include "loaders/loader_x11.h"
+#include "hud_elements.h"

 static std::unique_ptr<Display, std::function<void(Display*)>> display;

@@ -41,6 +42,15 @@ bool init_x11() {
     if (!displayid)
         SPDLOG_DEBUG("DISPLAY env is not set");

+    if (display) {
+        int opcode, event, error;
+        if (libx11->XQueryExtension(display.get(), "XWAYLAND", &opcode, &event, &error))
+           HUDElements.display_session = XWAYLAND;
+        else
+            HUDElements.display_session = XORG;
+
+   }
+
     return !!display;
 }

diff --git a/src/shared_x11.h b/src/shared_x11.h
index 8379857..2ca669f 100644
--- a/src/shared_x11.h
+++ b/src/shared_x11.h
@@ -7,4 +7,10 @@
 Display* get_xdisplay();
 bool init_x11();

+enum display_sessions {
+    WAYLAND,
+    XWAYLAND,
+    XORG
+};
+
 #endif //MANGOHUD_SHARED_X11_H
flightlessmango commented 2 months ago

should have mentioned that the option is display_session

Lassebq commented 2 months ago

Patch applied successfully but build fails with

../MangoHud/src/hud_elements.cpp:1668:25: error: ‘OVERLAY_PARAM_ENABLED_display_session’ was not declared in this scope; did you mean ‘OVERLAY_PARAM_ENABLED_engine_version’?
 1668 |     if (params->enabled[OVERLAY_PARAM_ENABLED_display_session])
flightlessmango commented 2 months ago

Must have forgotten to include overlay_params.h

index 41e3f4e..8890d74 100644
--- a/src/hud_elements.cpp
+++ b/src/hud_elements.cpp
@@ -1475,6 +1475,20 @@ void HudElements::network() {
 #endif
 }

+void HudElements::_display_session() {
+    ImGui::PushFont(HUDElements.sw_stats->font1);
+    ImguiNextColumnFirstItem();
+    HUDElements.TextColored(HUDElements.colors.engine, "%s", "session");
+    ImguiNextColumnOrNewRow();
+    static std::map<display_sessions, std::string> sessions {
+        {WAYLAND, {"WAYLAND"}},
+        {XWAYLAND, {"XWAYLAND"}},
+        {XORG, {"XORG"}}
+    };
+    right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%s", sessions[HUDElements.display_session].c_str());
+    ImGui::PopFont();
+}
+
 void HudElements::sort_elements(const std::pair<std::string, std::string>& option) {
     const auto& param = option.first;
     const auto& value = option.second;
@@ -1522,7 +1536,8 @@ void HudElements::sort_elements(const std::pair<std::string, std::string>& optio
         {"refresh_rate", {refresh_rate}},
         {"winesync", {winesync}},
         {"present_mode", {present_mode}},
-        {"network", {network}}
+        {"network", {network}},
+        {"display_session", {_display_session}}

     };

@@ -1650,6 +1665,8 @@ void HudElements::legacy_elements(){
         ordered_functions.push_back({present_mode, "present_mode", value});
     if (params->enabled[OVERLAY_PARAM_ENABLED_refresh_rate])
         ordered_functions.push_back({refresh_rate, "refresh_rate", value});
+    if (params->enabled[OVERLAY_PARAM_ENABLED_display_session])
+        ordered_functions.push_back({_display_session, "display_session", value});
 }

 void HudElements::update_exec(){
diff --git a/src/hud_elements.h b/src/hud_elements.h
index 08c3b7e..321d96e 100644
--- a/src/hud_elements.h
+++ b/src/hud_elements.h
@@ -11,6 +11,7 @@
 #include "net.h"
 #include "overlay_params.h"
 #include "shell.h"
+#include "shared_x11.h"

 struct Function {
     std::function<void()> run;  // Using std::function instead of a raw function pointer for more flexibility
@@ -53,6 +54,7 @@ class HudElements{
         int hdr_status = 0;
         int refresh = 0;
         unsigned int vsync = 10;
+        display_sessions display_session = WAYLAND;
         std::unique_ptr<WineSync> winesync_ptr = nullptr;
         std::unique_ptr<Net> net = nullptr;
 #ifdef __linux__
@@ -104,6 +106,7 @@ class HudElements{
         static void winesync();
         static void present_mode();
         static void network();
+        static void _display_session();

         void convert_colors(const struct overlay_params& params);
         void convert_colors(bool do_conv, const struct overlay_params& params);
diff --git a/src/loaders/loader_x11.cpp b/src/loaders/loader_x11.cpp
index dc59927..214fd50 100644
--- a/src/loaders/loader_x11.cpp
+++ b/src/loaders/loader_x11.cpp
@@ -77,6 +77,14 @@ bool libx11_loader::Load(const std::string& library_name) {
     return false;
   }

+  XQueryExtension =
+      reinterpret_cast<decltype(this->XQueryExtension)>(
+          dlsym(library_, "XQueryExtension"));
+  if (!XQueryExtension) {
+    CleanUp(true);
+    return false;
+  }
+
   loaded_ = true;
   return true;
 }
@@ -94,6 +102,7 @@ void libx11_loader::CleanUp(bool unload) {
   XKeysymToKeycode = NULL;
   XStringToKeysym = NULL;
   XGetGeometry = NULL;
+  XQueryExtension = NULL;

 }

diff --git a/src/loaders/loader_x11.h b/src/loaders/loader_x11.h
index 8861985..c6e2054 100644
--- a/src/loaders/loader_x11.h
+++ b/src/loaders/loader_x11.h
@@ -21,6 +21,7 @@ class libx11_loader {
   decltype(&::XKeysymToKeycode) XKeysymToKeycode;
   decltype(&::XStringToKeysym) XStringToKeysym;
   decltype(&::XGetGeometry) XGetGeometry;
+  decltype(&::XQueryExtension) XQueryExtension;

  private:
diff --git a/src/overlay_params.h b/src/overlay_params.h
index dbf2683..e4668ec 100644
--- a/src/overlay_params.h
+++ b/src/overlay_params.h
@@ -114,6 +114,7 @@ typedef unsigned long KeySym;
    OVERLAY_PARAM_BOOL(winesync)                      \
    OVERLAY_PARAM_BOOL(present_mode)                  \
    OVERLAY_PARAM_BOOL(time_no_label)                 \
+   OVERLAY_PARAM_BOOL(display_session)               \
    OVERLAY_PARAM_CUSTOM(fps_sampling_period)         \
    OVERLAY_PARAM_CUSTOM(output_folder)               \
    OVERLAY_PARAM_CUSTOM(output_file)                 \
diff --git a/src/shared_x11.cpp b/src/shared_x11.cpp
index 2122310..49b2969 100644
--- a/src/shared_x11.cpp
+++ b/src/shared_x11.cpp
@@ -5,6 +5,7 @@
 #include <spdlog/spdlog.h>
 #include "shared_x11.h"
 #include "loaders/loader_x11.h"
+#include "hud_elements.h"

 static std::unique_ptr<Display, std::function<void(Display*)>> display;

@@ -41,6 +42,15 @@ bool init_x11() {
     if (!displayid)
         SPDLOG_DEBUG("DISPLAY env is not set");

+    if (display) {
+        int opcode, event, error;
+        if (libx11->XQueryExtension(display.get(), "XWAYLAND", &opcode, &event, &error))
+           HUDElements.display_session = XWAYLAND;
+        else
+            HUDElements.display_session = XORG;
+
+   }
+
     return !!display;
 }

diff --git a/src/shared_x11.h b/src/shared_x11.h
index 8379857..2ca669f 100644
--- a/src/shared_x11.h
+++ b/src/shared_x11.h
@@ -7,4 +7,10 @@
 Display* get_xdisplay();
 bool init_x11();

+enum display_sessions {
+    WAYLAND,
+    XWAYLAND,
+    XORG
+};
+
 #endif //MANGOHUD_SHARED_X11_H
Lassebq commented 2 months ago

With above patch for wayland native applications mangohud still says XWAYLAND. Distinction between XOrg and XWayland does work though.

flightlessmango commented 2 months ago

If it says it's xwayland, it means it was able to connect to a xorg server and check the extension. So I'm thinking either the app isn't actually native wayland or we are connecting to other xwayland servers that are running out of scope of this app

Lassebq commented 2 months ago

eglgears_wayland cannot possibly run through xwayland. This also happens for SDL apps with SDL_VIDEODRIVER=wayland. I can additionally confirm this by using an X utility such as wmctrl to query windows list. It's empty.