Re: Send a message using Gio::Dbus




Hello everybody out there!

        Well, I may have found a way. Here is what I have done, it work on my
computer, I would be glad if somebody can confirm it is a good way.

        I have created the following enumeration:

enum ConnectionType {FREEDESKTOP, GNOME};

        And the following field in the class:

ConnectionType connectionType;

        Here is how I initialize the proxy in constructor:

proxy =
  Gio::DBus::Proxy::create_for_bus_sync(Gio::DBus::BUS_TYPE_SESSION,
                                  "org.freedesktop.PowerManagement",
                                  "org/freedesktop/PowerManagement",
                                 "org.freedesktop.PowerManagement");
if (!proxy) {
  connectionType = FREEDESKTOP;
}
else {
  std::ostringstream message;
  message << "No Feedesktop type D-Bus connection available, "
          << "trying Gnome type.\n";
  g_message(message.str().c_str());

  proxy =
    Gio::DBus::Proxy::create_for_bus_sync(Gio::DBus::BUS_TYPE_SESSION,
                                          "org.gnome.SessionManager",
                                          "/org/gnome/SessionManager",
                                          "org.gnome.SessionManager");
  connectionType = GNOME;
}

        Then, here is my inhibiting procedure:

void Interface::Window::inhibitScreenSaver () {
  /* Name of the application sending the message. */
  const Glib::Variant<Glib::ustring> app_name =
    Glib::Variant<Glib::ustring>::create("Tutorial4");
  /* Reason for sending message. */
  const Glib::Variant<Glib::ustring> reason =
    Glib::Variant<Glib::ustring>::create("Full-screen animation");
  /* Vector containing the message. */
  std::vector<Glib::VariantBase> vec;
  /* Bundling the message. */
  Glib::VariantContainerBase bundle;

  switch (connectionType) {
    case FREEDESKTOP:
      vec.push_back(app_name);
      vec.push_back(reason);
      bundle = Glib::VariantContainerBase::create_tuple(vec);
      result = proxy->call_sync("Inhibit", bundle);
      break;
    case GNOME:
      /* Window identifier. */
      const Glib::Variant<guint> toplevel_xid =
     Glib::Variant<guint>::create(GDK_WINDOW_XID(get_window()->gobj()));
      /* Action flag. */
      const Glib::Variant<guint> flag =
        Glib::Variant<guint>::create(4 | 8);
      vec.push_back(app_name);
      vec.push_back(toplevel_xid);
      vec.push_back(reason);
      vec.push_back(flag);
      bundle = Glib::VariantContainerBase::create_tuple(vec);
      result = proxy->call_sync("Inhibit", bundle);
  }
}

        And uninhibiting procedure:

void Interface::Window::uninhibitScreenSaver () {
  switch (connectionType) {
    case FREEDESKTOP:
      proxy->call_sync("UnInhibit", result);
      break;
    case GNOME:
      proxy->call_sync("Uninhibit", result);
  }
}

        On my computer, which runs Gnome 3, the screen does not turn black
while in full-screen, which is what is expected. I also get the
following messages:


(tutoriel4:6042): GLib-GIO-CRITICAL **:
g_dbus_connection_signal_subscribe: assertion `object_path == NULL ||
g_variant_is_object_path (object_path)' failed

(tutoriel4:6042): GLib-GIO-CRITICAL **:
g_dbus_connection_signal_subscribe: assertion `object_path == NULL ||
g_variant_is_object_path (object_path)' failed
** Message: No Feedesktop type D-Bus connection available, trying Gnome
type.

        Of course, as the code first attempt to connect to
"org.freedesktop.PowerManagement", fails, and then connect to
"org.gnome.SessionManager".

        So far, according to my tests, it works. But is there something I have
forgotten? Is there a better way to achieve this?

        Regards.

                                                        Yoann


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]