-
-
Notifications
You must be signed in to change notification settings - Fork 425
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
Actually override FFI methods in renderer system? #3265
Comments
Your observation is correct: if a method exists in both This follows from the fact that Therefore, the conclusion to draw seems to be: Option 1 should guarantee an uniform cross-renderer behavior. |
@jmercouris expressed that foreign interface design is imperfect. So maybe we can make it better.
Not necessarily. See below.
Or (3, suggested in the top post) override the commands/interfaces in
|
We can, and I have been working in it within the context of #2989. The solution you proposed has the shortcomings that you have outlined in the top post. Our current goal is to have a simple foreign interface without tricks or dark corners. |
I mean, either option has shortcomings. It's about picking the one that's fulfilling the requirements. And the initial suggestion does that, also reducing the line count and making foreign interface less renderer-specific. My only concern about it was it's aesthetic value, and that I'm slowly accepting its minor ugliness for its effectiveness. |
I think that the best way to address this is to tweak |
That sounds wrong, because we're going against CLOS. Still, it's an elegant and simple solution. |
There is some degree of confusion in this thread and the report below attempts to clarify it. The factors that determine whether a renderer-specific method or fallback one (general, for all renderers) is triggered are:
With that in mind, the two strategies below are worth of attention. (define-ffi-generic ffi-foo (buffer)
"..."
;; This strategy would fail if <renderer>-buffer would inherit from buffer.
(:method ((buffer buffer))
(or (call-next-method) (fallback-logic))))
(define-ffi-generic ffi-foo (buffer)
"..."
;; This strategy is more lenient wrt typing. If there is a renderer
;; specialization, it will be invoked instead of the fallback logic below.
(:method ((buffer t))
(fallback-logic))) As of today, we follow the second option and it seems reasonable. It should now be clear that, when running Nyxt with WebKitGTK, the specialized GTK method of Nonetheless, it did trick me for a while as well. I'm keeping the issue open since I'm making a very deep review of |
Our FFI design relies on renderer class inheritance for method specialization. So
renderer-buffer
is a superclass ofbuffer
, allowing one to specialize methods onrenderer-buffer
to add some renderer-specific logic. The problem is: regular classes, being subclasses of renderer ones, are more specific and thus their methods override the renderer-specific methods. Even though it should've happened the other way around.Here's one example:
(setf ffi-buffer-zoom-level)
method.buffer
, use fallback JavaScript-based zooming.gtk-buffer
, use WebKit-provided scrolling.buffer
is inherited fromgtk-buffer
and thus is more specific.One option for fixing it is making our code a bit dirtier with actual renderer-specific overrides. Even though we make our FFI architecture harder to grasp, it ensures that we actually override the necessary methods. In case of example above, we can do:
in renderer/gtk.lisp. This will override the method from buffer.lisp, which is bad. But it'll also ensure that only the renderer-specific methods are called. And it's also quite Lispy—monkey-patching the imperfect behavior to make it better 😛
Originally posted by @aartaka in #3250 (comment)
The text was updated successfully, but these errors were encountered: