BringToFront in Cinnamon

Do you have a typical platform dependent issue you're battling with ? Ask it here. Make sure you mention your platform, compiler, and wxWidgets version.
Post Reply
AndrzejB
Earned some good credits
Earned some good credits
Posts: 105
Joined: Sun Nov 29, 2015 12:46 pm

BringToFront in Cinnamon

Post by AndrzejB »

I have written multidocument text editor using wxStyledTextCtrl.
I have IPC for detect other instance, if other instance is called it send message to first instance and stop.
This action work OK.
First instance must bring to front, and here begin problems.
I have Linux and Cinnamon, and I wrote special method:

Code: Select all

void BringToFront() {
    int pid = getpid();
// Start with the root window.
    Display *display = XOpenDisplay(0);
    WindowsMatchingPid match(display, XDefaultRootWindow(display), pid);
    Display *dsp = XOpenDisplay(NULL);
    long id = match.result()[0];
    XRaiseWindow ( dsp, id );
    XCloseDisplay ( dsp );
}

void MyFrame::OnPoke(wxCommandEvent &event) {
    SetFocus();
    CmdStruct cmdStruct;
    char *data = (char*)event.GetClientData();
    auto argv = cmdStruct.unpack(data);
    for (int i=1; i<argv.size(); i++)
        OpenOrActivate(argv[i]);
    BringToFront();
}
But is still not enough. I have Mint21 with Cinnamon. This is important behavior because I call my editor from DoubleCommander and if I click on file, I see nothing and must got to editor application with Alt+Tab
User avatar
doublemax
Moderator
Moderator
Posts: 19114
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: BringToFront in Cinnamon

Post by doublemax »

Why are you using platform specific code here? Have you tried Raise()?

It would also be interesting if this never works in Cinnamon, or only in your application. Build a small test app with two toplevel windows, and check if it works there.

Sometimes you also need to call stuff like this asynchronously after all events have been processed:

Code: Select all

  CallAfter( [this] {
    Raise();
  });
Use the source, Luke!
AndrzejB
Earned some good credits
Earned some good credits
Posts: 105
Joined: Sun Nov 29, 2015 12:46 pm

Re: BringToFront in Cinnamon

Post by AndrzejB »

In which header is Raise() ?
OK, this is widget method. After applying, this application is flickering in taskbar, but is not enough. Maybe Cinnamon protect it from bringing to front?
But editor Kate probably can bring.
Partial solution is in https://stackoverflow.com/questions/733 ... nt-in-mint
"only window is bringing to front, not keyboard focus: If I call my editor from DoubleCommander, my editor is bring to front, but keyboard (for example closing by Alt-F4) is attached to DoubleCommander."
AndrzejB
Earned some good credits
Earned some good credits
Posts: 105
Joined: Sun Nov 29, 2015 12:46 pm

Re: BringToFront in Cinnamon

Post by AndrzejB »

On other forum I have reply
I'm not so sure about X11, but other systems, such as Windows, do not allow applications to "steal" the focus – for reasons of security and user experience. If at all, the process that owns the window which is currently focused will be allowed to transfer the focus to another window (potentially belonging to another process), but other (background) processes will certainly not be allowed to just take over the focus...

See "Remarks" here:
https://docs.microsoft.com/en-us/window ... oundwindow
https://www.cplusplus.com/forum/unices/284655/
User avatar
doublemax
Moderator
Moderator
Posts: 19114
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: BringToFront in Cinnamon

Post by doublemax »

I took a quick look into the "Kate" source code and i think i have identified the relevant code part:
https://github.com/KDE/kate/blob/e79609 ... or.cpp#L31

It really seems that you need to jump through some extra hoops to accomplish that task.
Use the source, Luke!
AndrzejB
Earned some good credits
Earned some good credits
Posts: 105
Joined: Sun Nov 29, 2015 12:46 pm

Re: BringToFront in Cinnamon

Post by AndrzejB »

Main problem is token, which I don't know which should be.

Code: Select all

KWindowSystem::setCurrentXdgActivationToken(token);
In WxWidgets application is probably possible using method used in Lazarus Pascal.
There is inside:

Code: Select all

procedure TGtk2WidgetSet.AppBringToFront;
begin
  if Assigned(Application.MainForm) and Application.MainForm.HandleAllocated then
  begin
    gdk_window_raise({%H-}PGtkWidget(Application.MainForm.Handle)^.window);
    gdk_window_focus({%H-}PGtkWidget(Application.MainForm.Handle)^.window,
                                gtk_get_current_event_time);
  end;
end;
Post Reply