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

Problems with "setGeometryHints" #74

Open
lscrd opened this issue May 23, 2020 · 9 comments
Open

Problems with "setGeometryHints" #74

lscrd opened this issue May 23, 2020 · 9 comments

Comments

@lscrd
Copy link

lscrd commented May 23, 2020

The interface of setGeometryHints is the following:
proc setGeometryHints*(self: Window; geometry: Geometry; geomMask: WindowHints)

There are two problems with this interface.

First, WindowHints is an enum. As we expect a mask, it should be either an int (which we can initialize by combining values) or a set of enums. The second solution is the preferred way and is actually used at several places in gintro.

Second, when we want to reset the geometry hints, according to the documentation we should transmit a null geometry and a null mask. But Geometry is an object, not a ref object, and, so, there is no way to transmit a null address as expected by the C interface.

I don’t know if is is mandatory to transmit a null address for the geometry. Maybe transmitting any geometry object with a null mask will be sufficient to reset the hints. But this is not what the documentation says and it may be risky to rely on this behavior even if it works.

@StefanSalewski
Copy link
Owner

Thanks for reporting. Yes, it seems that WindowHints should be a set, I will fix it. Passing nil for value objects -- I had that issue some years ago with other functions, have to find out if an overloaded function is necessary or if there was a simpler solution. Will fix it tomorrow.

I think I will not make a new tagged version for this fix, so you would have to install head from github then. I hope you know how to do that, it is something with @Head or so...

@lscrd
Copy link
Author

lscrd commented May 23, 2020

Thanks for your answer.

I’m not a git expert, but I have already installed some development versions. I will find a way to retrieve HEAD.

@StefanSalewski
Copy link
Owner

I had some trouble unfortunately, see

https://discourse.gnome.org/t/gdk-window-set-geometry-hints/3404

So fix may take some more time.

@StefanSalewski
Copy link
Owner

The good news is that the gdk.Geometry = castptr gdk.Geometry[]; as used in

grep -A7 gtk_window_set_geometry_hints ~/gintrotest/tests/nim_gi/gtk.nim 
proc gtk_window_set_geometry_hints(self: ptr Window00; geometryWidget: ptr Widget00;
    geometry: gdk.Geometry; geomMask: gdk.WindowHints) {.
    importc, libprag.}

proc setGeometryHints*(self: Window | WindowAccessible; geometryWidget: Widget = nil;
    geometry: gdk.Geometry = cast[ptr gdk.Geometry](nil)[]; geomMask: gdk.WindowHints) =
  gtk_window_set_geometry_hints(cast[ptr Window00](self.impl), if geometryWidget.isNil: nil else: cast[ptr Widget00](geometryWidget.impl), geometry, geomMask)

seems still to work. I tested with

gtk.setGeometryHints(window, geomMask = {})

which does not crash. That trick was introduced maybe 4 years ago, I first assumed that a compiler change would be the reason that it did not work. But now my impression is that the gdk function just does not allow NULL.

@lscrd
Copy link
Author

lscrd commented May 24, 2020

Oups! I have apparently made a confusion. As my window inherits from gtk.Window, this is indeed the gtk proc I have used, not the gdk one. And I’m inexcusable as I use VSCode which shows me the interface with the default value for the geometry parameter :-(.

So it was a false alert as the trick you have used seems indeed to allow the reset.

To be sure, I have checked on an example. As I have not installed the development version yet, I have used a trick to force the value 0 for the mask parameter. Then, using the default parameter for geometry and 0 for geomMask, I can confirm that the reset works. The hints provided before the call (which in my example constrained the aspect) are indeed forgotten after.

@StefanSalewski
Copy link
Owner

OK, I have reverted the fix for gdk.setGeometryHints() as it crashes when nil is passed for Geometry. I asked at the GTK forum, but there is no reply still. From docs NULL should work, from gobject-introspection not.

Now the only fix is

<   WindowHintsFlag* {.size: sizeof(cint), pure.} = enum
<     pos = 0
<     minSize = 1
<     maxSize = 2
<     baseSize = 3
<     aspect = 4
<     resizeInc = 5
<     winGravity = 6
<     userPos = 7
<     userSize = 8
< 
<   WindowHints* {.size: sizeof(cint).} = set[WindowHintsFlag]
---
>   WindowHints* {.size: sizeof(cint), pure.} = enum
>     pos = 1
>     minSize = 2
>     maxSize = 4
>     baseSize = 8
>     aspect = 16
>     resizeInc = 32
>     winGravity = 64
>     userPos = 128
>     userSize = 256

I think you can install it with nimble install gintro@head

gtk.setGeometryHints(window, geomMask = {}) works as nil is the default value for widget and Geometry, but we have to use a named parameter for the set, otherwise the compiler is confused with the default values. Whenever you want to pass nil for a value object you can use

cast[ptr Geometry](nil)[]

or

(ptr Geometry)(nil)[]

@StefanSalewski
Copy link
Owner

nimble install gintro@#head

@lscrd
Copy link
Author

lscrd commented May 24, 2020

This modification is fine for me. Thanks!

As regards the way to use the default nil value for geometry, I have encountered the compilation problem in my test and indeed, it can be solved by using a named parameter. This is a subtlety to remember for other cases.

I have also been able to install the head version with nimble. The exact command is:
nimble install gintro@#head

@lscrd
Copy link
Author

lscrd commented May 24, 2020

Sorry, I have not got your last message before answering :-).

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

2 participants