Open sebastinas opened 4 years ago
zathura is already capable of sending/receiving messages to/from other processs via dbus. The interface could be extended to receive more commands. Check out how this is currently done in zathura/dbus-interface.c.
On GitLab by @jcguu95 on Aug 31, 2020, 02:06
Thank you so much @sebastinas for reaching out! I'm not familiar with dbus
but will take this chance to learn. Would you please provide a few simple usage examples? For example, how would I scroll down an opened document from terminal?
It's not that simple. You'd start at https://git.pwmt.org/pwmt/zathura/-/blob/develop/data/org.pwmt.zathura.xml and define a new method handling arbitrary commands. In https://git.pwmt.org/pwmt/zathura/-/blob/develop/zathura/dbus-interface.c, handle_method_call
, one would then need to handle the new method and execute the command.
On GitLab by @jcguu95 on Aug 31, 2020, 14:16
@sebastinas thanks so much for your quick reply! I can see potentials here, and am so excited. I'm not familiar with dbus
so this might be a dumb question:
This example aims to quickly involve people who don't know dbus
to get started with it. In zathura.xml
and dbus-interface.c
it seems that a method GotoPage
has been implemented
# in zathura.xml
<method name='GotoPage'>
<arg type='u' name='page' direction='in' />
<arg type='b' name='return' direction='out' />
</method>
# in dbus-interface.c
{ "GotoPage", handle_goto_page, true, true },
So, how can one launch this method from external terminal?
dbus-send --type="method_call" --dest=org.pwmt.zathura.PID-$pid /org/pwmt/zathura org.pwmt.zathura.GotoPage uint32:$page
where $pid
is the PID of the process which should execute the action.
Alternatively you can also look at zathura's main.c
and follow the synctex code path to see how this can be done with the dbus API. That code path also first searches for $pid
based on the all running zathura process and their opened documents.
On GitLab by @jcguu95 on Aug 31, 2020, 22:00
Bad news.. just realized that zathura
did not compile correctly for me.. so I'm not able to test the method I wrote. It could take a while before I start making contrib, if you feel worth it and keep helping I'd appreciate it!
ScrollDown
Just as an exercise, I tried to build a dbus method ScrollDown
.
In dbus-interface.c
I added
{ "ScrollDown", handle_scrolldown, true, true },
to handlers[]
, and added the function handle_scrolldown
static void
handle_scrolldown(zathura_t* zathura, GVariant* parameters,
GDBusMethodInvocation* invocation)
{
const unsigned int number_of_pages = zathura_document_get_number_of_pages(zathura->document);
// guint page = 0;
// g_variant_get(parameters, "(u)", &page);
guint session = session; // TODO ?
guint argument = DOWN;
guint event = NULL; // TODO ?
guint t = 1; // number of execution
// g_variant_get(parameters, "u", &argument);
bool ret = true;
sc_scroll(session,argument,event,t); // TODO
GVariant* result = g_variant_new("(b)", ret);
g_dbus_method_invocation_return_value(invocation, result);
}
I'm not sure that the initial value of session
and event
is set right. I traced through the function sc_scroll
. It seems that session
is generated in girara
already.. I don't know how to pass that session here while calling dbus
. Similar situation holds for event
.
(By the way, I did add the necessary in xml
<!-- Scroll down. -->
<method name='ScrollDown'>
<arg type='u' name='argument' direction='in' />
<arg type='b' name='return' direction='out' />
</method>
I followed compilation guide
meson build
cd build
ninja
It generates a binary zathura
in build
, but an attempt to read file by it gives an error
./zathura book.pdf
error: could not open plugin directory: /usr/local/lib/zathura
error: Unable to initialize database. Bookmarks won't be available.
error: Could not determine file type.
Make sure to build with the same prefix or specify the plugin dir when running zathura (e.g., zathura -p /usr/lib/zathura
).
On GitLab by @jcguu95 on Sep 1, 2020, 01:33
Ok, I solved the compilation problem. Now for the code, a new method ScrollDown
is what I aim for:
static const struct {
const char* method;
void (*handler)(zathura_t*, GVariant*, GDBusMethodInvocation*);
bool needs_document;
bool present_window;
} handlers[] = {
{ "OpenDocument", handle_open_document, false, true },
{ "CloseDocument", handle_close_document, false, false },
{ "GotoPage", handle_goto_page, true, true },
{ "ScrollDown", handle_scrolldown, true, true }, // <----- this is new
{ "HighlightRects", handle_highlight_rects, true, true },
{ "SynctexView", handle_synctex_view, true, true }
};
However, to do that I invoke the function sc_scroll(session,argument,event,t)
in the body of the handlers[]
: "ScrollDown"..
. The function sc_scroll
calls input
girara_session_t* session,
girara_argument_t* argument,
girara_event_t* event
where session
and event
seem to be generated somewhere else by girara
. It seems that fetching them externally requires another handler.. could you confirm this?
You can access the girara session via zathura->ui.session
. argument
needs to be populated depending on how you want to scroll. See sc_scroll
for possible cases (and also check config.c
). event
is only used for bidrectional scrolling, so that only needs to be populated if you want to support that too.
On GitLab by @jcguu95 on Sep 1, 2020, 13:49
Yay.. after 6 hours I finally got it working. Here's the code
static void
handle_scroll(zathura_t* zathura, GVariant* parameters,
GDBusMethodInvocation* invocation)
{
/*
Usage:
#+begin_src shell
dbus-send --type="method_call" --print-reply \
--dest=org.pwmt.zathura.PID-${pid} \
/org/pwmt/zathura org.pwmt.zathura.Scroll int32:${n}
#+end_src
n = 2 ... LEFT
n = 3 ... RIGHT
n = 4 ... UP
n = 5 ... DOWN
n = 6 ... BOTTOM
n = 7 ... TOP
More to be found in the block `enum..` in `zathura.h`.
*/
girara_session_t* session = zathura->ui.session ;
girara_argument_t argument ;
girara_event_t* event = NULL ;
unsigned int t = 1 ; // number of execution
g_variant_get(parameters, "(i)", &(argument.n));
argument.data = NULL;
bool ret = true;
sc_scroll(session,&argument,event,t);
GVariant* result = g_variant_new("(b)", ret);
g_dbus_method_invocation_return_value(invocation, result);
}
Do you find it useful (should I PR)? Or you want other methods to be implemented?
Yes, I think this would be useful in general. But it'd be interesting to handle more than just scroll.
On GitLab by @jcguu95 on Sep 4, 2020, 24:14
I think so! Do you have some interesting methods in mind?
I'm thinking of
Such functionalities will be enough for taking quick notes and annotations externally. If it's not too taxing for you, could you point out the difficulties of these, and perhaps some useful functions to look at :) Thank you!
Are you still interested in turning this into a MR?
On GitLab by @rmorales on Sep 21, 2023, 20:46
@jcguu95 @sebastinas In merge request !84, I've introduced a Dbus handler that can call any shortcut function. I believe this solution is more generic as it make it possible to call sc_scroll
and all other shortcut functions. Please consider take a look at the merge request.
On GitLab by @jcguu95 on Aug 26, 2020, 19:25
Hoping for
I have a simple implementation of annotation (..etc) in mind, but I need a way to control
zathura
externally. For example, I hope the following scrolls the documentwhere,
sc_scroll
is the built-in function that scrolls the document.Question
How to send commands to zathura externally?
As a quick note,
sc_scroll
callsposition_set
at the end of itself.sc_scroll
then callsrefresh_view(zathura)
in its end. Thenrefresh_view
callswhich finally communicates with an external packages.