Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
Faalagorn opened this issue Jun 13, 2021 · 11 comments
Open

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

Faalagorn opened this issue Jun 13, 2021 · 11 comments

Comments

@Faalagorn
Copy link
Contributor

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
Copy link

dpanter commented Jun 13, 2021

Something like this for a quick workaround?

custom_text=Session:
exec=printf $XDG_SESSION_TYPE

Screenshot_20210613_143632

@Faalagorn
Copy link
Contributor Author

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
Copy link

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
Copy link

Lassebq commented Jun 22, 2024

bump

@flightlessmango
Copy link
Owner

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
Copy link
Owner

should have mentioned that the option is display_session

@Lassebq
Copy link

Lassebq commented Jul 10, 2024

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
Copy link
Owner

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
Copy link

Lassebq commented Jul 10, 2024

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

@flightlessmango
Copy link
Owner

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
Copy link

Lassebq commented Jul 10, 2024

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants