I have an x window id and need the gtk id

Linux specific forum
infratec
Always Here
Always Here
Posts: 6810
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

I have an x window id and need the gtk id

Post by infratec »

Hi,

I open an app with chromium (chromiuim --app=https://www.purebasic.fr/english)
Then I use xwininfo to get the window id (xwininfo -name "PureBasic Forums - English - Index page")
Unfortunatel I don't know an programatic way to get this id.
And the sourcecode of the xwininfo function is not short :cry:

To use gdk_window_reparent( ) I need the *GtkWidget of this window.

I found only ways for the opposite.

Any ideas?
User avatar
mk-soft
Always Here
Always Here
Posts: 5313
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: I have an x window id and need the gtk id

Post by mk-soft »

I have written these functions for all OS.
For Linus, an apt still needs to be installed.
sudo apt-get install wmctrl

Code: Select all

;-TOP

; Comment : Window Functions
; Author  : mk-soft
; Version : v1.02.0
; Create  : ?
; Update  : 29.08.2020

Structure udtListWindows
  Name.s
  Class.s
  Handle.i
  Process.i
  Childs.i
  Level.i
EndStructure

Threaded NewList ListWindows.udtListWindows()

CompilerSelect #PB_Compiler_OS
  CompilerCase #PB_OS_Windows
    
    ;- Windows
    
    Procedure.s GetTitle(Handle)
      Protected Name.s
      Name.s = Space(1024)
      GetWindowText_(Handle, @Name, Len(Name))
      ProcedureReturn Left(Name, Len(Name))
    EndProcedure
    
    Procedure.s GetClassName(Handle.i)
      Protected Class.s
      Class.s = Space(1024)
      GetClassName_(Handle, @Class, Len(Class))
      ProcedureReturn Left(Class, Len(Class))
    EndProcedure

    Procedure EnumProc(Handle.i, lParam.i)
      Protected *tmp.udtListWindows
      AddElement(ListWindows())
     
      ListWindows()\Handle = Handle
      ListWindows()\Process = 0
      GetWindowThreadProcessId_(Handle, @ListWindows()\Process)
      ListWindows()\Name = GetTitle(Handle)
      ListWindows()\Class = GetClassName(Handle)
      
      If lParam
        *tmp = lParam
        *tmp\Childs + 1
        ListWindows()\Level = *tmp\Level + 1
      Else
        ListWindows()\Level = 0
      EndIf
      
      EnumChildWindows_(Handle, @EnumProc(), @ListWindows())
      
      ProcedureReturn #True
    EndProcedure
    
    Procedure GetAllWindows() ; Result = Count of Windows
      Protected r1, len
      
      ClearList(ListWindows())
      r1 = EnumWindows_(@EnumProc(), 0)
      ProcedureReturn ListSize(ListWindows())
    EndProcedure
    
    Procedure FindNamedWindow(Name.s) ; Result = Handle
      Protected cnt, len
      len = Len(Name)
      
      GetAllWindows()
      ForEach ListWindows()
        If FindString(ListWindows()\Class, "CabinetWClass")
          Continue
        EndIf
        If FindString(ListWindows()\Class, "ShellTabWindowClass")
          Continue
        EndIf
        If Left(ListWindows()\Name, len) = Name
          ProcedureReturn ListWindows()\Handle
        EndIf
      Next
      ProcedureReturn 0
    EndProcedure
    
    Procedure CloseNamedWindow(Name.s) ; Result = Count of Windows
      Protected cnt, len
      len = Len(Name)
      GetAllWindows()
      ForEach ListWindows()
        If Left(ListWindows()\Name, len) = Name
          If FindString(ListWindows()\Class, "CabinetWClass")
            Continue
          EndIf
          If FindString(ListWindows()\Class, "ShellTabWindowClass")
            Continue
          EndIf
          SendMessage_(ListWindows()\Handle, #WM_CLOSE, 0, 0)
          cnt + 1
        EndIf
      Next
      ProcedureReturn cnt
    EndProcedure
    

  CompilerCase #PB_OS_MacOS
    
    ;- MacOS
    Threaded __IsMainScope
    __IsMainScope = #True
    
    Procedure GetAllWindows() ; Result = Count of Windows
      Protected RunningApps.i, RunningAppsCount.i, RunningApp.i, AppName.s, i, Pool
      
      If Not __IsMainScope
        Pool = CocoaMessage(0, 0, "NSAutoreleasePool new")
      EndIf
      
      ClearList(ListWindows())
      RunningApps = CocoaMessage(0, CocoaMessage(0, 0, "NSWorkspace sharedWorkspace"), "runningApplications")
      RunningAppsCount = CocoaMessage(0, RunningApps, "count")
      i = 0
      While i < RunningAppsCount
        RunningApp = CocoaMessage(0, RunningApps, "objectAtIndex:", i)
        AppName.s = PeekS(CocoaMessage(0, CocoaMessage(0, RunningApp, "localizedName"), "UTF8String"), -1, #PB_UTF8)
        AddElement(ListWindows())
        ListWindows()\Name = AppName
        ListWindows()\Handle = RunningApp
        i + 1
      Wend
      
      If Pool
        CocoaMessage(0, Pool, "release")
      EndIf
      
      ProcedureReturn i
    EndProcedure
    
    Procedure FindNamedWindow(Name.s) ; Result = RunningApp
      Protected r1, RunningApps.i, RunningAppsCount.i, RunningApp.i, AppName.s, i, cnt, Pool
      
      If Not __IsMainScope
        Pool = CocoaMessage(0, 0, "NSAutoreleasePool new")
      EndIf
      
      RunningApps = CocoaMessage(0, CocoaMessage(0, 0, "NSWorkspace sharedWorkspace"), "runningApplications")
      RunningAppsCount = CocoaMessage(0, RunningApps, "count")
      i = 0
      While i < RunningAppsCount
        RunningApp = CocoaMessage(0, RunningApps, "objectAtIndex:", i)
        AppName.s = PeekS(CocoaMessage(0, CocoaMessage(0, RunningApp, "localizedName"), "UTF8String"), -1, #PB_UTF8)
        If Name = AppName
          r1 = RunningApp
          Break
        EndIf
        i + 1
      Wend
      
      If Pool
        CocoaMessage(0, Pool, "release")
      EndIf
      
      ProcedureReturn r1
    EndProcedure
    
    Procedure CloseNamedWindow(Name.s) ;  ; Result = Count of Windows
      Protected RunningApps.i, RunningAppsCount.i, RunningApp.i, AppName.s, i, cnt, Pool
      
      If Not __IsMainScope
        Pool = CocoaMessage(0, 0, "NSAutoreleasePool new")
      EndIf
      
      RunningApps = CocoaMessage(0, CocoaMessage(0, 0, "NSWorkspace sharedWorkspace"), "runningApplications")
      RunningAppsCount = CocoaMessage(0, RunningApps, "count")
      i = 0
      While i < RunningAppsCount
        RunningApp = CocoaMessage(0, RunningApps, "objectAtIndex:", i)
        AppName.s = PeekS(CocoaMessage(0, CocoaMessage(0, RunningApp, "localizedName"), "UTF8String"), -1, #PB_UTF8)
        If Name = AppName
          CocoaMessage(0, RunningApp, "terminate")
          cnt + 1
        EndIf
        i + 1
      Wend
      
      If Pool
        CocoaMessage(0, Pool, "release")
      EndIf
      
      ProcedureReturn cnt
    EndProcedure
      
  CompilerCase #PB_OS_Linux
    
    ;- Linux
    
    ;- Install Paket 'sudo apt-get install wmctrl'
    
    Procedure GetAllWindows()
      Protected Compiler, Output.s, Temp.s, pos
      
        ClearList(ListWindows())
        Compiler = RunProgram("wmctrl", "-l -x", "", #PB_Program_Open | #PB_Program_Read)
        Output = ""
        If Compiler
          While ProgramRunning(Compiler)
            If AvailableProgramOutput(Compiler)
              Output = ReadProgramString(Compiler)
              AddElement(ListWindows())
              temp = "$" + Mid(Output, 3, 8)
              ListWindows()\Handle = Val(temp)
              temp = Mid(Output, 15)
              pos = FindString(temp, "  ")
              ListWindows()\Class = Left(temp, pos)
              temp = Trim(Mid(temp, pos))
              pos = FindString(temp, " ")
              ListWindows()\Name = Mid(temp, pos + 1)
            Else
              Delay(10)
            EndIf
          Wend
          CloseProgram(Compiler) ; Close the connection to the program
        Else
          Output = "Error - Programm konnte nicht gestartet werden!"
        EndIf
        
    EndProcedure
    
    Procedure FindNamedWindow(Name.s)
      Protected len = Len(Name)
      GetAllWindows()
      ForEach ListWindows()
        If Left(ListWindows()\Name, len) = Name
          If Not FindString(ListWindows()\Class, "nautilus", 1, #PB_String_NoCase)
            ProcedureReturn ListWindows()\Handle
          EndIf
        EndIf
      Next
      ProcedureReturn 0
    EndProcedure
    
    Procedure CloseNamedWindow(Name.s)  ; Result = #True or #False
      RunProgram("wmctrl", "-a " + Name, "")
      Delay(100)
      RunProgram("wmctrl", "-c " + Name, "")
      Delay(100)
      ProcedureReturn #True
    EndProcedure
    
CompilerEndSelect

;- Example

CompilerIf #PB_Compiler_IsMainFile
  
  Enumeration Windows
    #Main
  EndEnumeration
  
  Enumeration Gadgets
    
  EndEnumeration
  
  Enumeration Status
    #MainStatusBar
  EndEnumeration
  
  Procedure Main()
    
    If OpenWindow(#Main, #PB_Ignore, #PB_Ignore, 400, 200, "Window" , #PB_Window_SystemMenu)
      
      GetAllWindows()
      ForEach ListWindows()
        Debug ListWindows()\Name + ": Handle = " + ListWindows()\Handle
      Next
      ;r1 = FindNamedWindow("PureBasic")
      ;Debug "Windows Handle = " + Hex(r1)
      ;CloseNamedWindow("PureBasic")
      
      ;Debug GetTitle(r1)
      
      Repeat
        Select WaitWindowEvent()
          Case #PB_Event_CloseWindow
            Break
        EndSelect
      ForEver
      
    EndIf
    
  EndProcedure : Main()
  
CompilerEndIf
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
infratec
Always Here
Always Here
Posts: 6810
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: I have an x window id and need the gtk id

Post by infratec »

To call wmctrl or xwininfo as external programm makes no difference :wink:

But how can I use the result handle for use with

Code: Select all

gtk_widget_reparent_(*childWidget , *parentWidget)
:?:

I don't know how to find out the gtk widget structure with this handle.
Post Reply