ecal icon indicating copy to clipboard operation
ecal copied to clipboard

eCAL Sys: Bring Window to front

Open FlorianReimold opened this issue 2 years ago • 4 comments

Description

The goal is to have some kind of "Bring to front" functionality in eCAL Sys, probably from the context menu of tasks.

eCAL Sys must still function headless, so if it means binding the ecal_sys_core to a GUI Lib (like xlib) additional measures must be taken to not break headless support. For embedded systems there probably should be a CMake Switch entirely removing the GUI dependency.

How to tacle

  • [ ] Implement Sample Code
    • for Windows
    • for X11
    • for Wayland
  • [ ] Move the code to ecal_sys_core
  • [ ] Add CMake Switch / code etc. to disable that feature for headless systems
  • [ ] Add RPC Call
  • [ ] Add GUI Code

Screenhot

The functionality should be similar to what many task managers offer:

grafik

FlorianReimold avatar Mar 24 '22 07:03 FlorianReimold

Not meaning to be destructive here, but is this really a feature that eCAL Sys should have? The focus of Sys is on managing group of tasks, e.g. providing start / stop functionality. Should user interaction (e.g. bring something to the front) really be part of that? I am a bit skeptical.

Kerstin-Keller avatar Mar 24 '22 08:03 Kerstin-Keller

That has to be discussed.

The feature was requested to me in person and so I wanted to put it here for discussion and to not forget about it. eCAL Sys already supports a very limited window management:

  • Starting minimized / normal / maximized (Windows only)
  • Startig with a graphical terminal emulator (Linux only)

I assume we all can see why this was brought up: If you have many tasks where each task launches its own GUI, it may be hard to find the appropriate window in the Task bar. Bringing the GUI of a task that reports an error in eCAL Sys directly to the front seems like a trivial idea.


I personally think it would be a great addition to have, but I am also a little afraid of the implementation, as I assume you will have to do 3 entire implementations with differnet GUI libraries only to support Windows and Linux. Regarding user interaction: Yes, this is part of eCAL Sys. The user starts, stops, restarts, modifies and moves tasks, just like any native task manager. Having a "Bring window to the top" function should fit into that scheme of task management.

FlorianReimold avatar Mar 24 '22 08:03 FlorianReimold

I have created the PR (https://github.com/eclipse-ecal/ecal/pull/924) with the work I have done so far. Unfortunately this does not work with Wayland applications and I have not found a proper solution for this yet.

mirzacanovic avatar Dec 20 '22 11:12 mirzacanovic

Just wanted to share the code here for future use:

#ifdef WIN32
#include "Windows.h"
#include "WinUser.h"
#endif
void TaskWidget::activateWindow()
{
  auto selected_tasks = getSelectedTasks();
#ifdef __linux__
  for (auto& task : selected_tasks)
  {
    for (auto id : task->GetPids())
    {
      std::string command = "xdotool search --desktop 0 --pid ";
      command += std::to_string(id);
      command += " | xargs xdotool windowactivate";
      std::cout << command << std::endl;
      system(command.c_str());
    }
  }
#elif defined WIN32
  std::vector<HWND> vhWnds;
  for (auto& task : selected_tasks)
  {
    for (auto id : task->GetPids())
    {
      DWORD pId = static_cast<DWORD>(id);

      HWND hCurWnd = NULL;

      do
      {
          hCurWnd = FindWindowEx(NULL, hCurWnd, NULL, NULL);
          DWORD dwProcID = 0;
          GetWindowThreadProcessId(hCurWnd, &dwProcID);
          if (dwProcID == pId)
          {
              vhWnds.push_back(hCurWnd);  // add the found hCurWnd to the vector
              wprintf(L"Found hWnd %d\n", hCurWnd);
          }
      }
      while (hCurWnd != NULL);

      for (const auto hwnd : vhWnds)
      {
          BOOL bVisible = IsWindowVisible(hwnd);
          SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0,
                      SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW |
                      (bVisible ? SWP_NOACTIVATE : 0));

          SetForegroundWindow(hwnd);
      }
    }
  }
#endif
}

FlorianReimold avatar Jan 12 '23 16:01 FlorianReimold