Recent

Author Topic: How to use Unity Launcher API?  (Read 4271 times)

Keeper-Volok

  • Newbie
  • Posts: 3
How to use Unity Launcher API?
« on: May 24, 2017, 10:25:10 pm »
I want progressbar on icon of application in Unity launchpanel.

I have found an DBus API of Unity, but I don't understand how to use him.

Launch-file "mainform.desktop" is created in /usr/share/application

On the basis of an simple DBus example and extended example I have tried such decision:
Code: Pascal  [Select]
  1. unit mainunit;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  9.   ctypes, dbus   // sudo apt-get install libdbus-1-dev
  10.   ;
  11.  
  12. type
  13.  
  14.   { TMainForm }
  15.  
  16.   TMainForm = class(TForm)
  17.     Button1: TButton;
  18.     procedure Button1Click(Sender: TObject);
  19.   private
  20.     { private declarations }
  21.     procedure BusSend(sigvalue: PChar);
  22.   public
  23.     { public declarations }
  24.   end;
  25.  
  26. var
  27.   MainForm: TMainForm;
  28.   err: DBusError;
  29.   conn: PDBusConnection;
  30.   ret: cint;
  31.  
  32. implementation
  33.  
  34. {$R *.lfm}
  35.  
  36. { TMainForm }
  37.  
  38. procedure TMainForm.Button1Click(Sender: TObject);
  39. begin
  40.   //  signal com.canonical.Unity.LauncherEntry.Update (in s app_uri, in a{sv} properties)
  41.  
  42.   BusSend(PChar('"application://mainform.desktop", "{' + #39 + 'progress-visible' + #39 + ': <true>, ' + #39 + 'progress' + #39 + ': <0.5>}"'));
  43.   // "application://mainform.desktop" "{'progress-visible': <true>, 'progress': <0.5>}"
  44. end;
  45.  
  46. procedure TMainForm.BusSend(sigvalue: PChar);
  47. var
  48.   msg: PDBusMessage;
  49.   args: DBusMessageIter;
  50.   serial: dbus_uint32_t = 0;
  51. begin
  52.   dbus_error_init(@err);
  53.  
  54.   { Connection }
  55.   conn := dbus_bus_get(DBUS_BUS_SESSION, @err);
  56.  
  57.   if dbus_error_is_set(@err) <> 0 then
  58.   begin
  59.     ShowMessage('Connection Error: ' + err.message);
  60.     dbus_error_free(@err);
  61.   end;
  62.  
  63.   if conn = nil then
  64.   begin
  65.     ShowMessage('conn = nil');
  66.     Exit;
  67.   end;
  68.  
  69.   ShowMessage('Sending signal with value ' + string(sigvalue));
  70.  
  71.   { Request the name of the bus }
  72.  
  73.   ret := dbus_bus_request_name(conn, 'com.canonical.Unity.LauncherEntry', DBUS_NAME_FLAG_REPLACE_EXISTING, @err);
  74.  
  75.   if dbus_error_is_set(@err) <> 0 then
  76.   begin
  77.     ShowMessage('Name Error: ' + err.message);
  78.     dbus_error_free(@err);
  79.   end;
  80.  
  81.   if ret <> DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER then
  82.   begin
  83.     ShowMessage('NOT DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER');
  84.     Exit;
  85.   end;
  86.  
  87.   // create a signal & check for errors
  88.   msg := dbus_message_new_signal('/', // object name of the signal
  89.                                  'com.canonical.Unity.LauncherEntry', // interface name of the signal
  90.                                  'Update'); // name of the signal
  91.   if (msg = nil) then
  92.   begin
  93.     ShowMessage('Message Null');
  94.     Exit;
  95.   end;
  96.  
  97.   // append arguments onto signal
  98.   dbus_message_iter_init_append(msg, @args);
  99.   if (dbus_message_iter_append_basic(@args, DBUS_TYPE_STRING, @sigvalue) = 0) then
  100.   begin
  101.     ShowMessage('Out Of Memory, iter append basic!');
  102.     Exit;
  103.   end;
  104.  
  105.   // send the message and flush the connection
  106.   if (dbus_connection_send(conn, msg, @serial) = 0) then
  107.   begin
  108.     ShowMessage('Out Of Memory, connection send!');
  109.     Exit;
  110.   end;
  111.  
  112.   dbus_connection_flush(conn);
  113.  
  114.   ShowMessage('Signal Sent');
  115.  
  116.   // free the message and close the connection
  117.   dbus_message_unref(msg);
  118. end;
  119.  
  120. end.

There are no mistakes, but also there is no result.
Also I have found Qt/C++ example, but there all on another.

Forgive for bad English, Google-Translate.

Phil

  • Hero Member
  • *****
  • Posts: 2750

Keeper-Volok

  • Newbie
  • Posts: 3
Re: How to use Unity Launcher API?
« Reply #2 on: May 24, 2017, 10:44:06 pm »
Note that Unity is dead.
Yes, but for example KDE Plasma supports Unity API
But I test on Unity, Ubuntu 16.04 LTS (x64)
« Last Edit: May 24, 2017, 10:48:24 pm by Keeper-Volok »

eny

  • Hero Member
  • *****
  • Posts: 1588
All posts based on: Win10 (Win64); Lazarus 1.8.0 'stable' (#56594 win64) unless specified otherwise...

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 7643
Re: How to use Unity Launcher API?
« Reply #4 on: May 25, 2017, 03:06:15 pm »
To my knowledge the FPC dbus header was an one of donation, and not maintained.

varianus

  • New Member
  • *
  • Posts: 17
Re: How to use Unity Launcher API?
« Reply #5 on: May 25, 2017, 04:24:01 pm »
FPC DBUS implementation is working fine, but is very low-level and need a lot of work to implement something.

The signature for the signal is
Code: [Select]
signal com.canonical.Unity.LauncherEntry.Update (in s app_uri, in a{sv} properties)
So the DBUS receiver is expecting a string and a variant array, but you are sending only a string.

So the code should be something like the one below. Please note that is a quick adaptation of an old code, it's absolutely not tested.

Code: Pascal  [Select]
  1.   ...
  2.   var
  3.   // define some temporary variable
  4.     b_val: dword;
  5.     d_Val: double;
  6.     sub1, sub2, sub3, sub4: DBusMessageIter;
  7.     Property_: PChar;
  8.  ...
  9.  ...  
  10.  
  11.    dbus_message_iter_init_append(msg, @args);
  12.    property_:='application://mainform.desktop';
  13.    dbus_message_iter_append_basic(@args, DBUS_TYPE_STRING, property_);    
  14.  
  15.    dbus_message_iter_open_container(@args, DBUS_TYPE_ARRAY, '{sv}', @sub1);
  16.    dbus_message_iter_open_container(@sub1, DBUS_TYPE_DICT_ENTRY, nil, @sub2);
  17.    property_ := 'progress-visible';
  18.    b_val := 1; // 1 - true, 0 - false
  19.    dbus_message_iter_append_basic(@sub2, DBUS_TYPE_STRING, @property_);
  20.    dbus_message_iter_open_container(@sub2, DBUS_TYPE_VARIANT, 'b', @sub3);
  21.    dbus_message_iter_append_basic(@sub3, DBUS_TYPE_BOOLEAN, @b_val);
  22.    dbus_message_iter_close_container(@sub2, @sub3);
  23.    dbus_message_iter_close_container(@sub1, @sub2);
  24.  
  25.    dbus_message_iter_open_container(@sub1, DBUS_TYPE_DICT_ENTRY, nil, @sub2);
  26.    property_ := 'progress';
  27.    d_val := 0.5;
  28.    dbus_message_iter_append_basic(@sub2, DBUS_TYPE_STRING, @property_);
  29.    dbus_message_iter_open_container(@sub2, DBUS_TYPE_VARIANT, 'd', @sub3);
  30.    dbus_message_iter_append_basic(@sub3, DBUS_TYPE_DOUBLE, @d_val);
  31.    dbus_message_iter_close_container(@sub2, @sub3);
  32.    dbus_message_iter_close_container(@sub1, @sub2);
  33.    dbus_message_iter_close_container(@args, @sub1);
  34.  
  35.   // send the message and flush the connection
  36.    if (dbus_connection_send(conn, msg, @serial) = 0) then
  37.    begin
  38.      ShowMessage('Out Of Memory, connection send!');
  39.      Exit;
  40.    end;
  41.  


Keeper-Volok

  • Newbie
  • Posts: 3
Re: How to use Unity Launcher API?
« Reply #6 on: May 25, 2017, 08:24:01 pm »
varianus, thank you very much for your response.
I understood the main idea.

But so far it has not turned out, this container scheme causes an segfault in "strlen" from glib.