Author: bgstack15 Date: 2022-11-26 Version: fluxbox 1.4.0 Source: bgstack15 Summary: Add "(on $CLIENT)" to titlebar for forwarded windows Message: Inspired by xfwm4's ability to display the remote host running an X11 window. This fails on xfe which somehow lacks the WM_CLIENT_MACHINE property. --- a/doc/asciidoc/fluxbox.txt +++ b/doc/asciidoc/fluxbox.txt @@ -1084,6 +1084,12 @@ across the edge of the screen. + Default: *True* +*session.screen0.showClientmachine*: 'boolean':: +This enables in the titlebar an indication of forwarded client windows +with "(on $CLIENT)" appended to the main title. ++ +Default: *True* + *session.screen0.showwindowposition*: 'boolean':: Setting this resource to True shows the user, in a little window, the exact position of the application window while the user is --- a/nls/C/Translation.m +++ b/nls/C/Translation.m @@ -83,6 +83,7 @@ $set 4 #Configmenu 27 Ignore Resize Increment 28 Disable Moving 29 Disable Resizing +33 Show clientmachine $set 5 #Ewmh_OBSOLETE --- a/nls/fluxbox-nls.hh +++ b/nls/fluxbox-nls.hh @@ -90,6 +90,7 @@ enum { ConfigmenuStrictMouseFocus = 30, ConfigmenuFocusSameHead = 31, ConfigmenuOpaqueResize = 32, + ConfigmenuWorkspaceShowClientmachine = 33, EwmhSet = 5, EwmhOutOfMemoryClientList = 1, --- a/src/ConfigMenu.cc +++ b/src/ConfigMenu.cc @@ -344,6 +344,10 @@ void ConfigMenu::setup(FbTk::Menu& menu, "Workspace Warping", "Workspace Warping - dragging windows to the edge and onto the next workspace", sh.resource.workspace_warping, saverc_cmd); + _BOOLITEM(menu, Configmenu, WorkspaceShowClientmachine, + "Show (on $CLIENT)", + "Show clientmachine if not running on localhost", + sh.resource.show_clientmachine, saverc_cmd); #undef _BOOLITEM --- a/src/Screen.hh +++ b/src/Screen.hh @@ -99,6 +99,7 @@ public: bool isWorkspaceWarpingVertical() const { return isWorkspaceWarping() && *resource.workspace_warping_vertical; } int getWorkspaceWarpingHorizontalOffset() const { return *resource.workspace_warping_horizontal_offset; } int getWorkspaceWarpingVerticalOffset() const { return *resource.workspace_warping_vertical_offset; } + bool isShowClient() const { return *resource.show_clientmachine; } bool doAutoRaise() const { return *resource.auto_raise; } bool clickRaises() const { return *resource.click_raises; } bool doOpaqueMove() const { return *resource.opaque_move; } --- a/src/ScreenResource.cc +++ b/src/ScreenResource.cc @@ -93,6 +93,7 @@ ScreenResource::ScreenResource(FbTk::Res workspace_warping_vertical(rm, true, scrname+".workspacewarpingvertical", altscrname+".WorkspaceWarpingVertical"), workspace_warping_horizontal_offset(rm, 1, scrname+".workspacewarpinghorizontaloffset", altscrname+".WorkspaceWarpingHorizontalOffset"), workspace_warping_vertical_offset(rm, 1, scrname+".workspacewarpingverticaloffset", altscrname+".WorkspaceWarpingVerticalOffset"), + show_clientmachine(rm, true, scrname+".showClientmachine", altscrname+".ShowClientmachine"), show_window_pos(rm, false, scrname+".showwindowposition", altscrname+".ShowWindowPosition"), auto_raise(rm, true, scrname+".autoRaise", altscrname+".AutoRaise"), click_raises(rm, true, scrname+".clickRaises", altscrname+".ClickRaises"), --- a/src/ScreenResource.hh +++ b/src/ScreenResource.hh @@ -40,6 +40,7 @@ struct ScreenResource { workspace_warping, workspace_warping_horizontal, workspace_warping_vertical, + show_clientmachine, show_window_pos, auto_raise, click_raises; --- a/src/WinClient.cc +++ b/src/WinClient.cc @@ -49,6 +49,7 @@ #else #include #endif +#include using std::string; using std::list; @@ -104,6 +105,8 @@ WinClient::WinClient(Window win, BScreen updateWMHints(); updateWMNormalHints(); updateWMClassHint(); + gethostname(hostname_char, 512); + hostname = FbTk::FbString(hostname_char); updateTitle(); Fluxbox::instance()->saveWindowSearch(win, this); if (window_group != None) @@ -217,6 +220,10 @@ bool WinClient::getAttrib(XWindowAttribu return XGetWindowAttributes(display(), window(), &attr); } +bool WinClient::getWMClientMachine(XTextProperty &textprop) const { + return XGetWMClientMachine(display(), window(), &textprop); +} + bool WinClient::getWMName(XTextProperty &textprop) const { return XGetWMName(display(), window(), &textprop); } @@ -319,7 +326,14 @@ void WinClient::updateTitle() { if (m_title_override) return; - m_title.setLogical(FbTk::FbString(Xutil::getWMName(window()), 0, 512)); + FbTk::FbString fullname = FbTk::FbString(Xutil::getWMName(window()), 0, 512); + if (m_screen.isShowClient()) { + FbTk::FbString clientmachine = FbTk::FbString(Xutil::getWMClientMachine(window()), 0, 512); + if (clientmachine != "Unnamed" && clientmachine != "" && clientmachine != hostname) { + fullname += " (on " + clientmachine + ")"; + } + } + m_title.setLogical(fullname); m_title_update_timer.start(); } @@ -328,7 +342,14 @@ void WinClient::emitTitleSig() { } void WinClient::setTitle(const FbTk::FbString &title) { - m_title.setLogical(title); + FbTk::FbString fullname = title; + if (m_screen.isShowClient()) { + FbTk::FbString clientmachine = FbTk::FbString(Xutil::getWMClientMachine(window()), 0, 512); + if (clientmachine != "Unnamed" && clientmachine != "" && clientmachine != hostname) { + fullname += " (on " + clientmachine + ")"; + } + } + m_title.setLogical(fullname); m_title_override = true; m_title_update_timer.start(); } --- a/src/WinClient.hh +++ b/src/WinClient.hh @@ -91,6 +91,7 @@ public: // bool getAttrib(XWindowAttributes &attr) const; + bool getWMClientMachine(XTextProperty &textprop) const; bool getWMName(XTextProperty &textprop) const; bool getWMIconName(XTextProperty &textprop) const; std::string getWMRole() const; @@ -141,6 +142,8 @@ public: unsigned long initial_state, normal_hint_flags, wm_hint_flags; private: + char hostname_char[512]; + FbTk::FbString hostname; /// removes client from any waiting list and clears empty waiting lists void removeTransientFromWaitingList(); --- a/src/Xutil.cc +++ b/src/Xutil.cc @@ -43,6 +43,51 @@ using std::endl; namespace Xutil { +FbTk::FbString getWMClientMachine(Window window) { + + if (window == None) + return FbTk::FbString(""); + + Display *display = FbTk::App::instance()->display(); + + XTextProperty text_prop; + text_prop.value = 0; + char **list = 0; + int num = 0; + _FB_USES_NLS; + FbTk::FbString name; + + if (XGetWMClientMachine(display, window, &text_prop)) { + if (text_prop.value && text_prop.nitems > 0) { + if (text_prop.encoding != XA_STRING) { + + text_prop.nitems = strlen((char *) text_prop.value); + XmbTextPropertyToTextList(display, &text_prop, &list, &num); + + if (num > 0 && list != 0) + name = FbTk::FbStringUtil::LocaleStrToFb(static_cast(*list)); + else + name = text_prop.value ? FbTk::FbStringUtil::XStrToFb((char *)text_prop.value) : ""; + + if (list) + XFreeStringList(list); + + } else + name = text_prop.value ? FbTk::FbStringUtil::XStrToFb((char *)text_prop.value) : ""; + + XFree(text_prop.value); + + } else { // default name + name = _FB_XTEXT(Window, Unnamed, "Unnamed", "Default name for a window without a WM_NAME"); + } + } else { + // default name + name = _FB_XTEXT(Window, Unnamed, "Unnamed", "Default name for a window without a WM_NAME"); + } + + return name; +} + FbTk::FbString getWMName(Window window) { if (window == None) --- a/src/Xutil.hh +++ b/src/Xutil.hh @@ -28,6 +28,7 @@ namespace Xutil { +FbTk::FbString getWMClientMachine(Window window); FbTk::FbString getWMName(Window window); FbTk::FbString getWMClassName(Window win);