1. 06 Eki, 2015 1 kayıt (commit)
  2. 05 Eki, 2015 7 kayıt (commit)
    • Thomas Martitz's avatar
      plugins: reselect when toggling the current plugin · 8ac9d56f
      Thomas Martitz yazdı
      When enabling/disabling pluxys in the PM dialog the list of available
      plugins might change. If plugins before the pluxy go/come then the wrong
      plugin becomes selected (the selected row number stays the same). Re-apply
      the selection to the current one in the toggle callback to overcome this issue.
      8ac9d56f
    • Thomas Martitz's avatar
      plugins: add geany_plugin_register_proxy() to the plugin API · 6e5ca69e
      Thomas Martitz yazdı
      This function finally allows plugins to register themselves as a proxy
      for one or more file extensions.
      
      Lots of documentation is added to doc/plugins.dox, please refer to that for more
      details.
      6e5ca69e
    • Thomas Martitz's avatar
      plugins: introduce probe() for proxy plugins · 3ccf9590
      Thomas Martitz yazdı
      When a file extension alone is ambigious as to whether a potential plugin is
      really handled then the proxy should use the probe hook to find out. This can
      be especially helpful when two pluxies work on the same file extension.
      
      The proxy's probe() should return PROXY_IGNORED or PROXY_MATCHED accordingly.
      A special flag value, PROXY_NOLOAD, can be or'ed into PROXY_MATCHED to say
      that the file belongs to the proxy, but isn't directly loaded and should not
      be handled by any other proxy or geany itself.
      
      Example for PROXY_IGNORED:
      geanypy only supports python2 at the moment. So, scripts written
      for python3 aren't handled by it and should be skipped for the PM dialog.
      Or perhaps they are handled by another proxy that supports python3.
      
      Example for PROXY_NOLOAD:
      A pluxy registers for the metadata file extension (.plugin) where author etc
      is in. The actual implmentation is in a python script (.py). The .py file
      is tied to the .plugin and should not be processed by other pluxies. Thus,
      the pluxy also registers for the .py extension but returns
      PROXY_MATCHED|PROXY_NOLOAD for it (if it would return only PROXY_MATCHED
      the sub-plugin would show up twice in the PM dialog).
      3ccf9590
    • Thomas Martitz's avatar
      plugins: when loading active ones, loop until no more proxy plugins are added · e5bb6571
      Thomas Martitz yazdı
      During the loading of the active plugins they are also initialized (done at
      startup). As a result, these plugins could be pluxys and make more plugins
      available, some of which may be active as well.
      
      Because of this the loop has to be restarted if pluxies become
      available to also load active plugins that depend on the pluxy.
      
      The loop is only restarted at the end so only nested pluxys could possibly
      cause the loop to be run more than twice.
      e5bb6571
    • Thomas Martitz's avatar
    • Thomas Martitz's avatar
      plugins: generic load_data instead of module pointer in Plugin struct · bdaab9c8
      Thomas Martitz yazdı
      Being a GModule is actually a detail of standard plugins. Future proxy plugins
      might need different handles. Therefore replace the module field with a more
      generic pointer and encapsulate the GModule detail further.
      
      This pointer shall be returned from GeanyProxyFuncs::load and is passed back
      to GeanyProxyFuncs::unload, and isn't interpreted by Geany.
      bdaab9c8
    • Thomas Martitz's avatar
      plugins: introduce load and unload functions for plugins · d008675b
      Thomas Martitz yazdı
      Currently they encapsulate loading and unloading of standard plugins. In
      the future plugins can provide such functions to load their types of plugins.
      
      Such a dummy proxy plugin is implemented now to load standard plugins so
      that these aren't going to be specially handled.
      d008675b
  3. 24 Agu, 2015 1 kayıt (commit)
  4. 23 Agu, 2015 12 kayıt (commit)
    • Colomban Wendling's avatar
      Merge pull request #469 from kugel-/new_hooks · 280163a2
      Colomban Wendling yazdı
      Plugin loader redesign
      280163a2
    • Colomban Wendling's avatar
      b7bcf14d
    • Thomas Martitz's avatar
      plugins: Clarify which API functions may be called within geany_load_module() · 765000be
      Thomas Martitz yazdı
      Since geany_load_module() is called for non-enabled plugins you may not
      use the plugin API here yet. The only exceptions to this rule are API functions
      required for plugin registration.
      
      This rule is hard to enforce (would need to g_return_if_val(PLUGIN_LOADED_OK(p))
      for all API functions (well, those taking a plugin pointer anyway), so this
      rule is only documented for now.
      765000be
    • Thomas Martitz's avatar
      plugins: separate geany_plugin_set_data() dual-use · 437837d3
      Thomas Martitz yazdı
      It was found that because geany_plugin_set_data() could be used by both
      plugin's init() and geany_load_module(), that it introduced some uncertainty
      as to when to call the free_func. init() callers might expect the call
      around the same time as cleanup() is called, while geany_load_module()
      callers expected the call at module unload time.
      
      It was indeed called at module unload time. But that means that init() callers
      cannot call it again reliably after in a init()->cleanup()->init() flow (when
      toggling the plugin) without fully unloading the plugin (which is what we do
      currently but that's we would want to change).
      
      With the separation we can actually destroy the data depending on where
      it was set and do everything unambigiously.
      437837d3
    • Thomas Martitz's avatar
      plugins: Updated doxygen for the new plugin loader · d54b65b9
      Thomas Martitz yazdı
      The documentation provides a quite detailed description of the new loader
      In addition it adds a "how to transition" that briefly describes the old
      loader (for curious newcomers) and lots of hints for porting legacy
      plugins to the new loader.
      d54b65b9
    • Thomas Martitz's avatar
      plugins: Pass pdata to PluginCallback function by default · 58c8144a
      Thomas Martitz yazdı
      If the plugin did not set its own user_data we set it to whatever it set
      with geany_plugin_register_full() or geany_plugin_set_data().
      This is particularly convinient because PluginCallback is usually statically
      allocated, at which point dynamically allocated plugin data doesn't exists yet.
      58c8144a
    • Thomas Martitz's avatar
      plugins: change return codes of geany_load_module() and GeanyPluginFuncs::init · 43c58e0f
      Thomas Martitz yazdı
      - The return value from geany_load_module is removed (void). It was ignored
        anyway and we have to check separately whether the plugin loaded OK or not
        anyway. If the plugin specific code fails it should simply not call
        geany_plugin_register() (which it should only call iff all other conditions
        are good).
      
      - GeanyPluginFuncs::init() now returns a bool to allow failing initialization.
        Some plugins might want to defer work to their init() (i.e. only do
        it when the plugin was activated by the user), and some of that work can
        possibly fail (e.g. GtkBuilder fails to load .xml).
      
      Note that the GUI integration of the latter is less than ideal but this kind
      of GUI/policy work is out of scope for this patch set. Therefore a plugin
      failing to init is simply removed from the PM dialog as if it became
      incompatible. However, as the code that generates the list does not call init
      they will show up again if the PM dialog is re-opened.
      43c58e0f
    • Thomas Martitz's avatar
      demoplugin: Adapt demoplugin to the new loader · 82412784
      Thomas Martitz yazdı
      Demoplugin, while not installed by default, is a nice starting point
      and mini-howto. Therefore it should advertise the new loader from the
      beginning.
      82412784
    • Thomas Martitz's avatar
      plugins: Refactor legacy plugin support · 75827c69
      Thomas Martitz yazdı
      With geany_plugin_set_data() the legacy plugin support can be made
      more transparent by using wrapper functions that call the actual plugin_*
      functions. This allows to remove the differentiation in code that's not
      directly concerned with actually loading plugins.
      
      This commit doesn't change anything except for one thing: legacy plugins now
      cannot call geany_plugin_set_data(). But it is meant for new-style plugins
      anyway.
      75827c69
    • Thomas Martitz's avatar
      plugins: Replace geany_plugin_register() pdata with a separate API function · f2579141
      Thomas Martitz yazdı
      The API function adds a free_func parameter, and can also be called
      after geany_plugin_register(), i.e. in the plugin's init() callback. This
      fixes a by-design memory leak and gives greater flexibility.
      f2579141
    • Thomas Martitz's avatar
      plugins: Let plugins fill GeanyPlugin::callbacks instead of passing their own pointer · babf0083
      Thomas Martitz yazdı
      This is easier to handle if we decide to add callbacks. Since we can
      zero-initialize callbacks before passing it to the plugin we can be certain as
      to which callbacks the plugin knew about when it was compiled. This is exactly
      the same method used for GeanyPlugin::info already and easier than inspecting
      the API version.
      babf0083
    • Thomas Martitz's avatar
      plugins: plugin loader redesign · 721009e2
      Thomas Martitz yazdı
      The old plugin loader has a number of deficiencies:
      
      - plugins need to export a couple of callback functions into the global namespace
      - plugins need to export data pointers, that are written by Geany
      - the exported functions have no user_data param, so there is no way to
        pass context/state back to the plugin (it needs global storage for that)
      - plugin registration is implicit, plugins have no way to not register themselves
        (it may want that due to missing runtime dependencies)
      - plugins perform the ABI/API verification, and even though we provide a
        convinience wrapper, it may get that wrong
      
      As a result, I designed a new loader with the following design principles
      - semantics of callbacks should not change, but they they shouldn't be mess
        with the global namespace
      - each callback receives a self-identifying param (the GeanyPlugin instance) and
        a plugin-defined data pointer for their own use
      - explicit registration through a new API function
      - in-core API/ABI checks
      
      The following principles shall be left unchanged:
      - The scan is done on startup and when the PM dialog is opened
      - Geany allocates GeanyPluginPrivate for each plugin, and GeanyPlugin is
        a member of it
      - Geany initially probes for the validity of the plugin, including file type
        and API/ABI check, thus Geany has the last word in determining what a
        plugin is
      - the PM dialog is updated with the proper, translated plugin information
      - the PM dialog GUI and user interaction in general is unchanged
      
      With the redesign, plugins export a single function: geany_load_module().
      This is called when the GModule is loaded. The main purpose of this function
      is to call geany_plugin_register() (new API function) to register the plugin.
      This is the only function that is learned about through g_module_symbol().
      Within this call the plugin should
      a) set the localized info fields of GeanyPlugin::info
      b) pass compiled-against and minimum API version as well as compiled-against
         ABI version, to allow Geany to verify compatibility
      c) pass a pointer to an instance of GeanyPluginFuncs
         which holds pointers to enhanced versions of the known callbacks (except
         configure_single which is dropped).
      d) optionally pass a plugin-private data pointer for later callbacks
      
      Enhanced means that all callbacks receive the GeanyPlugin pointer as the first
      and a pdata pointer as the last. pdata is private to the plugin and is set
      by geany_plugin_register().
      
      The callbacks need (should) not be globally defined anymore, and the global
      GeanyData, GeanyPlugin and GeanyFunctions pointers are ignored and not set
      anymore. GeanyData is available through GeanyPlugin::geany_data.
      721009e2
  5. 22 Agu, 2015 3 kayıt (commit)
  6. 21 Agu, 2015 1 kayıt (commit)
  7. 16 Agu, 2015 5 kayıt (commit)
  8. 06 Agu, 2015 1 kayıt (commit)
  9. 05 Agu, 2015 2 kayıt (commit)
  10. 04 Agu, 2015 1 kayıt (commit)
  11. 31 Tem, 2015 1 kayıt (commit)
  12. 22 Tem, 2015 4 kayıt (commit)
  13. 21 Tem, 2015 1 kayıt (commit)