Git Product home page Git Product logo

Comments (7)

aadcg avatar aadcg commented on May 24, 2024

Your observation is correct: if a method exists in both foreign-interface and one of the renderers, then the most specific one (the one from foreign-interface) prevails.

This follows from the fact that buffer inherits from renderer-specific-buffer, as you noted. We can ask: "could it have been the other way around?". Maybe, but we have invested in the current design and it has been serving us well.

Therefore, the conclusion to draw seems to be: foreign-interface must only define methods in case the implementation serves all renderers. In other words, we can either (1) delete the method in gtk.lisp and accept that ffi-buffer-zoom-level is implemented via JS and that's how it will work for all renderers, or (2) delete that method in foreign-interface.

Option 1 should guarantee an uniform cross-renderer behavior.

from nyxt.

aartaka avatar aartaka commented on May 24, 2024

This follows from the fact that buffer inherits from renderer-specific-buffer, as you noted. We can ask: "could it have been the other way around?". Maybe, but we have invested in the current design and it has been serving us well.

@jmercouris expressed that foreign interface design is imperfect. So maybe we can make it better.

Therefore, the conclusion to draw seems to be: foreign-interface must only define methods in case the implementation serves all renderers.

Not necessarily. See below.

In other words, we can either (1) delete the method in gtk.lisp and accept that ffi-buffer-zoom-level is implemented via JS and that's how it will work for all renderers, or (2) delete that method in foreign-interface.

Or (3, suggested in the top post) override the commands/interfaces in renderer/gtk. This way, we have

  • clean FFI architecture,
  • sane (JS) fallbacks,
  • and meningful renderer-specific behavior.

from nyxt.

aadcg avatar aadcg commented on May 24, 2024

So maybe we can make it better.

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.

from nyxt.

aartaka avatar aartaka commented on May 24, 2024

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.

from nyxt.

aadcg avatar aadcg commented on May 24, 2024

I think that the best way to address this is to tweak :method-combination.

from nyxt.

aartaka avatar aartaka commented on May 24, 2024

That sounds wrong, because we're going against CLOS. Still, it's an elegant and simple solution.

from nyxt.

aadcg avatar aadcg commented on May 24, 2024

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:

  1. primary methods in CLOS run in most-specific-first order by default;
  2. the inheritance relationship between renderer and non-renderer classes (i.e. either buffer inherits from <renderer>-buffer or vice-versa);
  3. the method's specialized-lambda-list (i.e. ((buffer t)) and ((buffer buffer)) are radically different).

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 ffi-buffer-zoom-level is being honored. Note that the corresponding method defined in foreign-interface (relying on JS) takes (buffer) as argument (i.e. ((buffer t))), meaning that the GTK method is more specific and the conclusion follows.

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 foreign-interface.

from nyxt.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.