Linux 'Native' Widgets

Organizing tasks to work on, New Features Ideas, Building LCS & LCB Libraries & Widgets, Redecorating and Modifying the IDE, Hacking / Editing Tools, Compiling the Engine from Source, etc.
User avatar
OpenXTalkPaul
Posts: 1574
Joined: Sat Sep 11, 2021 4:19 pm
Contact:

Linux 'Native' Widgets

Post by OpenXTalkPaul »

So...I finally started to really try to make a Linux 'Native' Widget.
'Native' in single-quotes because there is no 'Native' in Linuxes is there?
I think that all of the GNOME projects like GTK are probably what people think of when they think Linux 'Native', right?

There are no real Linux 'Native' Widget examples to go on, but there are some (outdated and not fully functional example) bits of information in the Extension Builder guides.
I quickly had some success:

Code: Select all

widget org.openxtalk.gtkbutton

	use com.livecode.canvas
	use com.livecode.widget
	use com.livecode.engine
	use com.livecode.foreign
   use com.livecode.arithmetic
   use com.livecode.array
   use com.livecode.assert
   use com.livecode.binary
   use com.livecode.bitwise
   use com.livecode.byte
   use com.livecode.char
   use com.livecode.codeunit
   use com.livecode.date
   use com.livecode.file
   use com.livecode.java
   use com.livecode.list
   use com.livecode.logic
   use com.livecode.math
   use com.livecode.mathfoundation

	metadata title is "GTK Button"
	metadata author is "Paul McClernan"
	metadata version is "1.0.0"
	metadata platforms is "desktop,mobile"

--- If the module makes use of external code that is only
--  available on specific Operating Systems or Platforms, use the "os"
--  and/or "platforms" metadata keys.
-- code/x86-linux/library.so
-- code/x86_64-linux/library.so

--- The key piece of syntax for creating widgets that hook into native view objects is `my native layer`:
--- set my native layer to mNativeView
private variable mNativeLayer as optional Pointer
// Store references to both the plug and button
private variable mPlug as optional Pointer
private variable mNativeView as optional Pointer
private variable mGTKBtn as optional Pointer

--- When using a native layer, a widget's `OnPaint` handler is not called. However it is recommended to provide some sort of
--- placeholder `OnPaint` method to represent the widget when the native layer is not supported on the current platform.
--- It is not yet possible to write a fully functional native widget on Linux, as there are some issues with event handling and focus. This will be addressed in future releases.
--- Native views on Linux are `GtkPlug`s. A `GtkSocket` is used internally to render the view from the process in which it is running. In most instances you will want to embed a `GtkWidget` in a `GtkPlug`.
-- The following snippet shows how to bind to `gtk_button_new_with_label`, and use it to set the native layer to a suitable gtk plug id:
--  Bind to various useful functions in libgtk.
--- We need to create a GTK plug, and GTK button, add the button to the plug and then show them.
foreign handler GTK_PlugNew(in pType as CUInt) returns Pointer binds to "c:libgtk-x11-2.0.so>gtk_plug_new"
foreign handler GTK_ButtonNewWithLabel(in pLabel as ZStringNative) returns Pointer binds to	"c:libgtk-x11-2.0.so>gtk_button_new_with_label"
foreign handler GTK_ContainerAdd(in pContainer as Pointer, in pWidget as Pointer) returns nothing binds to "c:libgtk-x11-2.0.so>gtk_container_add"
foreign handler GTK_WidgetShow(in pWidget as Pointer) returns nothing binds to "c:libgtk-x11-2.0.so>gtk_widget_show"
	// The actual native layer will be set to the plug id
foreign handler GTK_PlugGetId(in pPlug as Pointer) returns Pointer binds to "c:libgtk-x11-2.0.so>gtk_plug_get_id"
--- Event callbacks are pretty simple on Linux, as you can pass a (foreign) handler into `g_signal_connect_data` directly:
	// Define the callback foreign handler type
public foreign handler type ClickCallback(in pWidget as Pointer, in pContext as optional Pointer) returns nothing
	// Bind to g_signal_connect_data to connect a foreign handler to a gtk signal
foreign handler GTK_SignalConnect(in pObj as Pointer, in pEvent as ZStringNative, in pHandler as ClickCallback, in pData as optional Pointer, in pNotify as optional Pointer, in pFlags as CUInt) returns CULong binds to "c:libgtk-x11-2.0.so>g_signal_connect_data"
--- Properties of Linux native views can be set using the GTK Widget API.
--- For example, to hook up the enabled property of a Linux button (called "_sensitive_" in the GTK API):
foreign handler GTK_WidgetSetSensitive(in pWidget as Pointer, in pValue as CBool) returns nothing binds to "c:libgtk-x11-2.0.so>gtk_widget_set_sensitive"

public handler OnOpen()
	unsafe
	put CreateNativeView() into mNativeLayer
	set my native layer to mNativeLayer
	end unsafe
end handler

private handler OnCreate()
	unsafe
	put CreateNativeView() into mNativeLayer
	set my native layer to mNativeLayer
	end unsafe
end handler

private handler OnClose()
	unsafe
	set my native layer to nothing
	put nothing into mNativeLayer
	end unsafe
end handler

private handler CreateNativeView() returns Pointer
	unsafe
		// Create a new default plug
		put GTK_PlugNew(0) into mPlug
		log ["Plug",mPlug]
		// Create a button with empty label
		put GTK_ButtonNewWithLabel("TEST BUTTON") into mGTKBtn
		log ["Button",mGTKBtn]
		GTK_WidgetSetSensitive(mGTKBtn, true)
		GTK_SignalConnect(mGTKBtn, "clicked", OnButtonClick, nothing, nothing, 0)

		// Add the button to the plug
		GTK_ContainerAdd(mPlug, mGTKBtn)

		// Ensure both button and plug are visible
		GTK_WidgetShow(mGTKBtn)
		GTK_WidgetShow(mPlug)

		// Return the plug window id
		return GTK_PlugGetId(mPlug)
	end unsafe
end handler

private handler SetNativeLayer()
	unsafe
		set my native layer to CreateNativeView()
	end unsafe
end handler

private handler OnButtonClick(in pWidget as Pointer, in pContext as optional Pointer) returns nothing
		unsafe
		// The widget object in LiveCode will receive the posted message
		post "mouseUp"
end handler

// Actual handler that will be called when the button is clicked
private handler SignalConnect(in pButtonView as Pointer) returns nothing
	unsafe
	// Connect the foreign handler to the clicked signal. All other
	// parameters are empty/default
	GTK_SignalConnect(pButtonView, "clicked", OnButtonClick, nothing, nothing, 0)
	end unsafe
end handler

private handler SetEnabled(in pButtonView as Pointer)
	unsafe
		GTK_WidgetSetSensitive(pButtonView, my enabled)
	end unsafe
end handler

end widget

The Extension Widget above creates a clickable GTK Button,
HOWEVER, it only triggers the 'mouseUp' message a single time, then the button seems like it is disabled. I'm thinking this is an object life-cycle issue, but it could be that it button needs to be re-armed by setting that property again?
GTK is a C API, which should kind of make things easy to work out.
Anyway, this is one small small step towards building something like a GStreamer widget.
Screenshot_20240117_123008.png
Screenshot_20240117_123008.png (139.24 KiB) Viewed 792 times
User avatar
tperry2x
Posts: 1537
Joined: Tue Dec 21, 2021 9:10 pm
Location: Britain (Previously known as Great Britain)
Contact:

Re: Linux 'Native' Widgets

Post by tperry2x »

That is a brilliant proof-of-concept widget. Thank you for your efforts on this Paul.
User avatar
OpenXTalkPaul
Posts: 1574
Joined: Sat Sep 11, 2021 4:19 pm
Contact:

Re: Linux 'Native' Widgets

Post by OpenXTalkPaul »

tperry2x wrote: Wed Jan 17, 2024 6:11 pm That is a brilliant proof-of-concept widget. Thank you for your efforts on this Paul.
Basically all I did was combine some snippets from the Guide and fix a few lines so that it works.
From the binding string you can see it's using GTK v2 (which I obviously have installed).
GTK is currently on v4, so right off the bat that needs to be updated.
GTK has an interesting feature where you can pass widget attributes and create a collection view with combined controls simply by passing it some XML (and it can do some CSS stuff too).

A 'Plug' seems to be the GTK equivalent of an 'NSView' in macOS Cocoa/ObjC. It's kind of strange that GTK calls its view port object a 'plug'. If you create a widget with a 'native layer' without actually rendering anything into that layer, on Linux it literally punches a rectangle hole through the window the widget is on. I wonder if that's why GTK called it a 'plug' since it actually 'plug's-up the whole that was created to used as the 'view-port'?a
User avatar
tperry2x
Posts: 1537
Joined: Tue Dec 21, 2021 9:10 pm
Location: Britain (Previously known as Great Britain)
Contact:

Re: Linux 'Native' Widgets

Post by tperry2x »

I forget exactly which, but you can punch holes in the card through to your desktop with one of the ink modes too
User avatar
OpenXTalkPaul
Posts: 1574
Joined: Sat Sep 11, 2021 4:19 pm
Contact:

Re: Linux 'Native' Widgets

Post by OpenXTalkPaul »

tperry2x wrote: Wed Jan 17, 2024 11:13 pm I forget exactly which, but you can punch holes in the card through to your desktop with one of the ink modes too
Yes, and you can do that with a alpha channel mask applied to a stack window too.

I wasn't looking for that effect, just thought it was curious that the Linux 'native layer' did that when there wasn't any thing being rendered into that 'hole'. So this seems to be the way GTK2-3 can display a window/view from another process inside your app. I suspect this is actually part of the problems with both the 'native' Player and the Browser Widget on Linux. I've been reading various things about how that mechanism is problematic with Wayland (works ok with X11) and worse, that mechanism has been removed entirely from GTK4.
Read the comments here: https://www.reddit.com/r/gnome/comments ... al_window/
User avatar
OpenXTalkPaul
Posts: 1574
Joined: Sat Sep 11, 2021 4:19 pm
Contact:

Re: Linux 'Native' Widgets

Post by OpenXTalkPaul »

I installed wxWidgets 3 (on macOS) to give that a try (it is LGPL /dual licensed), but it is 17mb for the main libraries and macOS cocoa support libraries only (and that's just for intel CPUs, not 'universal'), a complete cross-platform packaging of that would need to include the support libraries for Windows, Linux (GTK), etc. too.
I think it might be better to have our own libraries to tap into these platform UI kits directly, and then tie them together for our own unified UI library, which would be similar to what wxWidgets provides. Of course that's all a sh*t-TON of work, but the end result would be a package that didn't need to include like probably 50mb of supporting libraries... and people already think OXT DPE is 'heavy' so...
User avatar
richmond62
Posts: 2774
Joined: Sun Sep 12, 2021 11:03 am
Location: Bulgaria
Contact:

Re: Linux 'Native' Widgets

Post by richmond62 »

'Native' in single-quotes because there is no 'Native' in Linuxes is there?
No, BUT, there might be GNOME-native, XFCE-native, LXQt-native, and so on.
https://richmondmathewson.owlstown.net/
User avatar
richmond62
Posts: 2774
Joined: Sun Sep 12, 2021 11:03 am
Location: Bulgaria
Contact:

Re: Linux 'Native' Widgets

Post by richmond62 »

people already think OXT DPE is 'heavy' so...
I can see nothing wrong with there being 2 variants:

OXT light (erm: I think we already have something in that direction).

OXT heavy (isn't that what your's is already?).

People who don't need all the bells and whistles that you, Paul, have laboured so long to include, can opt for 'light', while those want the 'whole thing' can opt for 'heavy'.
https://richmondmathewson.owlstown.net/
User avatar
OpenXTalkPaul
Posts: 1574
Joined: Sat Sep 11, 2021 4:19 pm
Contact:

Re: Linux 'Native' Widgets

Post by OpenXTalkPaul »

richmond62 wrote: Sat Jan 27, 2024 5:19 pm
'Native' in single-quotes because there is no 'Native' in Linuxes is there?
No, BUT, there might be GNOME-native, XFCE-native, LXQt-native, and so on.
Well all of those comply to some extent with the FreeDesktop.org specifications, but it's not like there's any compliance requirement or governing body really.
User avatar
richmond62
Posts: 2774
Joined: Sun Sep 12, 2021 11:03 am
Location: Bulgaria
Contact:

Re: Linux 'Native' Widgets

Post by richmond62 »

any compliance requirement
No there isn't: and your spending an awful lot of time to keep Fred happy because he happens to have FrankensteinOS Linux is a terrible waste of your time.

Personally I would look at which distros are the most popular and target those.

Off the top of my head I'd go for Ubuntu, Mint, Debian, and anything sporting XFCE: but that's just me and my subjective judgement.

A quick "run round" all the friends and acquaintances you have who run some sort of Linux should give you a fairly representative picture. 8-)

After all, if you "pop over" to the LiveCode site you should be able to find something about their system requirements.

(I couldn't just now.)

Here is an extract from the LC 963 PDF:

"All Operating Systems
To use LiveCode you will need:
1024x768 or larger monitor
True color display (16-bit or 32-bit depth) At least 256Mb of memory
At least 150Mb of disk space

Requirements for Windows Systems
LiveCode supports the following versions of Windows: Windows 2000 SP4
Windows XP SP2 and above
Windows Server 2003
Windows Vista SP1 and above (both 32-bit and 64-bit) Windows 7 (both 32-bit and 64-bit)
Windows Server 2008

Requirements for Linux Systems
The minimal requirements for LiveCode to run on Linux are:
32-bit installation, or a 64-bit linux distribution that has a 32-bit compatibility layer 2.4.x or later kernel
glibc 2.3.2 or later X11R5 capable Xserver running locally on a 24-bit display* compositing window manager (optional - required for alpha-blended window shapes) gtk/gdk/glib (optional - required for native theme support)
pango/xft (optional - required for pdf printing, anti-aliased text and unicode font support) lcms (optional - required for color profile support in JPEGs and PNGs)
gksu (optional - required for elevate process support)
mplayer (optional - required for video playback)
esd (optional - required for audio playback)
Although impossible to test every existing Linux distribution, we are aiming to ensure that LiveCode runs on as wide a variety of systems as possible. To achieve this, the engine has been implemented to have minimal direct dependencies on system software, and will gracefully degrade in feature set if it cannot find the libraries it needs. Generally any recent linux distribution including Gnome/GTK support will have the required libraries for full feature support – for example, Ubuntu 7 supports all these features (although alpha blended window shape support requires you to be running with 'Advance Desktop Effects' turned on).

Requirements for Mac OS X Systems
LiveCode supports the following versions of Mac OS X:
10.6.x (Snow Leopard) 10.7.x (Lion)
10.8.x (Mountain Lion) 10.9.x (Mavericks) 10.10.x (Yosemite) 10.11.x (El Capitan)"

Although mention of Ubuntu 7 suggests quite a bad case of 'lazy toads'.

https://ubuntu.com/
https://richmondmathewson.owlstown.net/
User avatar
OpenXTalkPaul
Posts: 1574
Joined: Sat Sep 11, 2021 4:19 pm
Contact:

Re: Linux 'Native' Widgets

Post by OpenXTalkPaul »

richmond62 wrote: Sat Jan 27, 2024 5:22 pm OXT heavy (isn't that what your's is already?).
In my opinion, No, not really, it's similar in file size to what LC Community was, the size which I put some (small) effort into trying to maintain.
The libraries I've added are all small with biggest exception of libFluidSynth's (which I've reduced the package size by only including a tiny fallback soundbank) followed by a library that is less than 10mb but comes with thousands of useful Symbolic SVG Icons. If they aren't being used they shouldn't increase memory requirements for the IDE so it's not heavy in that respect either.
Those additions were offset slightly by removing some things like extra IDE Themes (for like Windows9x), but there is probably more that could be trimmed out. I'm reluctant to remove stuff like 'MetaCard Compatibility images because I may want to open an old .mc or .rev file that uses them.
User avatar
richmond62
Posts: 2774
Joined: Sun Sep 12, 2021 11:03 am
Location: Bulgaria
Contact:

Re: Linux 'Native' Widgets

Post by richmond62 »

it's similar in file size to what LC Community was
OK: although, arguably there was a bit of bloat round those parts.
-
Screenshot 2024-01-27 at 19.46.29.png
Screenshot 2024-01-27 at 19.46.29.png (205.23 KiB) Viewed 602 times
-
It would be quite interesting to know exactly WHAT the very great difference in size between LC 905 and LC 950 involved.
https://richmondmathewson.owlstown.net/
User avatar
OpenXTalkPaul
Posts: 1574
Joined: Sat Sep 11, 2021 4:19 pm
Contact:

Re: Linux 'Native' Widgets

Post by OpenXTalkPaul »

The other option would be to NOT include the dependent libraries, so they would need to already be installed in the OS in order to use them. Extensions can bundle library dependencies inside its package and dynamically load them from there, so that they don't need to be pre-installed on the operating system.
User avatar
OpenXTalkPaul
Posts: 1574
Joined: Sat Sep 11, 2021 4:19 pm
Contact:

Re: Linux 'Native' Widgets

Post by OpenXTalkPaul »

30mb, 50mb, or even 100mb is not a significant difference to me, these days.
User avatar
richmond62
Posts: 2774
Joined: Sun Sep 12, 2021 11:03 am
Location: Bulgaria
Contact:

Re: Linux 'Native' Widgets

Post by richmond62 »

30mb, 50mb, or even 100mb is not a significant difference to me, these days.
Probably not to many people either.

I was just remembering my Mac LC 475 with a 40 MB hard drive.

Mind you, I still want to know exactly WHAT the very great difference in size between LC 905 and LC 950 involved. 8-)
https://richmondmathewson.owlstown.net/
User avatar
OpenXTalkPaul
Posts: 1574
Joined: Sat Sep 11, 2021 4:19 pm
Contact:

Re: Linux 'Native' Widgets

Post by OpenXTalkPaul »

richmond62 wrote: Sat Jan 27, 2024 5:57 pm
30mb, 50mb, or even 100mb is not a significant difference to me, these days.
Probably not to many people either.

I was just remembering my Mac LC 475 with a 40 MB hard drive.
I still have a few 40 & 80mb SCSI drives around for vintage fun, but I was thinking of upgrading to solid-state with the SCSI-SDCard adapters that are available now. Just for kicks I'd like to see my Mac512KE max out that 5MB/sec async throughput of SCSI 1, lol.
User avatar
OpenXTalkPaul
Posts: 1574
Joined: Sat Sep 11, 2021 4:19 pm
Contact:

Re: Linux 'Native' Widgets

Post by OpenXTalkPaul »

In the long-run if we replaced all the pixel icons with SVG Paths, the whole would be a much smaller file size.
A well crafted vector graphic can be quite small, render well at any size, be darkMode ready, AND render much faster than pixel images. Don't believe me, just look for yourself at the reasons why SWF / Flash was so successful.
User avatar
richmond62
Posts: 2774
Joined: Sun Sep 12, 2021 11:03 am
Location: Bulgaria
Contact:

Re: Linux 'Native' Widgets

Post by richmond62 »

I am perfectly prepared to believe you.

But I wonder why SWF/Flash went the way of all flesh if it was so successful.

And: would the tedious process of converting everything to SVG be justified by the shrinkage when, as you pointed out: the size is probably not that big a problem to most users?
https://richmondmathewson.owlstown.net/
User avatar
OpenXTalkPaul
Posts: 1574
Joined: Sat Sep 11, 2021 4:19 pm
Contact:

Re: Linux 'Native' Widgets

Post by OpenXTalkPaul »

richmond62 wrote: Sat Jan 27, 2024 6:12 pm I am perfectly prepared to believe you.

But I wonder why SWF/Flash went the way of all flesh if it was so successful.

And: would the tedious process of converting everything to SVG be justified by the shrinkage when, as you pointed out: the size is probably not that big a problem to most users?
Yeah the size isn't really an issue, although monitor pixel density has been increasing. I've used screen that were 144ppi and 288ppi vs the 1990s when they were all 72ppi. SVG is scalable. I mostly want to do it for a sub-set of icons, like the tools palette, because 'Symbolic' icons can auto-toggle between light/dark. I kind of like the revMenuBar Toolbar icons being in color though.

Rendering speed isn't why Flash 'died', it was the security issues that kept coming up, the demise of Browser Plug-ins, and probably to some degree a general desire to not use Adobe-owned proprietary format. SVG came from Adobe but it is an open-standard (like PDF, and Compuserve GIF are now too), and with HTML5+modern JS that pretty much can fill the role that Flash did.

Not sure if Google still has their own Flash support built-in to Chrome (since they switch engine to Blink from their own Chromium). There are open-source Flash Engines, people can still use Flash to develop for Desktop apps. There's also Adobe Flex and Adobe Animate so the underlying technology sort of never really died.
User avatar
OpenXTalkPaul
Posts: 1574
Joined: Sat Sep 11, 2021 4:19 pm
Contact:

Re: Linux 'Native' Widgets

Post by OpenXTalkPaul »

richmond62 wrote: Sat Jan 27, 2024 5:47 pm It would be quite interesting to know exactly WHAT the very great difference in size between LC 905 and LC 950 involved.
A bunch of different copies of Chromium Engine for Browser widget support on various supported platforms (Linux, Android, Windows) and CPU (Intel 32 & 64 bit, and ARM/Android) architectures. They are the largest components included with the IDE, by far!

In 9.6.3 only macOS/iOS uses the OS's included Browser Engine, which is Webkit (Safari), so it doesn't need the Mac Chromium Libs included for Mac/iOS (as they previously were for macOS in v6 & 7). LC stated they switched to WebKit across the board in new versions. I'm not sure if different Webkit lib builds are bundled with their IDE for Win/Linux, but I would guess they need to be.
Post Reply

Who is online

Users browsing this forum: No registered users and 17 guests