Transparent window in linux

Linux specific forum
HarrysLad
User
User
Posts: 57
Joined: Fri Jun 04, 2010 9:29 pm
Location: Sunny Spain

Transparent window in linux

Post by HarrysLad »

Hi,

I'm using a universal splash routine in my Windows and macOS apps and I'd like to extend it to cover Linux versions as well but I don't have a clue how to make the magic work.
The code below works for rectangular images (without transparency) but I tend to use circular .png images on a transparent background.

Code: Select all

ImportC "-no-pie" : EndImport

UsePNGImageDecoder()                              ; setup system to use a .png image

; premultiply image (required for Windows splash screen but does no harm for OSX)
Procedure PreMultiply(image)
  
  Define i, j, colour
  StartDrawing(ImageOutput(image))
    DrawingMode(#PB_2DDrawing_AllChannels)
    For j=0 To ImageHeight(image)-1
      For i=0 To ImageWidth(image)-1
        colour = Point(i,j)
        Plot(i,j, RGBA(Red(colour)   & $FF * Alpha(colour) & $FF / $FF,
                       Green(colour) & $FF * Alpha(colour) & $FF / $FF,
                       Blue(colour)  & $FF * Alpha(colour) & $FF / $FF,
                       Alpha(colour)))
      Next
    Next
    StopDrawing()
    
EndProcedure

; this splash-screen business is a bit of a faff but has the advantage that it works even if the
; image has transparent areas. e.g., a round image on a transparent background.
Procedure showSplash(s, image)

  ExamineDesktops()
  
  #SPLASH_IMAGE = 0
  #SPLASH_WINDOW = 1
  
  CatchImage(#SPLASH_IMAGE, image)           ; load the image into memory
  w.l = ImageWidth(#SPLASH_IMAGE)                   ; splash image width
  h.l = ImageHeight(#SPLASH_IMAGE)                  ; splash image height
  x.l = (DesktopWidth(0)-w)/2                       ; x position
  y.l = (DesktopHeight(0)-h)/2                      ; y position
  
  StartTime.q = ElapsedMilliseconds()               ; access the millisecond clock
  PreMultiply(#SPLASH_IMAGE)
  
  CompilerIf #PB_Compiler_OS = #PB_OS_MacOS         ; if this is an OSX compiler ...
    
    OpenWindow(#SPLASH_WINDOW, x, y, w, h, "", #PB_Window_BorderLess|#PB_Window_Invisible)
    CopyImage(#SPLASH_IMAGE, #SPLASH_WINDOW)
    CocoaMessage(0, WindowID(#SPLASH_WINDOW), "setBackgroundColor:", CocoaMessage(0, 0, "NSColor colorWithPatternImage:", ImageID(#SPLASH_WINDOW)))
    CocoaMessage(0,WindowID(#SPLASH_WINDOW),"setHasShadow:",#YES)
    CocoaMessage(0, WindowID(#SPLASH_WINDOW), "setOpaque:", #NO)
    
  CompilerElseIf #PB_Compiler_OS = #PB_OS_Windows   ; else if this is a Windows compiler ...
    
    OpenWindow(#SPLASH_WINDOW, x, y, w, h,"",#PB_Window_BorderLess|#PB_Window_ScreenCentered)
    SetWindowLongPtr_(WindowID(#SPLASH_WINDOW), #GWL_EXSTYLE, GetWindowLongPtr_(WindowID(#SPLASH_WINDOW), #GWL_EXSTYLE)|#WS_EX_LAYERED|#WS_EX_TOOLWINDOW)
    hDC = StartDrawing(ImageOutput(#SPLASH_IMAGE))
    With sz.SIZE
      \cx = ImageWidth(#SPLASH_IMAGE)
      \cy = ImageHeight(#SPLASH_IMAGE)
    EndWith
    With BlendMode.BLENDFUNCTION
      \SourceConstantAlpha = 255
      \AlphaFormat = 1
    EndWith
    UpdateLayeredWindow_(WindowID(#SPLASH_WINDOW),0,0,@sz,hDC,@ContextOffset.POINT,0,@BlendMode,2)
    StopDrawing()
    
  CompilerElseIf #PB_Compiler_OS = #PB_OS_Linux   ; else if this is an linux compiler ...
    
    OpenWindow(#SPLASH_WINDOW, x, y, w, h, "", #PB_Window_BorderLess|#PB_Window_Invisible)
    can = CanvasGadget(#PB_Any,0, 0, w, h)
    If StartDrawing(CanvasOutput(can))
      DrawingMode(#PB_2DDrawing_Default)
      DrawAlphaImage(ImageID(#SPLASH_IMAGE), 0, 0)
      StopDrawing()
    EndIf 

  CompilerElse
    
    ProcedureReturn
    
  CompilerEndIf
  
  HideWindow(#SPLASH_WINDOW, #False)
  
  While ElapsedMilliseconds() - StartTime < s*1000    ; wait for 's' seconds showing splash screen
    WaitWindowEvent(1)
  Wend
  CloseWindow(#SPLASH_WINDOW)   

EndProcedure

showSplash(3,?SplashImage)

End

DataSection

  SplashImage:
  IncludeBinary "sphere.png" 
  
EndDataSection
The sphere.png is like this:
Image

Any ideas?

Dave
vwidmer
Enthusiast
Enthusiast
Posts: 282
Joined: Mon Jan 20, 2014 6:32 pm

Re: Transparent window in linux

Post by vwidmer »

I am not the author of this but maybe it will help if so would love to see what you do with it.

Code: Select all

;For gtk3...
EnableExplicit

#CAIRO_OPERATOR_SOURCE = 1

ImportC ""
   gdk_cairo_create(*Drawable.GdkDrawable)
   gdk_screen_get_rgba_visual(*screen.GdkScreen)
   gdk_display_get_pointer(*display.GdkDisplay, *screen.GdkScreen, *x, *y, *mask);    gtk2.2+
   gtk_widget_set_visual(*widget.GtkWidget, *visual.GdkVisual)
   gtk_widget_get_window(*widget.GtkWidget)
   gdk_screen_get_system_visual(*screen.GdkScreen)
   g_signal_connect(*instance, detailed_signal.p-ascii, *c_handler, *pdata, destroy= 0, flags= 0) As "g_signal_connect_data"
   gtk_widget_get_allocation(*widget.GtkWidget, *allocation.GtkAllocation)
EndImport

ImportC "-lcairo"
  cairo_arc(*CairoContext, xCenter.D, yCenter.D, Radius.D, StartAngle.D, EndAngle.D)
  cairo_destroy(*CairoContext)
  cairo_fill_preserve(*CairoContext)
  cairo_line_to(*CairoContext, x.D, y.D)
  cairo_move_to(*CairoContext, x.D, y.D)
  cairo_paint(CairoContext)
  cairo_restore(*CairoContext)
  cairo_save(*CairoContext)
  cairo_set_line_width(*CairoContext, LineWidth.D)
  cairo_set_operator(*CairoRegion, CairoOperator.I)
  cairo_set_source_rgba(*CairoRegion, Red.D, Green.D, Blue.D, Alpha.D)
  cairo_stroke(*CairoContext)
EndImport

ProcedureC Callback_ButtonMotion(*widget.GtkWindow, *event.GdkEventButton, window); to drag window, based on a mestnyi-example
   Static.i    isPressed
   Static.i    wX, wY;                                                          pointer window relative
   Static.i    wBorderL, wBorderT;                                              left, upper window delta
   Protected.i rX, rY, rMask;                                                   pointer root relative
   
   If *event\type = #GDK_BUTTON_PRESS And *event\button= 1; 2 / 3
      wX = WindowMouseX(window)
      wY = WindowMouseY(window)
      isPressed= #True
      gdk_window_get_position_(gtk_widget_get_window(*widget), @wBorderL, @wBorderT)
      gdk_window_get_root_origin_(gtk_widget_get_window(*widget), @rX, @rY)
      wBorderL- rX : wBorderT- rY
   ElseIf *event\type = #GDK_BUTTON_RELEASE
      isPressed= #False
   EndIf

   If isPressed
      gdk_display_get_pointer(gdk_display_get_default_(), #Null, @rX, @rY, @rMask)
      gtk_window_move_(*widget, rX- wX- wBorderL, rY- wY- wBorderT)
      If Not (rMask & #GDK_BUTTON1_MASK) : isPressed= #False : EndIf;            against trailing, quick stop
   EndIf

   ProcedureReturn #False
EndProcedure

ProcedureC DrawClockCallback(*Widget.GtkWidget, *Event.GdkEventExpose)
  Protected CairoContext.I
  Protected Hours.I
  Protected i.I
  Protected Inset.I
  Protected Minutes.I
  Protected Radius.D
  Protected Seconds.I
  Protected xCenter.D
  Protected yCenter.D
  Protected Allocation.GtkAllocation

  ; ----- Draw transparent background

  CairoContext = gdk_cairo_create(gtk_widget_get_window(*widget))
  cairo_set_source_rgba(CairoContext, 1, 1, 1, 0)
  cairo_set_operator(CairoContext, #CAIRO_OPERATOR_SOURCE)
  cairo_paint(CairoContext)

  ; ----- Update current time

  Hours = Hour(Date())
  Minutes = Minute(Date())
  Seconds = Second(Date())

  ; ----- Draw clock face
 
  gtk_widget_get_allocation(*widget, @Allocation)
  xCenter = Allocation\width / 2
  yCenter = Allocation\height / 2
 
  If xCenter < yCenter
    Radius = xCenter - 5
  Else
    Radius = yCenter - 5
  EndIf

  cairo_arc(CairoContext, xCenter, yCenter, Radius, 0, 2 * #PI)
  cairo_set_source_rgba(CairoContext, 1, 1, 1, 1)
  cairo_fill_preserve(CairoContext)
  cairo_set_source_rgba(CairoContext, 0, 0, 0, 1)
  cairo_stroke(CairoContext)

  For i = 0 To 11
    If i % 3 = 0
      Inset = 0.2 * Radius
    Else
      Inset = 0.1 * Radius
    EndIf

    cairo_move_to(CairoContext, xCenter + (Radius - Inset) * Cos(i * #PI / 6), yCenter + (Radius - Inset) * Sin(i * #PI / 6))
    cairo_line_to(CairoContext, xCenter + Radius * Cos(i * #PI / 6), yCenter + Radius * Sin(i * #PI / 6))
    cairo_stroke(CairoContext)
  Next i

  cairo_save(CairoContext)

  ; ----- Draw hour hand
  ;       The hour hand is rotated 30 degrees (Pi/6r) per hour + 1/2 a Degree
  ;       (Pi/360) per minute
  cairo_set_line_width(CairoContext, 5)
  cairo_move_to(CairoContext, xCenter, yCenter)
  cairo_line_to(CairoContext, xCenter + Radius / 2 * Sin(#PI / 6 * Hours + #PI / 360 * Minutes), yCenter + Radius / 2 * -Cos(#PI / 6 * Hours + #PI / 360 * Minutes))
  cairo_stroke(CairoContext)

  ; ----- Draw minute hand
  ;       The minute hand is rotated 6 degrees (Pi/30r) per minute
  cairo_set_line_width(CairoContext, 2)
  cairo_move_to(CairoContext, xCenter, yCenter)
  cairo_line_to(CairoContext, xCenter + Radius * 0.75 * Sin(#PI / 30 * Minutes), yCenter + Radius * 0.75 * -Cos(#PI / 30 * Minutes))
  cairo_stroke(CairoContext)

  ; ----- Draw seconds hand
  ;       Operates identically to the minute hand
  cairo_save(CairoContext)
  cairo_set_source_rgba(CairoContext, 1, 0, 0, 1)
  cairo_move_to(CairoContext, xCenter, yCenter)
  cairo_line_to(CairoContext, xCenter + Radius * 0.7 * Sin(#PI / 30 * Seconds), yCenter + Radius * 0.7 * -Cos(#PI / 30 * Seconds))
  cairo_stroke(CairoContext)

  cairo_restore(CairoContext)
  cairo_destroy(CairoContext)
EndProcedure

ProcedureC Callback_ScreenChanged(*widget.GtkWidget, *old_screen.GdkScreen, user_data)
   Protected *Screen.GdkScreen= gtk_widget_get_screen_(*widget)
   Protected *Visual.GdkVisual= gdk_screen_get_rgba_visual(*Screen)
   
   If Not *Visual
      *Visual = gdk_screen_get_system_visual(*Screen)
   EndIf
   gtk_widget_set_visual(*widget, *Visual)
EndProcedure

Define Screen.I
Define *Window.GtkWidget

OpenWindow(0, 140, 100, 200, 200, "Clock", #PB_Window_Invisible)
   *Window= WindowID(0)
   
   gtk_window_set_decorated_(*Window, #False)
   gtk_widget_set_app_paintable_(*Window, #True)
   gtk_widget_unrealize_(*Window)
   
   g_signal_connect(*Window, "draw", @DrawClockCallback(), 0)
   g_signal_connect(*Window, "screen-changed", @Callback_ScreenChanged(), #Null)
   Callback_ScreenChanged(*Window, #Null, #Null)
   g_signal_connect(*Window, "event",  @Callback_ButtonMotion(), 0);            to drag window by click in the content
   
   gtk_widget_show_all_(*Window)
   
   AddWindowTimer(0, 0, 1000)
   AddKeyboardShortcut(0, #PB_Shortcut_Escape, 0)

Repeat
   Select WaitWindowEvent()
      Case #PB_Event_Menu
         If EventMenu() = 0
            RemoveWindowTimer(0, 0)
            Break
         EndIf
      Case #PB_Event_Timer
         DrawClockCallback(*Window, 0)
         
   EndSelect
ForEver
WARNING: I dont know what I am doing! I just put stuff here and there and sometimes like magic it works. So please improve on my code and post your changes so I can learn more. TIA
User avatar
Shardik
Addict
Addict
Posts: 1989
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: Transparent window in linux

Post by Shardik »

HarrysLad wrote:Any ideas?
Successfully tested on
- Linux Mint 18.3 x64 with Cinnamon using PB 5.62 x64 and GTK3
- Lubuntu 14.04 x86 with LXDE using PB 5.46 x86 in ASCII and Unicode mode and PB 5.62 x86 in both GTK2 and GTK3

Code: Select all

EnableExplicit

Define PNGImageFile.S =  GetTemporaryDirectory() + "Sphere.png"

UsePNGImageDecoder()

InitNetwork()

ReceiveHTTPFile("http://www.fotosoft.co.uk/sphere.png", PNGImageFile)

If LoadImage(0, PNGImageFile) = 0
  MessageRequester("Error", "Unable to load image!")
Else
  OpenWindow(0, 100, 100, ImageWidth(0) + 20, ImageHeight(0) + 20,
    "Display transparent PNG image")
  SetWindowColor(0, RGB(226, 199, 182))

  ; ----- Wait until background color is applied

  Delay(50)
  While WindowEvent() : Wend

  CreateImage(1, ImageWidth(0), ImageHeight(0), 32, #PB_Image_Transparent)

  StartDrawing(ImageOutput(1))
    DrawAlphaImage(ImageID(0), 0, 0, 255)
  StopDrawing()

  StartDrawing(WindowOutput(0))
    DrawImage(ImageID(1), 10, 10)
  StopDrawing()

  Repeat
  Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
vwidmer wrote:I am not the author of this but maybe it will help if so would love to see what you do with it.
It would be very nice to not only post the code but also post the link to the thread containing the source code. Often the thread contains important additional information and other examples or links to further examples. In this case I opened this thread in which I posted a converted C source code to display a running clock using GTK2. Oma converted my example for you to GTK3. So when copying an example from the forum and even say "Awesome thanks" it would be nice to also save a link to that code in your source code...
HarrysLad
User
User
Posts: 57
Joined: Fri Jun 04, 2010 9:29 pm
Location: Sunny Spain

Re: Transparent window in linux

Post by HarrysLad »

Hi Shardik,

Thanks for that but the code doesn't do what I need.
Maybe we're at cross-purposes here.

This is what I want (as on macOS):

Image

But your code gives me (on Ubuntu 16.04):

Image

Or (on Ubuntu 18.04):

Image

Both of Ubuntu versions are pretty much what my original code did.
Am I doing something stupid again?

Dave
User avatar
Shardik
Addict
Addict
Posts: 1989
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: Transparent window in linux

Post by Shardik »

HarrysLad wrote:Thanks for that but the code doesn't do what I need.
Sorry for that. Unfortunately in Linux transparency seems to be far more complicated than on MacOS and Windows. This is a whole day's work. It's only for Linux but it's running now with both GTK2 and GTK3. It would have been too complicated and confusing for users only needing the Linux solution to integrate it into your cross-platform code, therefore I left that part for you...:wink:

I have tested this example successfully on Linux Mint 18.3 x64 with PB 5.46 x64 in ASCII and Unicode mode with GTK2 and GTK3:

Code: Select all

EnableExplicit

#CAIRO_OPERATOR_SOURCE = 1

ImportC ""
  gdk_cairo_create(*Drawable.GdkDrawable)
  gtk_widget_is_composited(*Widget.GtkWidget)
EndImport

ImportC "-lcairo"
  cairo_paint(*CairoContext)
  cairo_set_operator(*CairoContext, CairoOperator.I)
  cairo_set_source_rgba(*CairoContext, Red.D, Green.D, Blue.D, Alpha.D)
EndImport

CompilerIf Subsystem("gtk2")
  ImportC ""
    cairo_destroy(*CairoContext)
    gdk_screen_get_rgba_colormap(*Screen.GdkScreen)
  EndImport

  ProcedureC WidgetExposeHandler(*Widget.GtkWidget, *Event.GdkEventExpose)
    Protected CairoContext.I

    CairoContext = gdk_cairo_create(*Widget\window)
CompilerElse
  ImportC ""
    gdk_screen_get_rgba_visual(*Screen.GdkScreen)
    gdk_screen_get_system_visual(*Screen.GdkScreen)
    gtk_widget_set_visual(*Vidget.GtkWidget, *Visual.GdkVisual)
  EndImport

  ProcedureC WidgetDrawHandler(*Widget.GtkWidget, CairoContext.I, *UserData)
CompilerEndIf

  cairo_set_source_rgba(CairoContext, 1, 1, 1, 0)
  cairo_set_operator(CairoContext, #CAIRO_OPERATOR_SOURCE)
  cairo_paint(CairoContext)

  CompilerIf Subsystem("gtk2") = #True
    cairo_destroy(CairoContext)
  CompilerEndIf
EndProcedure
;}

UsePNGImageDecoder()

Define Container.I
Define PNGImageFile.S =  GetTemporaryDirectory() + "Sphere.png"
Define Screen.I
Define Window.I

InitNetwork()
ReceiveHTTPFile("http://www.fotosoft.co.uk/sphere.png", PNGImageFile)

If LoadImage(0, PNGImageFile) = 0
  MessageRequester("Error", "Unable to download image!")
  End
Else
  If LoadImage(0, PNGImageFile) = 0
    MessageRequester("Error", "Unable to load image!")
    End
  EndIf
EndIf

Window = OpenWindow(0, 200, 150, ImageWidth(0), ImageHeight(0), "",
  #PB_Window_Invisible)

If gtk_widget_is_composited(WindowID(0)) = #False
  MessageRequester("Error",
    "Sorry, but transparency is not supported on this system!")
  End
EndIf

gtk_window_set_decorated_(Window, #False)
gtk_widget_set_app_paintable_(Window, #True)
ImageGadget(0, 0, 0, ImageWidth(0), ImageHeight(0), ImageID(0))

; ----- Delete GdkWindow resources to be able to change colormap
gtk_widget_unrealize_(Window)

CompilerIf Subsystem("gtk2")
  Define Colormap.I

  Container = g_list_nth_data_(gtk_container_get_children_(gtk_bin_get_child_(Window)), 0)
  g_signal_connect_(Container, "expose-event", @WidgetExposeHandler(), 0)

  ; ----- Change colormap to support alpha values and hence allow transparency
  Screen = gtk_widget_get_screen_(Window)
  Colormap = gdk_screen_get_rgba_colormap(Screen)

  If Colormap
    gtk_widget_set_colormap_(Window, Colormap)
  Else
    MessageRequester("Error",
      "Your current system configuration doesn't support transparency!")
    End
  EndIf
CompilerElse
  Define ChildrenList.I
  Define VBox.I
  Define Visual.I

  VBox = gtk_bin_get_child_(Window)
  ChildrenList = gtk_container_get_children_(VBox)
  Container = g_list_nth_data_(ChildrenList, 0)
  g_signal_connect_(Container, "draw", @WidgetDrawHandler(), 0)
  Screen = gtk_widget_get_screen_(Window)
  Visual = gdk_screen_get_rgba_visual(Screen)
   
  If Visual = 0
    Visual = gdk_screen_get_system_visual(Screen)
  EndIf

  gtk_widget_set_visual(Window, Visual)
CompilerEndIf

; ----- Realize window and rebuild new GdkWindow
HideWindow(0, #False)

; ----- Define <Esc> key to close splash window
AddKeyboardShortcut(0, #PB_Shortcut_Escape, 0)

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Menu
      If EventMenu() = 0
        Break
      EndIf
  EndSelect
ForEver
Update 1: I have removed

Code: Select all

  CairoContext = gdk_cairo_create(gtk_widget_get_window(*Widget))
because in GTK3 the CairoContext is delivered as a callback parameter and in GTK2 the CairoContext was created twice.

Update 2: I have added a check with gtk_widget_is_composited() whether the desktop environment supports compositing which is necessary for transparency. Now for example all distributions with LXDE should display the error message that transparency is not supported and terminate execution.

Update 3: I have added gtk_widget_set_app_paintable_(). Now also Ubuntu 18.04 is working fine with GTK3. Now I have to do all my tests again... :lol:
Last edited by Shardik on Mon Aug 13, 2018 11:54 am, edited 3 times in total.
HarrysLad
User
User
Posts: 57
Joined: Fri Jun 04, 2010 9:29 pm
Location: Sunny Spain

Re: Transparent window in linux

Post by HarrysLad »

Wow Shardik. Just wow. :D
Thank you so much, exactly what I wanted.
Looks like I owe you yet another pint.

Dave
User avatar
Shardik
Addict
Addict
Posts: 1989
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: Transparent window in linux

Post by Shardik »

Unfortunately some desktop environments don't support composition and hence no transparency (Moksha and LXDE). I have tested my last example with PB 5.46 on these 14 different Linux distributions:

Code: Select all

Distribution                Desktop       GTK2    GTK3
------------                -------       ----    ----
Bodhi Linux 4.5.0 x86       Moksha         -       -
Debian 8.10 x86             LXDE          Error    -
Elementary OS 0.2.1 x86     Pantheon       +       +
Fedora 27 x86               Gnome 3.26.2  Error    +
Kubuntu 18.04 x86           KDE            +       +
Linux Mint 18.3 x64         Cinnamon       +       +
Linux Mint 19 x86           Cinnamon       +       +
Lubuntu 16.04 x86           LXDE           -       -
Lubuntu 18.04 x86           LXDE           -       -
Ubuntu 16.04 x86            Unity          +       +
Ubuntu 18.04 x86            Gnome 3        +       +
Ubuntu Budgie 18.04 x86     Budgie         +       +
Ubuntu MATE 18.04 x86       MATE           +       +
Xubuntu 18.04 x86           Xfce           +       +
In the minus cases the desktop environment doesn't support transparency.

Fedora is always a special case in using GTK2 ("Error" in the table). All API calls have to be declared (the predefined API calls in PB with the trailing underscore don't work). So to display the flash image with transparent background on Fedora with GTK2 you have to use the following code:

Code: Select all

EnableExplicit

#CAIRO_OPERATOR_SOURCE = 1

ImportC ""
  cairo_destroy(*CairoContext)
  cairo_paint(*CairoContext)
  cairo_set_operator(*CairoContext, CairoOperator.I)
  cairo_set_source_rgba(*CairoContext, Red.D, Green.D, Blue.D, Alpha.D)
  g_list_nth_data(*List.GList, Position.L)
  g_signal_connect_data(*Instance, SignalName.P-UTF8, *Handler, *Data,
    *DestroyData, ConnectFlags.L)
  gdk_cairo_create(*Drawable.GdkDrawable)
  gdk_screen_get_rgba_colormap(*Screen.GdkScreen)
  gtk_bin_get_child(*Bin.GtkBin)
  gtk_container_get_children(*Container.GtkContainer)
  gtk_widget_get_screen(*Widget.GtkWidget)
  gtk_widget_is_composited(*Widget.GtkWidget)
  gtk_widget_set_app_paintable(*Widget.GtkWidget, IsPaintable.L)
  gtk_widget_set_colormap(*Widget.GtkWidget, *Colormap.GdkColormap)
  gtk_widget_unrealize(*Widget.GtkWidget)
  gtk_window_set_decorated(*Window.GtkWindow, Setting.L)
EndImport

ProcedureC WidgetExposeHandler(*Widget.GtkWidget, *Event.GdkEventExpose)
  Protected CairoContext.I

  CairoContext = gdk_cairo_create(*Widget\window)
  cairo_set_source_rgba(CairoContext, 1, 1, 1, 0)
  cairo_set_operator(CairoContext, #CAIRO_OPERATOR_SOURCE)
  cairo_paint(CairoContext)
  cairo_destroy(CairoContext)
EndProcedure

UsePNGImageDecoder()

Define Colormap.I
Define Container.I
Define PNGImageFile.S = GetTemporaryDirectory() + "Sphere.png"
Define Screen.I
Define Window.I

InitNetwork()
ReceiveHTTPFile("http://www.fotosoft.co.uk/sphere.png", PNGImageFile)

If LoadImage(0, PNGImageFile) = 0
  MessageRequester("Error", "Unable to download image!")
  End
Else
  If LoadImage(0, PNGImageFile) = 0
    MessageRequester("Error", "Unable to load image!")
    End
  EndIf
EndIf

Window = OpenWindow(0, 200, 150, ImageWidth(0), ImageHeight(0), "",
  #PB_Window_Invisible)

If gtk_widget_is_composited(Window) = #False
  MessageRequester("Error",
    "Sorry, but transparency is not supported on this system!")
  End
EndIf

gtk_window_set_decorated(Window, #False)
gtk_widget_set_app_paintable(Window, #True)
ImageGadget(0, 0, 0, ImageWidth(0), ImageHeight(0), ImageID(0))

; ----- Delete GdkWindow resources to be able to change colormap
gtk_widget_unrealize(Window)

Container = g_list_nth_data(gtk_container_get_children(gtk_bin_get_child(Window)), 0)
g_signal_connect_data(Container, "expose-event", @WidgetExposeHandler(), 0, 0, 0)

; ----- Change colormap to support alpha values and hence allow transparency
Screen = gtk_widget_get_screen(Window)
Colormap = gdk_screen_get_rgba_colormap(Screen)

If Colormap
  gtk_widget_set_colormap(Window, Colormap)
Else
  MessageRequester("Error",
    "Your current system configuration doesn't support transparency!")
  End
EndIf

; ----- Realize window and rebuild new GdkWindow
HideWindow(0, #False)

; ----- Define <Esc> key to close splash window
AddKeyboardShortcut(0, #PB_Shortcut_Escape, 0)

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Menu
      If EventMenu() = 0
        Break
      EndIf
  EndSelect
ForEver
Last edited by Shardik on Mon Aug 13, 2018 3:06 pm, edited 4 times in total.
HarrysLad
User
User
Posts: 57
Joined: Fri Jun 04, 2010 9:29 pm
Location: Sunny Spain

Re: Transparent window in linux

Post by HarrysLad »

Shardik wrote:Unfortunately the situation is complicated regarding the many different Linux distributions and desktop environments. I have tested my last example on 12 different Linux distributions:

Code: Select all

Distribution               Desktop       GTK2    GTK3
Bodhi Linux 4.5.0           Moksha         -      -
Fedora 27 x86              Gnome 3       Error    -
Yeah, I appreciate that'd be a problem.
I've littered the code with fail-safes - defaulting to a brisk ProcedureReturn/do nothing if a problem's detected.
Ultimately, the most reliable solution may well be to stick PB methods for displaying the splash screen (as per my original post) ... and try to avoid splash images that contain transparency!
Thanks for your work though. Very much appreciated.

Dave
vwidmer
Enthusiast
Enthusiast
Posts: 282
Joined: Mon Jan 20, 2014 6:32 pm

Re: Transparent window in linux

Post by vwidmer »

Shardik wrote:It would be very nice to not only post the code but also post the link to the thread containing the source code. Often the thread contains important additional information and other examples or links to further examples. In this case I opened this thread in which I posted a converted C source code to display a running clock using GTK2. Oma converted my example for you to GTK3. So when copying an example from the forum and even say "Awesome thanks" it would be nice to also save a link to that code in your source code...
@Shardik, yes sorry for that it was an old piece of code I took off the forum long time ago. These days I am putting the links to the forum where I find stuff so I can reference it back when needed. Happy you where able to locate the original.

Also thanks for the excellent code you have produced in this thread.

Thanks to everyone for all there help and great bits of code.
WARNING: I dont know what I am doing! I just put stuff here and there and sometimes like magic it works. So please improve on my code and post your changes so I can learn more. TIA
vwidmer
Enthusiast
Enthusiast
Posts: 282
Joined: Mon Jan 20, 2014 6:32 pm

Re: Transparent window in linux

Post by vwidmer »

Is it possible to show only text? like OSD/headsup ?
WARNING: I dont know what I am doing! I just put stuff here and there and sometimes like magic it works. So please improve on my code and post your changes so I can learn more. TIA
Oma
Enthusiast
Enthusiast
Posts: 312
Joined: Thu Jun 26, 2014 9:17 am
Location: Germany

Re: Transparent window in linux

Post by Oma »

Hello vwidmer,

I just had some time to respond to your question and modified a code to show text in transparent window. Since I don't know exactly what you mean by 'text', here are 2 examples (for newer PB and gtk versions)
(tested on a Xubuntu 14.04x32 w. PB5.46 and Xubuntu 18.04x64 w. PB5.70B2).
- A PB gadget (here a TextGadget) in a transparent window (with a drawn frame to illustrate the window size) ...
- And a solely 'cairo texts' example, also with visible border of the window size.
If the window is allowed to remain immobile, the following parts can be omitted ...
- ProcedureC Callback_WindowMotion(*widget.GtkWindow, *event.GdkEventButton, window)
- g_signal_connect(*Window, "event", @Callback_WindowMotion(), #Win_Main)
(May it work in general and for a long time within the temporary gtk funktions ;-))

TextGadget in a transparent window (only Linux) ...

Code: Select all

EnableExplicit

ImportC ""
	g_signal_connect(*instance, detailed_signal.p-utf8, *c_handler, *pdata, destroy= 0, flags= 0) As "g_signal_connect_data"
	gdk_cairo_create(*drawable.GdkDrawable)
	gdk_display_get_pointer(*display.GdkDisplay, *screen.GdkScreen, *x, *y, *mask);    gtk2.2+
	gdk_screen_get_rgba_visual(*screen.GdkScreen)
	gdk_screen_get_system_visual(*screen.GdkScreen)
	gtk_widget_get_window(*widget.GtkWidget)
	gtk_widget_set_visual(*widget.GtkWidget, *visual.GdkVisual)
	
	cairo_destroy(*cairocontext)
	cairo_fill_preserve(*cairocontext)
	cairo_paint(*cairocontext)
	cairo_rectangle(*cairocontext, x.d, y.d, width.d, height.d)
	cairo_set_line_width(*cairocontext, width.d)
	cairo_set_operator(*cairoregion, op)
	cairo_set_source_rgba(*cairoregion, red.d, green.d, blue.d, alpha.d)
	cairo_stroke(*cairocontext)
EndImport

#CAIRO_OPERATOR_SOURCE = 1

#Win_Main = 0

#But      = 0

#FontBigger= 1
LoadFont(#FontBigger, "Ubuntu", 15)

; only for frameless windows to make it movable ...
ProcedureC Callback_WindowMotion(*widget.GtkWindow, *event.GdkEventButton, window); based on a mestnyi-example
	Static.i    isPressed
	Static.i    wX, wY;                                                          pointer window relative
	Static.i    wBorderL, wBorderT;                                              left, upper window delta
	Protected.i rX, rY, rMask;                                                   pointer root relative
	
	If PeekS(gtk_widget_get_name_(*widget), -1, #PB_UTF8) = "GtkButton"
		*widget= gtk_widget_get_parent_window_(*widget)
		gdk_window_get_user_data_(*widget, @*widget)
	EndIf
	
	If *event\type = #GDK_BUTTON_PRESS And *event\button= 1; 2 / 3
		wX = WindowMouseX(window); see Window_GetInnerMousePos.pb
		wY = WindowMouseY(window)
		isPressed= #True
		gdk_window_get_position_(gtk_widget_get_window(*widget), @wBorderL, @wBorderT)
		gdk_window_get_root_origin_(gtk_widget_get_window(*widget), @rX, @rY)
		wBorderL- rX : wBorderT- rY
	ElseIf *event\type = #GDK_BUTTON_RELEASE
		isPressed= #False
	EndIf
	
	If isPressed
		gdk_display_get_pointer(gdk_display_get_default_(), #Null, @rX, @rY, @rMask)
		gtk_window_move_(*widget, rX- wX- wBorderL, rY- wY- wBorderT)
		If Not (rMask & #GDK_BUTTON1_MASK) : isPressed= #False : EndIf;            against trailing, quick stop
	EndIf
	
	ProcedureReturn #False
EndProcedure

ProcedureC Callback_DrawGadgetBackground(*Widget.GtkWidget, *Event.GdkEventExpose, user_data)
	Protected *cr= gdk_cairo_create(gtk_widget_get_window(*widget))
	
	; ----- Draw transparent background
	cairo_set_source_rgba(*cr, 1, 1, 1, 0)
	cairo_set_operator(*cr, #CAIRO_OPERATOR_SOURCE)
	cairo_paint(*cr)
	
	; ----- A frame + slight-opacity-background to show window and it's borders.
	cairo_rectangle(*cr, 0, 0, WindowWidth(user_data), WindowHeight(user_data))
	cairo_set_source_rgba(*cr, 1.0, 1.0, 0.0, 0.2)
	cairo_set_line_width(*cr, 10)
	cairo_stroke(*cr)
	
	cairo_destroy(*cr)
EndProcedure

ProcedureC Callback_ScreenChanged(*widget.GtkWidget, *old_screen.GdkScreen, user_data)
	Protected *Screen.GdkScreen= gtk_widget_get_screen_(*widget)
	Protected *Visual.GdkVisual= gdk_screen_get_rgba_visual(*Screen)
	
	If Not *Visual
		*Visual = gdk_screen_get_system_visual(*Screen)
	EndIf
	gtk_widget_set_visual(*widget, *Visual)
EndProcedure

Procedure CreateWindow_Main()
	Protected *Window.GtkWindow
	Protected *MainContainer.GtkContainer
	
	OpenWindow(#Win_Main, 140, 100, 240, 120, "Gadget without background (gtk3)", #PB_Window_Invisible)
	*Window= WindowID(#Win_Main)
	*MainContainer= g_list_nth_data_(gtk_container_get_children_(gtk_bin_get_child_(WindowID(#Win_Main))), 0)
	
	gtk_window_set_decorated_(*Window, #False);                                  no Window border/titlebar
	gtk_widget_set_app_paintable_(*Window, #True);                               suppress default themed drawing of the window's background
	gtk_widget_set_app_paintable_(*MainContainer, #True);                        suppress default themed drawing of the contaiiners background
	gtk_widget_unrealize_(*Window)
	
	g_signal_connect(*MainContainer, "screen-changed", @Callback_ScreenChanged(), #Null)
	g_signal_connect(*MainContainer, "draw", @Callback_DrawGadgetBackground(), #Win_Main)
	
	Callback_ScreenChanged(*Window, #Null, #Null)
	g_signal_connect(*Window, "event",  @Callback_WindowMotion(), #Win_Main);    event to use for moving window
	
	gtk_widget_show_all_(*Window)
	
; 	ButtonGadget(#But, 10, 20, 220, 100, "A gtk3-ButtonGadget" + #LF$ + "in an invisible window.")
	TextGadget(#But, 10, 20, 220, 100, "A PureBasic-TextGadget" + #LF$ + "(gtk3_label)" + #LF$ + "in an invisible window.", #PB_Text_Center)
	gtk_label_set_justify_(GadgetID(#But), #GTK_JUSTIFY_CENTER)
	SetGadgetFont(#But, FontID(#FontBigger))
	GadgetToolTip(#But, "The TextGadget isn't clickable, but you can grab window content within the yellow frame to move it. [Esc] to close.")
	
	AddKeyboardShortcut(#Win_Main, #PB_Shortcut_Escape, 0)
EndProcedure

CreateWindow_Main()

Repeat
	Select WaitWindowEvent()
		Case #PB_Event_Menu
			If EventMenu() = 0
				Break
			EndIf
		Case #PB_Event_Gadget
			If EventGadget() = #But
				Debug "Button clicked"
			EndIf
			
	EndSelect
ForEver
Cairo text in a transparent window (only Linux) ...

Code: Select all

EnableExplicit

ImportC ""
	g_signal_connect(*instance, detailed_signal.p-utf8, *c_handler, *pdata, destroy= 0, flags= 0) As "g_signal_connect_data"
	gdk_cairo_create(*drawable.GdkDrawable)
	gdk_display_get_pointer(*display.GdkDisplay, *screen.GdkScreen, *x, *y, *mask);    gtk2.2+
	gdk_screen_get_rgba_visual(*screen.GdkScreen)
	gdk_screen_get_system_visual(*screen.GdkScreen)
	gtk_widget_get_window(*widget.GtkWidget)
	gtk_widget_set_visual(*widget.GtkWidget, *visual.GdkVisual)
	
	cairo_destroy(*cairocontext)
	cairo_fill_preserve(*cairocontext)
	cairo_paint(*cairocontext)
	cairo_rectangle(*cairocontext, x.d, y.d, width.d, height.d)
	cairo_set_line_width(*cairocontext, width.d)
	cairo_set_operator(*cairoregion, op)
	
	cairo_select_font_face(*cairoregion, family.p-utf8, slant, weight)
	cairo_set_font_size(*cairoregion, size.d)
	cairo_move_to(*cairocontext, x.d, y.d)
	cairo_show_text(*cairocontext, utf8.p-utf8)
	
	cairo_set_source_rgba(*cairoregion, red.d, green.d, blue.d, alpha.d)
	cairo_stroke(*cairocontext)
	
	gtk_widget_set_tooltip_text(*widget.GtkWidget, text.p-utf8)
EndImport

#CAIRO_OPERATOR_SOURCE = 1

#Win_Main = 0

; only for frameless windows to make it movable ...
ProcedureC Callback_WindowMotion(*widget.GtkWindow, *event.GdkEventButton, window); based on a mestnyi-example
	Static.i    isPressed
	Static.i    wX, wY;                                                          pointer window relative
	Static.i    wBorderL, wBorderT;                                              left, upper window delta
	Protected.i rX, rY, rMask;                                                   pointer root relative
	
	If PeekS(gtk_widget_get_name_(*widget), -1, #PB_UTF8) = "GtkButton"
		*widget= gtk_widget_get_parent_window_(*widget)
		gdk_window_get_user_data_(*widget, @*widget)
	EndIf
	
	If *event\type = #GDK_BUTTON_PRESS And *event\button= 1; 2 / 3
		wX = WindowMouseX(window); see Window_GetInnerMousePos.pb
		wY = WindowMouseY(window)
		isPressed= #True
		gdk_window_get_position_(gtk_widget_get_window(*widget), @wBorderL, @wBorderT)
		gdk_window_get_root_origin_(gtk_widget_get_window(*widget), @rX, @rY)
		wBorderL- rX : wBorderT- rY
	ElseIf *event\type = #GDK_BUTTON_RELEASE
		isPressed= #False
	EndIf
	
	If isPressed
		gdk_display_get_pointer(gdk_display_get_default_(), #Null, @rX, @rY, @rMask)
		gtk_window_move_(*widget, rX- wX- wBorderL, rY- wY- wBorderT)
		If Not (rMask & #GDK_BUTTON1_MASK) : isPressed= #False : EndIf;            against trailing, quick stop
	EndIf
	
	ProcedureReturn #False
EndProcedure

ProcedureC Callback_DrawCairoBackground(*Widget.GtkWidget, *Event.GdkEventExpose, user_data)
	Protected *cr= gdk_cairo_create(gtk_widget_get_window(*widget))
	
	; ----- Draw transparent background
	cairo_set_source_rgba(*cr, 1, 1, 1, 0)
	cairo_set_operator(*cr, #CAIRO_OPERATOR_SOURCE)
	cairo_paint(*cr)
	
	; ----- A slight-opacity frame to show window and it's borders.
	cairo_rectangle(*cr, 0, 0, WindowWidth(user_data), WindowHeight(user_data))
	cairo_set_source_rgba(*cr, 1.0, 1.0, 0.0, 0.2)
	cairo_set_line_width(*cr, 10)
	cairo_stroke(*cr)
	
	; ----- A simple cairo text output example
	cairo_select_font_face(*cr, "Comic Sans MS", 0, 1)
	cairo_set_source_rgba(*cr, 0.0, 0.0, 0.2, 1.0)
	cairo_set_font_size(*cr, 18)
	cairo_move_to(*cr, 10, 45)
	cairo_show_text(*cr, "A cairo text in ")
	cairo_move_to(*cr, 10, 80)
	cairo_show_text(*cr, "an invisible window.")
	
	cairo_destroy(*cr)
EndProcedure

ProcedureC Callback_ScreenChanged(*widget.GtkWidget, *old_screen.GdkScreen, user_data)
	Protected *Screen.GdkScreen= gtk_widget_get_screen_(*widget)
	Protected *Visual.GdkVisual= gdk_screen_get_rgba_visual(*Screen)
	
	If Not *Visual
		*Visual = gdk_screen_get_system_visual(*Screen)
	EndIf
	gtk_widget_set_visual(*widget, *Visual)
EndProcedure

Procedure CreateWindow_Main()
	Protected *Window.GtkWindow
	Protected *MainContainer.GtkContainer
	
	OpenWindow(#Win_Main, 140, 100, 200, 120, "Gadget without background (gtk3)", #PB_Window_Invisible)
	*Window= WindowID(#Win_Main)
	*MainContainer= g_list_nth_data_(gtk_container_get_children_(gtk_bin_get_child_(WindowID(#Win_Main))), 0)
	
	gtk_window_set_decorated_(*Window, #False);                                  no Window border/titlebar
	gtk_widget_set_app_paintable_(*Window, #True);                               suppress default themed drawing of the window's background
	gtk_widget_set_app_paintable_(*MainContainer, #True);                        suppress default themed drawing of the contaiiners background
	gtk_widget_unrealize_(*Window)
	
	g_signal_connect(*MainContainer, "screen-changed", @Callback_ScreenChanged(), #Null)
	g_signal_connect(*MainContainer, "draw", @Callback_DrawCairoBackground(), #Win_Main)
	
	Callback_ScreenChanged(*Window, #Null, #Null)
	g_signal_connect(*Window, "event",  @Callback_WindowMotion(), #Win_Main);    event to use for moving window
	
	gtk_widget_show_all_(*Window)
	
	gtk_widget_set_tooltip_text(*Window, "Transparent window w. indicated size, cairo text, grabable window content to move it,  [Esc] to close.")
	AddKeyboardShortcut(#Win_Main, #PB_Shortcut_Escape, 0)
EndProcedure

CreateWindow_Main()

Repeat
	Select WaitWindowEvent()
		Case #PB_Event_Menu
			If EventMenu() = 0
				Break
			EndIf
	EndSelect
ForEver
Best regards, Charly
PureBasic 5.4-5.7, Linux: (X/L/K)Ubuntus+Mint - Windows XP (32Bit)
PureBasic Linux-API-Library & Viewer: http://www.chabba.de
User avatar
Shardik
Addict
Addict
Posts: 1989
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: Transparent window in linux

Post by Shardik »

I have taken my code to display a transparent splash image from above and modified it to display text in a transparent window. I have tested my example on Linux Mint 18.3 x64 with PB 5.46 in ASCII and Unicode mode using GTK3. It displays text in a transparent window in a transparent ImageGadget. You have to set the text in the procedure WidgetDrawHandler. You may define the text in this procedure dynamically using a Shared string variable and do also the text formatting in this procedure. The advantage of my code is that it uses native PureBasic 2D drawing functions to display the frame and text in the HUD window.

Currently the normal window frame and caption is displayed and you may therefore move the window and close it. If you want to hide the window frame and caption, simply uncomment the following line:

Code: Select all

; gtk_window_set_decorated_(Window, #False)
But then you can't move the HUD window anymore. To implement this you have to take a look into Charly's nice examples.

Code: Select all

EnableExplicit

#CAIRO_OPERATOR_SOURCE = 1

ImportC ""
  gdk_cairo_create(*Drawable.GdkDrawable)
  gtk_widget_get_window(*Widget.GtkWidget)
  gtk_widget_is_composited(*Widget.GtkWidget)
EndImport

ImportC "-lcairo"
  cairo_paint(*CairoContext)
  cairo_set_operator(*CairoContext, CairoOperator.I)
  cairo_set_source_rgba(*CairoContext, Red.D, Green.D, Blue.D, Alpha.D)
EndImport

ImportC ""
  gdk_screen_get_rgba_visual(*Screen.GdkScreen)
  gdk_screen_get_system_visual(*Screen.GdkScreen)
  gtk_widget_set_visual(*Vidget.GtkWidget, *Visual.GdkVisual)
EndImport

Define Container.I
Define Screen.I
Define Visual.I
Define Window.I

ProcedureC WidgetDrawHandler(*Widget.GtkWidget, CairoContext.I, *UserData)
  CairoContext = gdk_cairo_create(gtk_widget_get_window(*Widget))
  cairo_set_source_rgba(CairoContext, 1, 1, 1, 0)
  cairo_set_operator(CairoContext, #CAIRO_OPERATOR_SOURCE)
  cairo_paint(CairoContext)

  If StartDrawing(WindowOutput(0))
    ; ----- Draw frame of HUD
    DrawingMode(#PB_2DDrawing_Default)
    Line(1, 1, WindowWidth(0), 1, $FF)
    Line(1, 2, WindowWidth(0), 1, $FF)
    Line(1, WindowHeight(0), WindowWidth(0), 1, $FF)
    Line(1, WindowHeight(0) - 1, WindowWidth(0), 1, $FF)
    Line(1, 1, 1, WindowHeight(0), $FF)
    Line(2, 1, 1, WindowHeight(0), $FF)
    Line(WindowWidth(0), 1, 1, WindowHeight(0) - 1, $FF)
    Line(WindowWidth(0) - 1, 1, 1, WindowHeight(0) - 2, $FF)

    ; ----- Draw text into HUD window
    DrawingMode(#PB_2DDrawing_Transparent)
    DrawText(30, 26, "Text in HUD window", $FF0000)
    DrawText(48, 53, "<Esc> to close", $FF)
    StopDrawing()
  EndIf
EndProcedure

CreateImage(0, 220, 100, 32, #PB_Image_Transparent)
Window = OpenWindow(0, 200, 150, ImageWidth(0), ImageHeight(0),
  "HUD window", #PB_Window_Invisible)

If gtk_widget_is_composited(WindowID(0)) = #False
  MessageRequester("Error",
    "Sorry, but transparency is not supported on this system!")
  End
EndIf

; ----- Disable visibility of window frame
; gtk_window_set_decorated_(Window, #False)

; ----- Enable modification of window colors
gtk_widget_set_app_paintable_(Window, #True)

ImageGadget(0, 0, 0, ImageWidth(0), ImageHeight(0), ImageID(0))

; ----- Delete GdkWindow resources to be able to change colormap
gtk_widget_unrealize_(Window)

; ----- Get window's child container
Container = g_list_nth_data_(gtk_container_get_children_(0 +
  gtk_bin_get_child_(WindowID(0))), 0)

g_signal_connect_(GadgetID(0), "draw", @WidgetDrawHandler(), 0)
Screen = gtk_widget_get_screen_(Window)
Visual = gdk_screen_get_rgba_visual(Screen)
   
If Visual = 0
  Visual = gdk_screen_get_system_visual(Screen)
EndIf

gtk_widget_set_visual(Window, Visual)

; ----- Realize window and rebuild new GdkWindow
HideWindow(0, #False)

; ----- Define <Esc> key to close splash window
AddKeyboardShortcut(0, #PB_Shortcut_Escape, 0)

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Menu
      If EventMenu() = 0
        Break
      EndIf
  EndSelect
ForEver
Justin
Addict
Addict
Posts: 829
Joined: Sat Apr 26, 2003 2:49 pm

Re: Transparent window in linux

Post by Justin »

Very good examples, thanks
vwidmer
Enthusiast
Enthusiast
Posts: 282
Joined: Mon Jan 20, 2014 6:32 pm

Re: Transparent window in linux

Post by vwidmer »

Wow thanks very nice examples.
WARNING: I dont know what I am doing! I just put stuff here and there and sometimes like magic it works. So please improve on my code and post your changes so I can learn more. TIA
vwidmer
Enthusiast
Enthusiast
Posts: 282
Joined: Mon Jan 20, 2014 6:32 pm

Re: Transparent window in linux

Post by vwidmer »

I am trying the example with the text but I cant get it to change correctly it just keeps drawing on top of it self. I am not clear on what you mean by "define the text in this procedure dynamically using a Shared string variable"

Thanks
WARNING: I dont know what I am doing! I just put stuff here and there and sometimes like magic it works. So please improve on my code and post your changes so I can learn more. TIA
Post Reply