Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gtk eventBox with Gintro #201

Closed
dmknght opened this issue Apr 6, 2022 · 17 comments
Closed

Gtk eventBox with Gintro #201

dmknght opened this issue Apr 6, 2022 · 17 comments

Comments

@dmknght
Copy link

dmknght commented Apr 6, 2022

Hello! I found very interesting code that use EventBox to make label be a click object (from information on Google, it can make Widgets be clickable but EventBox is removed in GTK4). URL: https://www.tutorialspoint.com/pygtk/pygtk_eventbox_class.htm
I'm wondering is it possible to use it with Gintro? I'm having this message while trying it

undeclared identifier: 'gboolean'

candidates (edit distance, scope distance); see '--spellSuggest':
(1, 5): 'boolean' [proc declared in /home/dmknght/.nimble/pkgs/gintro-0.9.6/gintro/gobject.nim(1481, 6)]

I think my code is wrong. Callback function needs Event and i don't know how to create it. My code:

let evBox = newEventBox()
evBox.connect("button-press-event", switch_stack, myGTKStack) # 
@StefanSalewski
Copy link
Owner

Are you a long time gintro user? If yes, please try our latest v0.9.8 candidate with nimble install gintro@#head, as we intent to tag this release soon. If you should be new to gintro, please note that we are considering not accepting new users any more. Our current user base is one or two people including me, and maybe that is a good time to close this package.

For your concrete question: I heard of the GtkEventBox, but I think I never used it myself. When you say that it is removed in GTK4, them maybe we really should not use it any longer, you may ask on the Gnome forum for a replacement. Using old GTK3 stuff is really a bad idea, as for GTK4 a lot has changed. Recently I ported an old GTK3 app for someone to Nim, and at the end I discovered that all that was useless for recent GTK4.

Currently I do not see the advantage of a clickable label over a regular button. So please ask on the Gnome forum first. When they tell us that EventBox makes some sense still (for GTK4) I will investigate that further.

@gavr123456789
Copy link

gavr123456789 commented Apr 6, 2022

@dmknght In GTK 4 you can add any event(like right/middle/left click) on any widget with GTK Controllers.
Here how I added middle click for button https://github.com/gavr123456789/Katana/blob/master/REWRITE/page.nim#L146 (button 2 is middle click)
And here right click for box: https://github.com/gavr123456789/Katana/blob/master/REWRITE/page.nim#L269

Bonus: how to add keyboard shortcuts https://github.com/gavr123456789/Katana/blob/master/REWRITE/gtk_utils/shortcuts.nim#L72

@dmknght
Copy link
Author

dmknght commented Apr 6, 2022

Are you a long time gintro user?

Well you can say that. But in other hand, i don't always use gintro. I mean for now i am having only 1 project that use it.

If yes, please try our latest v0.9.8 candidate with nimble install gintro@#head

Oh i forgot to mention: I'm using v0.9.6. It's the most stable for me (i tested building on amd64, i386 and arm64, everything is good) so i'm using it officially. I didn't try later version. Version 0.9.7 failed to build.

Using old GTK3 stuff is really a bad idea

I think it's not that old but well it makes sense to use other solution that is supported in the future so I don't have to replace the whole code. At this point I agree with you.

Currently I do not see the advantage of a clickable label over a regular button

A label is just an example. EventBox can be added to Frame, Box, widget, ...
Here is my GUI
image

From my point of view, create an other button is not very beautiful. My idea is when user click on the first frame (except disabled buttons, which will be enabled when user clicks on start), the main widget switches to other widget. In previous version, I have 1 button for this. But for newer version, I prefer click on the whole GUI. This idea is similar to Kaspersky AV GUI.

So please ask on the Gnome forum first. When they tell us that EventBox makes some sense still (for GTK4) I will investigate that further.

The reason I asked here is because I tried code with python and it worked, and Gintro doesn't. I checked the api and it didn't help much. But if you want to drop EventBox support, I'd try other solution.

@dmknght In GTK 4 you can add any event(like right/middle/left click) on any widget with GTK Controllers.
Here how I added middle click for button https://github.com/gavr123456789/Katana/blob/master/REWRITE/page.nim#L146 (button 2 is middle click)

Hello and thank you very much for the info. The distro I'm using supports only GTK3 so I can't use new features of GTK4. I noticed you have newGestureClick() which I saw on stackoverflow, rust code. I'll try your code and see what can be used on my system.

@StefanSalewski
Copy link
Owner

OK, here is a GTK3 version from your linked Python example:

import gintro/[gtk, gdk, glib, gobject, gio]

#[
https://docs.gtk.org/gtk3/signal.Widget.button-press-event.html
gboolean
button_press_event (
  GtkWidget* self,
  GdkEventButton event,
  gpointer user_data
)
]#
proc hello1(w: EventBox; e: gdk.EventButton): bool =
  echo "clicked label 1"

proc hello2(w: EventBox; e: gdk.EventButton): bool =
  echo "clicked label 2"

proc appActivate (app: Application) =
  let window = newApplicationWindow(app)
  window.title = "EventBox demo"
  # window.defaultSize = (250, 50)
  window.setSizeRequest(200,100)
  window.setPosition(gtk.WindowPosition.center)
  var fixed = gtk.newFixed()
  var event1 = gtk.newEventBox()
  var label1 = gtk.newLabel("Label 1")
  event1.add(label1)
  fixed.put(event1, 80,20)
  connect(event1, "button_press_event", hello1)
  var event2 = gtk.newEventBox()
  var label2 = gtk.newLabel("Label 2")
  event2.add(label2)
  event2.connect("button_press_event", hello2)
  fixed.put(event2, 80,70)
  window.add(fixed)
  window.showAll

proc main =
  let app = newApplication("org.gtk.example")
  connect(app, "activate", appActivate)
  discard app.run

main()

Actually it is not that easy to get the connect() right, took me a full have hour. With a working C code it might have been easier, with Python I have always some trouble. The signal is similar like the GTK3 "draw" signal, we get one more parameter in our callback. So I had to consult the API docs. But the Python code seems to be old, I think setSizeRequest() is not recommended for a top level window, and fixed widgets are also not really recommended. And finally, I guess this is only for GTK3, for GTK4 it may look different...

@dmknght
Copy link
Author

dmknght commented Apr 6, 2022

Wow this is awesome! Thanks a lot.

Actually it is not that easy to get the connect() right, took me a full have hour.

Well that was my error as well. The python code looked very easy but the backend (with Nim) was a little hard. Did you use any extra flag when build with Nim? Or did you patch the gintro? I tried your script with latest gintro
nimble install gintro@#head, then i compiled nim c /tmp/eventbox.nim. Here's the error i got

/home/dmknght/.nimble/pkgs/gintro-#head/gintro/gobject.nim(849, 16) Error: undeclared identifier: 'generic_g_param_spec_uref'
candidates (edit distance, scope distance); see '--spellSuggest': 
 (1, 3): 'generic_g_param_spec_unref' [proc declared in /home/dmknght/.nimble/pkgs/gintro-#head/gintro/gobject.nim(526, 6)]

@StefanSalewski
Copy link
Owner

Here's the error i got

Thanks for testing. I had the feeling that there may be some trouble, that is why I ask people to test. The problem is #200, which I tried to fix. Latest gobject renamed uref to unref, I tried to fix that carefully, but was then unable to test the fix with old gobject. Will look at your error report later, hopefully I can understand what I did wrong.

@dmknght
Copy link
Author

dmknght commented Apr 6, 2022

Here's the error i got

Thanks for testing. I had the feeling that there may be some trouble, that is why I ask people to test. The problem is #200, which I tried to fix. Latest gobject renamed uref to unref, I tried to fix that carefully, but was then unable to test the fix with old gobject. Will look at your error report later, hopefully I can understand what I did wrong.

Ah i get it! Thank you! Btw when I said the newer version of gintro doesn't work for me (> 0.9.6), here is the error i got

stack trace: (most recent call last)
gimplgobj.nim(99, 13)    mconnect
/home/dmknght/ParrotProjects/anonsurf/nimsrc/anonsurf/AnonSurfGTK.nim(45, 13) template/generic instantiation of `connect` from here
/home/dmknght/.nimble/pkgs/gintro-#head/gintro/gimplgobj.nim(99, 13) Error: node is not a symbol

The code is really simple, and it works very well with 0.9.6
btnRestart.connect("clicked", ansurf_gtk_do_restart, cb_send_msg)
Is this a known issue or do you want me to create new issue?

@StefanSalewski
Copy link
Owner

I tried to fix it, please try again with

nimble install gintro@#head

I can unfortunately not test, as I found no way to reinstall a very old gobject on my Gentoo box again.

For your other issue with v0.9.7: We did a lot of changes at the end of the last year, as Mr. avr had some issues. He is using tuples as optional parameters with the connect() macro -- that was initially not intended, and never tested, but it was working. But then he updated GTK and got some name conflicts. We tried to fix that, with some ugly patches. A cleaner patch would require to rewrite the mconnect macro to use plain AST manipulations, and no string manipulations. That may avoid name conflicts, at least that would be our hope. Maybe some days of work for someone really good in macro writing. But as we got no error reports, we just assumed that the ugly fix was good enough.

@dmknght
Copy link
Author

dmknght commented Apr 6, 2022

I tried to fix it, please try again with

nimble install gintro@#head

I can unfortunately not test, as I found no way to reinstall a very old gobject on my Gentoo box again.

For your other issue with v0.9.7: We did a lot of changes at the end of the last year, as Mr. avr had some issues. He is using tuples as optional parameters with the connect() macro -- that was initially not intended, and never tested, but it was working. But then he updated GTK and got some name conflicts. We tried to fix that, with some ugly patches. A cleaner patch would require to rewrite the mconnect macro to use plain AST manipulations, and no string manipulations. That may avoid name conflicts, at least that would be our hope. Maybe some days of work for someone really good in macro writing. But as we got no error reports, we just assumed that the ugly fix was good enough.

I completely remove all gintro to make sure i'm having fresh one nimble uninstall gintro and then nimble install gintro. The code of EventBox worked but my project didn't. I'm creating new issue for it :D

@StefanSalewski
Copy link
Owner

The code of EventBox worked but my project didn't. I'm creating new issue for it :D

Fine that EventBox works now. I just found your anon code at github, I will try to install and test.

@dmknght
Copy link
Author

dmknght commented Apr 6, 2022

Fine that EventBox works now. I just found your anon code at github, I will try to install and test.

Oh it's not the latest version i think. The code on github is mirrored. If you want latest commits, pls try https://nest.parrotsec.org/packages/tools/anonsurf
P/s: My code is super ugly and I can't improve the code logic =="

@dmknght
Copy link
Author

dmknght commented Apr 6, 2022

@StefanSalewski Thank you a lot for your commits today. I made this feature work for me. I got gtk warning like this

(anonsurf-gtk:962842): Gtk-WARNING **: 02:25:06.848: Attempting to add a widget with type GtkBox to a container of type GtkEventBox, but the widget is already inside a container of type GtkEventBox, please remove the widget from its existing container first.

but it seems like it's my code is having wrong structure rather than the backend problem. I'm closing this issue as well. Thanks a lot!

@dmknght dmknght closed this as completed Apr 6, 2022
@StefanSalewski
Copy link
Owner

Yes, that issue seems to be not related to gintro. If you can not solve it yourself or with Google, you may ask at Gnome forum. I just tried by minimal proc example with --gc:arc, seems to work also. But I am still not sure if a GC_ref() may be additional necessary, that is a difficult question. When we should get crashes, we may add that.

I have to admit that I launched your program and got only a crash, as in

$ ./anonsurf-gtk 
SIGSEGV: Illegal storage access. (Attempt to read from nil?)
Segmentation fault (core dumped)

But I think I just used it wrong. Let me know when you need more support.

@dmknght
Copy link
Author

dmknght commented Apr 6, 2022

I have to admit that I launched your program and got only a crash, as in

Oh did you use make build or just nim c? I passwed gc:arc in nims file. I found out it didn't crash when I didn't use callback. But when I added callback procs, I had to add gc:arc into build flags. Idk why. I saw a line in gintro that caused crash. I asked it in Nim channel on Telegram and likely it's a specific issue
P/s: here is the screenshot
image
Here's the code part in 0.9.6. Not sure if it's the same in latest version
image
I think data was NULL randomly so cast crashed program but i'm not so sure

@dmknght
Copy link
Author

dmknght commented Apr 6, 2022

that issue seems to be not related to gintro

LoL turned out I added a box into EventBox 2 times by mistake :D It's fine now.

@StefanSalewski
Copy link
Owner

I did make build. But I do not understand what exactly your program shall do, and I do not know exactly how to handle proc parameters in the connect macro. One critical part in mconnect is

  # maybe we write this better this way:
  let r2s =
    if ignoreArg.boolVal:
      """
proc $1(self: $2;  p: proc $3): culong {.discardable.} =
  sc$4(self, $5, nil, $8)
$1($6, $7)
""" % [$procName, wts, ahl, signalName,  $procNameCdecl, $(widget.toStrLit), $p, sfstr, sigName]
    elif getTypeInst(arg).typeKind == ntyRef:
      """
proc $1(self: $2;  p: proc $3; a: $4): culong {.discardable.} =
  GC_ref(a)
  sc$5(self, $6, cast[pointer](a), $10 $11)
$1($7, $8, $9)
""" % [$procName, wts,  ahl, ats, signalName,  $procNameCdecl, $(widget.toStrLit), $p, $(arg.toStrLit), sfstr, sigName]
    else:
      """
proc $1(self: $2;  p: proc $3; a: $4): culong {.discardable.} =
  var ar: ref $4
  new(ar)
  #deepCopy(ar[], a)
  ar[] = a
  GC_ref(ar)

Initial this code was only to differentiate between ref parameters and value parameters, for ref we do GC_ref(), but value parameters get copied. All that was written in 2016 and 2017, and no one was willing to help. I spent about 1600 hours for gintro, and in 2015 already 600 hours for oldgtk3. And after all these years and all that work we have maybe 2 or 3 users. So I am a bit tired now.

For your proc parameter, you may investigate a bit yourself if a proc is more a reference that may need only a GC_ref, or a value object that gets copied. I think currently it get copied, which may not be the best solution.

Note that the easiest way to do some experiments is, to directly edit the file ~/.nimble/pkgs/gintro-#head/gintro/gimplgobj.nim

AS you have seen yourself, mconnect() has become very ugly, we would have to rewrite it by using only AST manipulation, no string ops.

Have to sleep now, bye.

@dmknght
Copy link
Author

dmknght commented Apr 6, 2022

I did make build

Hm then it should compile with --gc:arc by default. I don't really know this. Maybe it's about gtk and backend problem. I don't really know. The arm64 build was fine as well.

But I do not understand what exactly your program shall do

Well it's a little bit hard to explain because it has a lot, from just click button to start / stop a service to do real time status to check if the service is running, ... I'd say most part of the code is do check current status. The callback procs are to handle either echo on CLI, or show notifications, because I don't have to rewrite the same code structure for different UI.

So I am a bit tired now.

Well I totally get it! The gintro is so huge. It's not just create bindings for GTK, but handle the other things as well to make it be Nim friendly. It's too hard to complete it, especially very uncommon parts like EventBox; and it's very easy to mess everything up like macro.

I think currently it get copied

I honestly don't know LoL. I just tried the python like syntax, which works with Python, and for some reason it worked for me so I just used it. Before I used this, I worked on ClamAV binding and it uses sort of passing procs as callback functions. Well it works then it works.

Have to sleep now, bye.

LoL I have to sleep as well. It was a great time because I didn't think I could made this feature. Good night man!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants