File libgxdp-0.gitmodule.obscpio of Package xdg-desktop-portal-gnome

07070100000000000041ED00000000000000000000000267B22C4900000000000000000000000000000000000000000000001F00000000libgxdp-0.gitmodule/.gitlab-ci07070100000001000081A400000000000000000000000167B22C4900000FEA000000000000000000000000000000000000002300000000libgxdp-0.gitmodule/.gitlab-ci.ymlinclude:
  - remote: 'https://gitlab.freedesktop.org/freedesktop/ci-templates/-/raw/145b1bc7ef1702d2bd71584010d7113c6786a506/templates/fedora.yml'
  - remote: 'https://gitlab.freedesktop.org/freedesktop/ci-templates/-/raw/34f4ade99434043f88e164933f570301fd18b125/templates/ci-fairy.yml'

stages:
 - review
 - prepare
 - build
 - test

variables:
  FDO_UPSTREAM_REPO: GNOME/libgxp

default:
  interruptible: true

workflow:
  rules:
    # Allow to switch from branch pipelines to MR pipelines seamlessly
    # https://docs.gitlab.com/ee/ci/jobs/job_control.html#avoid-duplicate-pipelines
    - if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS && $CI_PIPELINE_SOURCE == "push"
      when: never
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
    # Don't trigger a branch pipeline if there is an open MR
    - if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS
      when: never
    - if: '$CI_COMMIT_BRANCH'
    - if: '$CI_COMMIT_TAG'

.skip-git-clone:
  variables:
    GIT_STRATEGY: none

.only-merge-requests:
  rules:
    - if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME =~ /^$/'
      when: never
    - if: $CI_MERGE_REQUEST_TARGET_BRANCH_NAME
      when: on_success

.pipeline-guard:
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
    - if: '$CI_COMMIT_TAG'
    - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
    - if: '$CI_COMMIT_BRANCH =~ /^gnome-[0-9-]+$/'
    # Avoid catchall `when: manual` rule which might
    # cause duplicate pipelines to be triggered.
    # https://docs.gitlab.com/ee/ci/jobs/job_control.html#avoid-duplicate-pipelines
    #
    # Also make it so pipelines without MR need to be started
    # manually, since their state will most likely be WIP
    - if: '$CI_COMMIT_BRANCH'
      when: 'manual'

repo-sanity:
  extends:
    - .fdo.ci-fairy
  stage: review
  variables:
    GIT_DEPTH: "1"
  script:
    - >
      if [[ -z "$CI_REGISTRY_IMAGE" ]] ;
      then
        .gitlab-ci/simple-junit-report.sh check-junit-report.xml \
          repo-sanity "The container registry should be enabled in the project general settings panel at $CI_PROJECT_URL/edit" ;
        exit 1 ;
      fi
  artifacts:
    expire_in: 1 week
    paths:
      - check-junit-report.xml
    reports:
      junit: check-junit-report.xml
  rules:
    - !reference [.only-merge-requests, rules]

check-merge-request:
  extends:
    - .fdo.ci-fairy
    - .skip-git-clone
  stage: review
  script:
    ci-fairy check-merge-request --require-allow-collaboration --junit-xml=check-merge-request-report.xml
  artifacts:
    expire_in: 1 week
    paths:
      - check-merge-request-report.xml
    reports:
      junit: check-merge-request-report.xml
  rules:
    - !reference [.only-merge-requests, rules]

.container-setup:
  variables:
    FDO_DISTRIBUTION_TAG: '2024-11-24.0'
    FDO_DISTRIBUTION_VERSION: 41
    FDO_DISTRIBUTION_PACKAGES:
      util-linux
      git
      dbus-daemon
      mutter
      xorg-x11-server-Xwayland
    FDO_DISTRIBUTION_EXEC: |
      dnf install -y 'dnf-command(builddep)'
      dnf builddep gtk4 -y

      ./.gitlab-ci/install-meson-project.sh \
        https://gitlab.gnome.org/GNOME/gtk.git \
        main . bccd0aa079eae54d2958032d8e5b008650b91ad7

prepare:
  extends:
    - .fdo.container-build@fedora
    - .container-setup
    - .skip-git-clone
  stage: prepare
  rules:
    - !reference [.pipeline-guard, rules]

build:
  extends:
    - .fdo.distribution-image@fedora
    - .container-setup
  stage: build
  script:
    - meson setup build .
    - meson compile -C build
  needs:
    - job: prepare
      artifacts: false
  artifacts:
    expire_in: 1 day
    paths:
      - build

test:
  extends:
    - .fdo.distribution-image@fedora
    - .container-setup
  stage: test
  variables:
    XDG_SESSION_TYPE: wayland
  script:
    - mkdir -m 1777 /tmp/.X11-unix
    - env XDG_RUNTIME_DIR=$(mktemp -d --tmpdir gxdp-runtime-XXXXXX)
        meson test
          -C build
          --no-rebuild
          --print-errorlogs
  needs:
    - job: build
  artifacts:
    reports:
      junit: "build/meson-logs/testlog.junit.xml"
07070100000002000081ED00000000000000000000000167B22C49000006A9000000000000000000000000000000000000003800000000libgxdp-0.gitmodule/.gitlab-ci/install-meson-project.sh#!/bin/bash

set -e

usage() {
  cat <<-EOF
	Usage: $(basename $0) [OPTION…] REPO_URL COMMIT

	Check out and install a meson project

	Options:
	  -Dkey=val          Option to pass on to meson
	  --subdir=DIR       Build subdirectory instead of whole project
	  --prepare=SCRIPT   Script to run before build
	  --libdir=DIR       Setup the project with a different libdir
	  --destdir=DIR      Install the project to an additional destdir

	  -h, --help         Display this help

	EOF
}

TEMP=$(getopt \
  --name=$(basename $0) \
  --options='D:h' \
  --longoptions='subdir:' \
  --longoptions='prepare:' \
  --longoptions='libdir:' \
  --longoptions='destdir:' \
  --longoptions='help' \
  -- "$@")

eval set -- "$TEMP"
unset TEMP

MESON_OPTIONS=()
SUBDIR=.
PREPARE=:
DESTDIR=""

while true; do
  case "$1" in
    -D)
      MESON_OPTIONS+=( -D$2 )
      shift 2
    ;;

    --subdir)
      SUBDIR=$2
      shift 2
    ;;

    --prepare)
      PREPARE=$2
      shift 2
    ;;

    --libdir)
      MESON_OPTIONS+=( --libdir=$2 )
      shift 2
    ;;

    --destdir)
      DESTDIR=$2
      shift 2
    ;;

    -h|--help)
      usage
      exit 0
    ;;

    --)
      shift
      break
    ;;
  esac
done

if [[ $# -lt 2 ]]; then
  usage
  exit 1
fi

REPO_URL="$1"
COMMIT="$2"

CHECKOUT_DIR=$(mktemp --directory)
trap "rm -rf $CHECKOUT_DIR" EXIT

git clone --depth 1 "$REPO_URL" -b "$COMMIT" "$CHECKOUT_DIR"

pushd "$CHECKOUT_DIR/$SUBDIR"
sh -c "$PREPARE"
meson setup --prefix=/usr _build "${MESON_OPTIONS[@]}"

# Install it to an additional directory e.g., system extension directory
if [ -n "${DESTDIR}" ]; then
    sudo meson install -C _build --destdir=$DESTDIR
fi

sudo meson install -C _build
popd
07070100000003000081A400000000000000000000000167B22C49000000FB000000000000000000000000000000000000001E00000000libgxdp-0.gitmodule/README.md# libgxdp

Libgxdp is a **lib**rary for **G**NOME **X**DG **D**esktop **P**ortal. It
provides functionality needed by GNOME portal backends, such as cross windowing
system dialog stacking functionality. It's intended to be used as a meson
subproject.
07070100000004000041ED00000000000000000000000267B22C4900000000000000000000000000000000000000000000001900000000libgxdp-0.gitmodule/data07070100000005000081A400000000000000000000000167B22C490000026C000000000000000000000000000000000000003000000000libgxdp-0.gitmodule/data/mutter-x11-interop.xml<?xml version="1.0" encoding="UTF-8"?>
<protocol name="mutter_x11_interop">
  <description summary="X11 interoperability helper">
    This protocol is intended to be used by the portal backend to map Wayland
    dialogs as modal dialogs on top of X11 windows.
  </description>

  <interface name="mutter_x11_interop" version="1">
    <description summary="X11 interoperability helper"/>

    <request name="destroy" type="destructor"/>

    <request name="set_x11_parent">
      <arg name="surface" type="object" interface="wl_surface"/>
      <arg name="xwindow" type="uint"/>
    </request>
  </interface>
</protocol>
07070100000006000081A400000000000000000000000167B22C4900000220000000000000000000000000000000000000003D00000000libgxdp-0.gitmodule/data/org.gnome.Mutter.ServiceChannel.xml<!DOCTYPE node PUBLIC
'-//freedesktop//DTD D-BUS Object Introspection 1.0//EN'
'http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd'>
<node>

  <interface name="org.gnome.Mutter.ServiceChannel">

    <!--
        ServiceClientTypes:
           PORTAL_BACKEND: 1
    -->
    <method name="OpenWaylandServiceConnection">
      <arg name="service_client_type" type="u" direction="in" />
      <annotation name="org.gtk.GDBus.C.UnixFD" value="true"/>
      <arg name="fd" type="h" direction="out" />
    </method>

  </interface>

</node>
07070100000007000081A400000000000000000000000167B22C4900000564000000000000000000000000000000000000002100000000libgxdp-0.gitmodule/libgxdp.doap<Project xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
         xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
         xmlns:foaf="http://xmlns.com/foaf/0.1/"
         xmlns:gnome="http://api.gnome.org/doap-extensions#"
         xmlns="http://usefulinc.com/ns/doap#">

  <name xml:lang="en">libgxdp</name>
  <description xml:lang="en">GNOME Desktop Portal helper library</description>
  <shortdesc xml:lang="en">
    Library for GNOME XDG Desktop Portal backend utilities.
  </shortdesc>
  <!--
  <homepage rdf:resource="http://www.gnome.org/" />
  -->
  <developer-forum rdf:resource="https://discourse.gnome.org/c/platform/" />
  <download-page rdf:resource="https://download.gnome.org/sources/libgxdp/" />
  <bug-database rdf:resource="https://gitlab.gnome.org/GNOME/libgxdp/issues/" />

  <category rdf:resource="http://api.gnome.org/doap-extensions#core" />
  <programming-language>C</programming-language>

  <maintainer>
    <foaf:Person>
      <foaf:name>Jonas Ådahl</foaf:name>
      <foaf:mbox rdf:resource="mailto:jadahl@gmail.com" />
      <gnome:userid>jadahl</gnome:userid>
    </foaf:Person>
  </maintainer>
  <maintainer>
    <foaf:Person>
      <foaf:name>Georges Basile Stavracas Neto</foaf:name>
      <foaf:mbox rdf:resource="mailto:gbsneto@gnome.org" />
      <gnome:userid>gbsneto</gnome:userid>
    </foaf:Person>
  </maintainer>
</Project>
07070100000008000081A400000000000000000000000167B22C49000000DB000000000000000000000000000000000000002000000000libgxdp-0.gitmodule/meson.buildproject(
  'libgxdp',
  'c',
  version: '48.alpha',
  meson_version: '>= 1.1',
  license: 'LGPLv2.1+'
)

gtk_dep = dependency('gtk4', version: '>= 4.17.1')

subdir('src')

if get_option('tests')
  subdir('tests')
endif
07070100000009000081A400000000000000000000000167B22C4900000052000000000000000000000000000000000000002200000000libgxdp-0.gitmodule/meson.optionsoption('tests',
  type: 'boolean',
  value: true,
  description: 'Enable tests'
)
0707010000000A000041ED00000000000000000000000267B22C4900000000000000000000000000000000000000000000001800000000libgxdp-0.gitmodule/src0707010000000B000081A400000000000000000000000167B22C4900000042000000000000000000000000000000000000002C00000000libgxdp-0.gitmodule/src/gxdp-config.h.meson#mesondefine GXDP_HAVE_GTK_WAYLAND
#mesondefine GXDP_HAVE_GTK_X11
0707010000000C000081A400000000000000000000000167B22C49000016A8000000000000000000000000000000000000003700000000libgxdp-0.gitmodule/src/gxdp-external-window-wayland.c/*
 * Copyright © 2016 Red Hat, Inc
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Jonas Ådahl <jadahl@redhat.com>
 */

#include "gxdp-config.h"

#include "gxdp-external-window-wayland.h"

#include <gdk/gdk.h>
#include <gdk/wayland/gdkwayland.h>
#include <wayland-client.h>

#include "gxdp-wayland.h"

#define WAYLAND_HANDLE_PREFIX "wayland:"
#define X11_HANDLE_PREFIX "x11:"

typedef enum _ParentWindowType
{
  PARENT_WINDOW_TYPE_WAYLAND,
  PARENT_WINDOW_TYPE_X11,
} ParentWindowType;

struct _GxdpExternalWindowWayland
{
  GxdpExternalWindow parent;

  ParentWindowType parent_type;
  struct {
    char *xdg_foreign_handle;
  } wayland;
  struct {
    int xid;
    gulong mapped_handler_id;
  } x11;

  GdkSurface *dialog_surface;
};

struct _GxdpExternalWindowWaylandClass
{
  GxdpExternalWindowClass parent_class;
};

G_DEFINE_TYPE (GxdpExternalWindowWayland, gxdp_external_window_wayland,
               GXDP_TYPE_EXTERNAL_WINDOW)

GxdpExternalWindowWayland *
gxdp_external_window_wayland_new (const char *handle_str)
{
  g_autoptr(GxdpExternalWindowWayland) external_window_wayland = NULL;

  external_window_wayland = g_object_new (GXDP_TYPE_EXTERNAL_WINDOW_WAYLAND,
                                          NULL);

  if (g_str_has_prefix (handle_str, WAYLAND_HANDLE_PREFIX))
    {
      external_window_wayland->parent_type = PARENT_WINDOW_TYPE_WAYLAND;
      external_window_wayland->wayland.xdg_foreign_handle =
        g_strdup (handle_str + strlen (WAYLAND_HANDLE_PREFIX));
    }
  else if (g_str_has_prefix (handle_str, X11_HANDLE_PREFIX))
    {
      const char *x11_handle_str = handle_str + strlen (X11_HANDLE_PREFIX);
      int xid;

      errno = 0;
      xid = strtol (x11_handle_str, NULL, 16);
      if (errno != 0)
        {
          g_warning ("Failed to reference external X11 window, invalid XID %s",
                     x11_handle_str);
          return NULL;
        }

      external_window_wayland->parent_type = PARENT_WINDOW_TYPE_X11;
      external_window_wayland->x11.xid = xid;
    }
  else
    {
      g_warning ("Invalid external window handle string '%s'", handle_str);
      return NULL;
    }

  return g_steal_pointer (&external_window_wayland);
}

static void
set_x11_parent (GxdpExternalWindow *external_window)
{
  GxdpExternalWindowWayland *external_window_wayland =
    GXDP_EXTERNAL_WINDOW_WAYLAND (external_window);

  gxdp_wayland_set_x11_parent (external_window_wayland->dialog_surface,
                               external_window_wayland->x11.xid);
}

static void
on_mapped (GdkSurface         *surface,
           GParamSpec         *pspec,
           GxdpExternalWindow *external_window)
{
  if (!gdk_surface_get_mapped (surface))
    return;

  set_x11_parent (external_window);
}

static void
gxdp_external_window_wayland_set_parent_of (GxdpExternalWindow *external_window,
                                            GdkSurface         *surface)
{
  GxdpExternalWindowWayland *external_window_wayland =
    GXDP_EXTERNAL_WINDOW_WAYLAND (external_window);

  g_clear_signal_handler (&external_window_wayland->x11.mapped_handler_id,
                          external_window_wayland->dialog_surface);
  g_clear_object (&external_window_wayland->dialog_surface);

  switch (external_window_wayland->parent_type)
    {
    case PARENT_WINDOW_TYPE_WAYLAND:
      {
        GdkToplevel *toplevel = GDK_TOPLEVEL (surface);
        const char *handle = external_window_wayland->wayland.xdg_foreign_handle;

        if (!gdk_wayland_toplevel_set_transient_for_exported (toplevel, handle))
          g_warning ("Failed to set portal window transient for external parent");
        break;
      }
    case PARENT_WINDOW_TYPE_X11:
      if (gdk_surface_get_mapped (surface))
        {
          set_x11_parent (external_window);
        }
      else
        {
          external_window_wayland->x11.mapped_handler_id =
            g_signal_connect (surface, "notify::mapped",
                              G_CALLBACK (on_mapped), external_window);
        }
      break;
    }

  g_set_object (&external_window_wayland->dialog_surface, surface);
}

static void
gxdp_external_window_wayland_dispose (GObject *object)
{
  GxdpExternalWindowWayland *external_window_wayland =
    GXDP_EXTERNAL_WINDOW_WAYLAND (object);

  g_clear_pointer (&external_window_wayland->wayland.xdg_foreign_handle,
                   g_free);
  g_clear_signal_handler (&external_window_wayland->x11.mapped_handler_id,
                          external_window_wayland->dialog_surface);
  g_clear_object (&external_window_wayland->dialog_surface);

  G_OBJECT_CLASS (gxdp_external_window_wayland_parent_class)->dispose (object);
}

static void
gxdp_external_window_wayland_init (GxdpExternalWindowWayland *external_window_wayland)
{
}

static void
gxdp_external_window_wayland_class_init (GxdpExternalWindowWaylandClass *klass)
{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
  GxdpExternalWindowClass *external_window_class =
    GXDP_EXTERNAL_WINDOW_CLASS (klass);

  object_class->dispose = gxdp_external_window_wayland_dispose;

  external_window_class->set_parent_of = gxdp_external_window_wayland_set_parent_of;
}
0707010000000D000081A400000000000000000000000167B22C49000004D4000000000000000000000000000000000000003700000000libgxdp-0.gitmodule/src/gxdp-external-window-wayland.h/*
 * Copyright © 2016 Red Hat, Inc
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Jonas Ådahl <jadahl@redhat.com>
 */

#pragma once

#include <glib-object.h>

#include "gxdp-external-window.h"

#define GXDP_TYPE_EXTERNAL_WINDOW_WAYLAND (gxdp_external_window_wayland_get_type ())
G_DECLARE_FINAL_TYPE (GxdpExternalWindowWayland, gxdp_external_window_wayland,
                      GXDP, EXTERNAL_WINDOW_WAYLAND, GxdpExternalWindow)

GxdpExternalWindowWayland *gxdp_external_window_wayland_new (const char *handle_str);

GdkDisplay * init_external_window_wayland_display (GError **error);
0707010000000E000081A400000000000000000000000167B22C4900000D84000000000000000000000000000000000000003300000000libgxdp-0.gitmodule/src/gxdp-external-window-x11.c/*
 * Copyright © 2016 Red Hat, Inc
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Jonas Ådahl <jadahl@redhat.com>
 */

#include "gxdp-config.h"

#include "gxdp-external-window-x11.h"

#include <errno.h>
#include <gdk/x11/gdkx.h>
#include <X11/Xatom.h>
#include <gdk/gdk.h>
#include <stdlib.h>

struct _GxdpExternalWindowX11
{
  GxdpExternalWindow parent;

  Window foreign_xid;
};

struct _GxdpExternalWindowX11Class
{
  GxdpExternalWindowClass parent_class;
};

G_DEFINE_TYPE (GxdpExternalWindowX11, gxdp_external_window_x11,
               GXDP_TYPE_EXTERNAL_WINDOW)

GxdpExternalWindowX11 *
gxdp_external_window_x11_new (const char *handle_str)
{
  GxdpExternalWindowX11 *external_window_x11;
  const char x11_prefix[] = "x11:";
  const char *x11_handle_str;
  int xid;

  if (!g_str_has_prefix (handle_str, x11_prefix))
    {
      g_warning ("Invalid external window handle string '%s'", handle_str);
      return NULL;
    }

  x11_handle_str = handle_str + strlen (x11_prefix);

  errno = 0;
  xid = strtol (x11_handle_str, NULL, 16);
  if (errno != 0)
    {
      g_warning ("Failed to reference external X11 window, invalid XID %s",
                 x11_handle_str);
      return NULL;
    }

  external_window_x11 = g_object_new (GXDP_TYPE_EXTERNAL_WINDOW_X11,
                                      NULL);
  external_window_x11->foreign_xid = xid;

  return external_window_x11;
}

static void
gxdp_external_window_x11_set_parent_of (GxdpExternalWindow *external_window,
                                        GdkSurface         *surface)
{
  GxdpExternalWindowX11 *external_window_x11 =
    GXDP_EXTERNAL_WINDOW_X11 (external_window);
  GdkDisplay *display;
  Display *xdisplay;
  Atom net_wm_window_type_atom;
  Atom net_wm_window_type_dialog_atom;

  display = gdk_display_get_default ();
  xdisplay = gdk_x11_display_get_xdisplay (display);

  XSetTransientForHint (xdisplay,
                        GDK_SURFACE_XID (surface),
                        external_window_x11->foreign_xid);

  net_wm_window_type_atom =
    gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE"),
  net_wm_window_type_dialog_atom =
    gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DIALOG");
  XChangeProperty (xdisplay,
                   GDK_SURFACE_XID (surface),
                   net_wm_window_type_atom,
                   XA_ATOM, 32, PropModeReplace,
                   (guchar *) &net_wm_window_type_dialog_atom, 1);
}

static void
gxdp_external_window_x11_init (GxdpExternalWindowX11 *external_window_x11)
{
}

static void
gxdp_external_window_x11_class_init (GxdpExternalWindowX11Class *klass)
{
  GxdpExternalWindowClass *external_window_class = GXDP_EXTERNAL_WINDOW_CLASS (klass);

  external_window_class->set_parent_of = gxdp_external_window_x11_set_parent_of;
}
0707010000000F000081A400000000000000000000000167B22C49000004B4000000000000000000000000000000000000003300000000libgxdp-0.gitmodule/src/gxdp-external-window-x11.h/*
 * Copyright © 2016 Red Hat, Inc
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Jonas Ådahl <jadahl@redhat.com>
 */

#pragma once

#include <glib-object.h>

#include "gxdp-external-window.h"

#define GXDP_TYPE_EXTERNAL_WINDOW_X11 (gxdp_external_window_x11_get_type ())
G_DECLARE_FINAL_TYPE (GxdpExternalWindowX11, gxdp_external_window_x11,
                      GXDP, EXTERNAL_WINDOW_X11, GxdpExternalWindow)

GxdpExternalWindowX11 *gxdp_external_window_x11_new (const char *handle_str);

GdkDisplay * init_external_window_x11_display (GError **error);
07070100000010000081A400000000000000000000000167B22C4900000985000000000000000000000000000000000000002F00000000libgxdp-0.gitmodule/src/gxdp-external-window.c/*
 * Copyright © 2016 Red Hat, Inc
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Jonas Ådahl <jadahl@redhat.com>
 */

#include "gxdp-config.h"

#include "gxdp-external-window.h"

#include <string.h>

#ifdef GXDP_HAVE_GTK_X11
#include <gdk/x11/gdkx.h>
#include "gxdp-external-window-x11.h"
#endif
#ifdef GXDP_HAVE_GTK_WAYLAND
#include <gdk/wayland/gdkwayland.h>
#include "gxdp-external-window-wayland.h"
#endif

G_DEFINE_TYPE (GxdpExternalWindow, gxdp_external_window, G_TYPE_OBJECT)

GxdpExternalWindow *
gxdp_external_window_new_from_handle (const char *handle_str)
{
  if (!handle_str)
    return NULL;

  if (strlen (handle_str) == 0)
    return NULL;

#ifdef GXDP_HAVE_GTK_X11
  if (GDK_IS_X11_DISPLAY (gdk_display_get_default ()))
    {
      GxdpExternalWindowX11 *external_window_x11;

      external_window_x11 = gxdp_external_window_x11_new (handle_str);
      return GXDP_EXTERNAL_WINDOW (external_window_x11);
    }
#endif
#ifdef GXDP_HAVE_GTK_WAYLAND
  if (GDK_IS_WAYLAND_DISPLAY (gdk_display_get_default ()))
    {
      GxdpExternalWindowWayland *external_window_wayland;

      external_window_wayland = gxdp_external_window_wayland_new (handle_str);
      return GXDP_EXTERNAL_WINDOW (external_window_wayland);
    }
#endif

  g_warning ("Unhandled parent window type %s", handle_str);
  return NULL;
}

void
gxdp_external_window_set_parent_of (GxdpExternalWindow *external_window,
                                    GdkSurface     *surface)
{
  GXDP_EXTERNAL_WINDOW_GET_CLASS (external_window)->set_parent_of (external_window,
                                                                   surface);
}

static void
gxdp_external_window_init (GxdpExternalWindow *external_window)
{
}

static void
gxdp_external_window_class_init (GxdpExternalWindowClass *klass)
{
}
07070100000011000081A400000000000000000000000167B22C49000005A3000000000000000000000000000000000000002F00000000libgxdp-0.gitmodule/src/gxdp-external-window.h/*
 * Copyright © 2016 Red Hat, Inc
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Jonas Ådahl <jadahl@redhat.com>
 */

#pragma once

#include <glib-object.h>
#include <gtk/gtk.h>

#define GXDP_TYPE_EXTERNAL_WINDOW (gxdp_external_window_get_type ())
G_DECLARE_DERIVABLE_TYPE (GxdpExternalWindow, gxdp_external_window,
                          GXDP, EXTERNAL_WINDOW, GObject)

struct _GxdpExternalWindowClass
{
  GObjectClass parent_class;

  void (*set_parent_of) (GxdpExternalWindow *external_window,
                         GdkSurface         *surface);
};

GxdpExternalWindow *gxdp_external_window_new_from_handle (const char *handle_str);

void gxdp_external_window_set_parent_of (GxdpExternalWindow *external_window,
                                         GdkSurface         *surface);
07070100000012000081A400000000000000000000000167B22C49000013E6000000000000000000000000000000000000002700000000libgxdp-0.gitmodule/src/gxdp-wayland.c/*
 * Copyright © 2016-2024 Red Hat, Inc
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Jonas Ådahl <jadahl@redhat.com>
 */

#include "gxdp-config.h"

#include "gxdp-wayland.h"

#include <gdk/wayland/gdkwayland.h>

#include "mutter-x11-interop-client-protocol.h"
#include "gxdp-dbus.h"

static struct mutter_x11_interop *x11_interop = NULL;

static void
handle_registry_global (void               *user_data,
                        struct wl_registry *registry,
                        uint32_t            id,
                        const char         *interface,
                        uint32_t            version)
{
  struct mutter_x11_interop **x11_interop_ptr = user_data;

  if (strcmp (interface, mutter_x11_interop_interface.name) == 0)
    {
      *x11_interop_ptr = wl_registry_bind (registry, id,
                                           &mutter_x11_interop_interface, 1);
    }
}

static void
handle_registry_global_remove (void               *user_data,
                               struct wl_registry *registry,
                               uint32_t            name)
{
}

static const struct wl_registry_listener registry_listener = {
  handle_registry_global,
  handle_registry_global_remove
};

static void
init_x11_interop (void)
{
  GdkDisplay *display = gdk_display_get_default ();
  struct wl_display *wl_display;
  struct wl_registry *wl_registry;

  g_assert (GDK_IS_WAYLAND_DISPLAY (display));

  wl_display = gdk_wayland_display_get_wl_display (display);
  wl_registry = wl_display_get_registry (wl_display);
  wl_registry_add_listener (wl_registry, &registry_listener, &x11_interop);
  wl_display_roundtrip (wl_display);

  if (!x11_interop)
    {
      g_warning ("Missing X11 interop protocol support, "
                 "portal dialogs may missbehave");
    }
}

static gboolean
init_gtk_wayland_fallback (GError **error)
{
  if (!gtk_init_check ())
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                   "Failed to initialize GTK");
      return FALSE;
    }
  return TRUE;
}

gboolean
gxdp_wayland_init (GxdpServiceClientType   service_client_type,
                   GError                **error)
{
  g_autoptr(GError) local_error = NULL;
  g_autoptr(GxdpDBusMutterServiceChannel) proxy = NULL;
  g_autoptr(GVariant) fd_variant = NULL;
  g_autoptr(GUnixFDList) fd_list = NULL;
  int fd;
  g_autofree char *fd_str = NULL;

  proxy = gxdp_dbus_mutter_service_channel_proxy_new_for_bus_sync (
    G_BUS_TYPE_SESSION,
    (G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START |
     G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
     G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS),
    "org.gnome.Mutter.ServiceChannel",
    "/org/gnome/Mutter/ServiceChannel",
    NULL, &local_error);
  if (!proxy)
    {
      g_warning ("Compositor service channel missing, "
                 "portals dialogs may missbehave (%s)",
                 local_error->message);
      return init_gtk_wayland_fallback (error);
    }

  if (!gxdp_dbus_mutter_service_channel_call_open_wayland_service_connection_sync (
        proxy,
        service_client_type,
        NULL,
        &fd_variant,
        &fd_list,
        NULL, &local_error))
    {
      g_warning ("Failed to open service channel Wayland connection, "
                 "portals dialogs may missbehave (%s).",
                 local_error->message);

      return init_gtk_wayland_fallback (error);
    }

  fd = g_unix_fd_list_get (fd_list,
                           g_variant_get_handle (fd_variant),
                           &local_error);
  if (fd < 0)
    {
      g_warning ("Failed to acquire Wayland connection file descriptor, "
                 "portals dialogs may missbehave (%s).",
                 local_error->message);

      return init_gtk_wayland_fallback (error);
    }

  fd_str = g_strdup_printf ("%d", fd);

  g_setenv ("WAYLAND_SOCKET", fd_str, TRUE);
  gdk_set_allowed_backends ("wayland");
  if (!gtk_init_check ())
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                   "Failed to initialize GTK");
      return FALSE;
    }

  init_x11_interop ();

  return TRUE;
}

void
gxdp_wayland_set_x11_parent (GdkSurface *dialog_surface,
                             int         parent_xid)
{
  struct wl_surface *wl_surface;

  g_return_if_fail (dialog_surface);

  wl_surface = gdk_wayland_surface_get_wl_surface (dialog_surface);
  mutter_x11_interop_set_x11_parent (x11_interop, wl_surface, parent_xid);
}
07070100000013000081A400000000000000000000000167B22C4900000436000000000000000000000000000000000000002700000000libgxdp-0.gitmodule/src/gxdp-wayland.h/*
 * Copyright © 2024 Red Hat, Inc
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Jonas Ådahl <jadahl@redhat.com>
 */

#pragma once

#include <gdk/gdk.h>

#include "gxdp.h"

gboolean gxdp_wayland_init (GxdpServiceClientType   service_client_type,
                            GError                **error);

void gxdp_wayland_set_x11_parent (GdkSurface *dialog_surface,
                                  int         parent_xid);
07070100000014000081A400000000000000000000000167B22C49000009F0000000000000000000000000000000000000001F00000000libgxdp-0.gitmodule/src/gxdp.c/*
 * Copyright © 2024 Red Hat, Inc
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Jonas Ådahl <jadahl@redhat.com>
 */

#include "gxdp-config.h"

#include "gxdp.h"

#include <glib.h>
#include <gio/gio.h>
#include <gtk/gtk.h>

#ifdef GXDP_HAVE_GTK_WAYLAND
#include "gxdp-wayland.h"
#endif

gboolean
gxdp_init_gtk (GxdpServiceClientType   service_client_type,
               GError                **error)
{
  const char *forced_gdk_backend;
  const char *session_type;

  if (gtk_is_initialized ())
    {
      g_warning ("GTK was initialized too early, "
                 "portal dialogs may misbehave.");
      return TRUE;
    }

  gtk_disable_portals ();

  if (G_UNLIKELY (!g_setenv ("ADW_DISABLE_PORTAL", "1", TRUE)))
    {
      g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
                   "Failed to set ADW_DISABLE_PORTAL: %s", g_strerror (errno));
      return FALSE;
    }

  forced_gdk_backend = g_getenv ("GDK_BACKEND");

  session_type = getenv ("XDG_SESSION_TYPE");
#ifdef GXDP_HAVE_GTK_WAYLAND
  if (g_strcmp0 (session_type, "wayland") == 0)
    {
      if (forced_gdk_backend && g_strcmp0 (forced_gdk_backend, "wayland") != 0)
        {
          g_warning ("GDK backend forced via env var, "
                     "portal dialogs will not work properly.");
        }
      else
        {
          return gxdp_wayland_init (service_client_type, error);
        }
    }
#endif
#ifdef GXDP_HAVE_GTK_X11
  if (g_strcmp0 (session_type, "x11") == 0)
    {
      if (!gtk_init_check ())
        {
          g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                       "Failed to initialize GTK");
          return FALSE;
        }

      return TRUE;
    }
#endif

  g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
               "Unsupported or missing session type '%s'",
               session_type ? session_type : "");
  return FALSE;
}
07070100000015000081A400000000000000000000000167B22C4900000490000000000000000000000000000000000000001F00000000libgxdp-0.gitmodule/src/gxdp.h/*
 * Copyright © 2024 Red Hat, Inc
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Jonas Ådahl <jadahl@redhat.com>
 */

#pragma once

#include <gxdp-external-window.h>

typedef enum _GxdpServiceClientType
{
  GXDP_SERVICE_CLIENT_TYPE_NONE,
  GXDP_SERVICE_CLIENT_TYPE_PORTAL_BACKEND,
  GXDP_SERVICE_CLIENT_TYPE_FILE_CHOOSER,
  GXDP_SERVICE_CLIENT_TYPE_GLOBAL_SHORTCUTS,
} GxdpServiceClientType;

gboolean gxdp_init_gtk (GxdpServiceClientType   service_client_type,
                        GError                **error);
07070100000016000081A400000000000000000000000167B22C49000008CB000000000000000000000000000000000000002400000000libgxdp-0.gitmodule/src/meson.buildgnome = import('gnome')

top_srcdir = meson.project_source_root()
dbus_interfaces = files(
  top_srcdir / 'data' / 'org.gnome.Mutter.ServiceChannel.xml',
)

sources = files(
  'gxdp.c',
  'gxdp-external-window.c',
)

built_sources = []

dependencies = [
  gtk_dep,
]

cdata = configuration_data()

gtk_wayland_dep = dependency('gtk4-wayland', required: false)
if gtk_wayland_dep.found()
  wayland_scanner = find_program('wayland-scanner')

  wayland_protocols_dir = top_srcdir / 'data'

  wayland_protocols = [
    'mutter-x11-interop',
  ]

  foreach protocol : wayland_protocols
    client_header = custom_target('@0@ client header'.format(protocol),
      input: wayland_protocols_dir / '@0@.xml'.format(protocol),
      output: '@0@-client-protocol.h'.format(protocol),
      command: [
        wayland_scanner,
        'client-header',
        '@INPUT@', '@OUTPUT@',
      ]
    )
    protocol_code = custom_target('@0@ source'.format(protocol),
      input: wayland_protocols_dir / '@0@.xml'.format(protocol),
      output: '@0@-protocol.c'.format(protocol),
      command: [
        wayland_scanner,
        'private-code',
        '@INPUT@', '@OUTPUT@',
      ]
    )

    built_sources += gnome.gdbus_codegen(
      'gxdp-dbus',
      sources: dbus_interfaces,
      namespace: 'GxdpDBus',
      interface_prefix: 'org.gnome.',
    )

    built_sources += [client_header, protocol_code]
    dependencies += [gtk_wayland_dep]
  endforeach

  sources += files([
    'gxdp-external-window-wayland.c',
    'gxdp-wayland.c',
  ])
  dependencies += [
    dependency('wayland-client'),
    gtk_wayland_dep,
  ]
  cdata.set('GXDP_HAVE_GTK_WAYLAND', true)
endif

gtk_x11_dep = dependency('gtk4-x11', required: false)
if gtk_x11_dep.found()
  sources += files('gxdp-external-window-x11.c')
  dependencies += [
    dependency('x11'),
    gtk_x11_dep,
  ]
  cdata.set('GXDP_HAVE_GTK_X11', true)
endif

gxdp_config_h = configure_file(
  input: 'gxdp-config.h.meson',
  output: 'gxdp-config.h',
  configuration: cdata
)

built_sources += [gxdp_config_h]

libgxdp_dep = declare_dependency(
  sources: sources + built_sources,
  include_directories: include_directories('.'),
  dependencies: dependencies,
)
meson.override_dependency('libgxdp', libgxdp_dep)
07070100000017000041ED00000000000000000000000267B22C4900000000000000000000000000000000000000000000001A00000000libgxdp-0.gitmodule/tests07070100000018000081A400000000000000000000000167B22C4900000427000000000000000000000000000000000000002600000000libgxdp-0.gitmodule/tests/meson.buildgtk_wayland_dep = dependency('gtk4-wayland')
gtk_x11_dep = dependency('gtk4-x11')

test_wayland_client = executable('test-wayland-client',
  sources: 'test-wayland-client.c',
  dependencies: [
    gtk_dep,
    gtk_wayland_dep,
  ],
)

test_x11_client = executable('test-x11-client',
  sources: 'test-x11-client.c',
  dependencies: [
    gtk_dep,
    gtk_x11_dep,
  ],
)

test_portal = executable('test-portal',
  sources: 'test-portal.c',
  dependencies: [
    libgxdp_dep,
    gtk_wayland_dep,
  ],
)

test_env = environment()
test_env.set('GTK_A11Y', 'none')

dbus_run_session = find_program('dbus-run-session')
mutter = find_program('mutter')
test_stacking = find_program('test-stacking.py')
test('stacking', dbus_run_session,
  args: [
    '--',
    mutter.full_path(),
    '--headless',
    '--virtual-monitor', '800x600',
    '--wayland-display', 'libgxdp-test-display',
    '--',
    test_stacking.full_path(),
    test_wayland_client.full_path(),
    test_x11_client.full_path(),
    test_portal.full_path(),
  ],
  env: test_env,
  is_parallel: false,
)
07070100000019000081A400000000000000000000000167B22C4900000962000000000000000000000000000000000000002800000000libgxdp-0.gitmodule/tests/test-portal.c/*
 * Copyright © 2024 Red Hat, Inc
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
 *
 */

#include <gdk/wayland/gdkwayland.h>
#include <gxdp.h>

int
main (int    argc,
      char **argv)
{
  GError *error = NULL;
  g_autofree char *wayland_handle = NULL;
  g_autofree char *x11_handle = NULL;
  g_autoptr (GxdpExternalWindow) external_wayland_window = NULL;
  g_autoptr (GxdpExternalWindow) external_x11_window = NULL;
  g_autoptr (GtkWindow) window1 = NULL;
  g_autoptr (GtkWindow) window2 = NULL;
  GdkSurface *surface1;
  GdkSurface *surface2;
  struct wl_display *wl_display;

  g_test_init (&argc, &argv, NULL);

  g_assert_cmpint (argc, ==, 3);

  wayland_handle = g_strdup_printf ("wayland:%s", argv[1]);
  x11_handle = g_strdup_printf ("x11:%s", argv[2]);

  gxdp_init_gtk (GXDP_SERVICE_CLIENT_TYPE_PORTAL_BACKEND, &error);
  g_assert_no_error (error);

  external_wayland_window = gxdp_external_window_new_from_handle (wayland_handle);
  external_x11_window = gxdp_external_window_new_from_handle (x11_handle);

  window1 = GTK_WINDOW (gtk_window_new ());
  gtk_window_set_default_size (window1, 50, 50);
  gtk_window_present (window1);
  surface1 = gtk_native_get_surface (GTK_NATIVE (window1));
  gxdp_external_window_set_parent_of (external_wayland_window, surface1);

  window2 = GTK_WINDOW (gtk_window_new ());
  gtk_window_set_default_size (window2, 50, 50);
  gtk_window_present (window2);
  surface2 = gtk_native_get_surface (GTK_NATIVE (window2));
  gxdp_external_window_set_parent_of (external_x11_window, surface2);

  wl_display =
    gdk_wayland_display_get_wl_display (gdk_display_get_default ());
  wl_display_roundtrip (wl_display);

  while (TRUE)
    {
      if (!g_main_context_iteration (NULL, FALSE))
        break;
    }

  return EXIT_SUCCESS;
}
0707010000001A000081ED00000000000000000000000167B22C490000029A000000000000000000000000000000000000002B00000000libgxdp-0.gitmodule/tests/test-stacking.py#!/usr/bin/env python3

import os
import subprocess
import sys

[_, wayland_client, x11_client, test_portal] = sys.argv

os.environ['G_DEBUG'] = 'fatal-warnings'

wayland_client_proc = subprocess.Popen(wayland_client, stdout=subprocess.PIPE)
x11_client_proc = subprocess.Popen(x11_client, stdout=subprocess.PIPE)

xdg_foreign_id = wayland_client_proc.stdout.readline().strip()
xid = x11_client_proc.stdout.readline().strip()

test_portal_proc = subprocess.Popen([
  test_portal,
  xdg_foreign_id,
  xid,
])

ret = test_portal_proc.wait()
assert ret == 0

wayland_client_proc.terminate()
wayland_client_proc.wait()

x11_client_proc.terminate()
x11_client_proc.wait()
0707010000001B000081A400000000000000000000000167B22C49000006BB000000000000000000000000000000000000003000000000libgxdp-0.gitmodule/tests/test-wayland-client.c/*
 * Copyright © 2024 Red Hat, Inc
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
 *
 */

#include <gdk/gdk.h>
#include <gdk/wayland/gdkwayland.h>
#include <gtk/gtk.h>

static void
on_toplevel_exported (GdkToplevel *toplevel,
                      const char  *handle,
                      gpointer     user_data)
{
  char **out_handle = user_data;

  *out_handle = g_strdup (handle);
}

int
main (int    argc,
      char **argv)
{
  g_autoptr (GtkWindow) window = NULL;
  GdkSurface *surface;
  g_autofree char *handle = NULL;

  gdk_set_allowed_backends ("wayland");
  gtk_disable_portals ();
  gtk_init ();

  window = GTK_WINDOW (gtk_window_new ());
  gtk_window_set_default_size (window, 100, 100);
  gtk_window_present (window);

  surface = gtk_native_get_surface (GTK_NATIVE (window));
  gdk_wayland_toplevel_export_handle (GDK_WAYLAND_TOPLEVEL (surface),
                                      on_toplevel_exported, &handle, NULL);
  while (!handle)
    g_main_context_iteration (NULL, TRUE);

  g_print ("%s\n", handle);

  g_main_context_iteration (NULL, TRUE);

  return EXIT_SUCCESS;
}
0707010000001C000081A400000000000000000000000167B22C4900000514000000000000000000000000000000000000002C00000000libgxdp-0.gitmodule/tests/test-x11-client.c/*
 * Copyright © 2024 Red Hat, Inc
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
 *
 */

#include <gdk/gdk.h>
#include <gdk/x11/gdkx.h>
#include <gtk/gtk.h>

int
main (int    argc,
      char **argv)
{
  g_autoptr (GtkWindow) window = NULL;
  GdkSurface *surface;
  XID xid;

  gdk_set_allowed_backends ("x11");
  gtk_disable_portals ();
  gtk_init ();

  window = GTK_WINDOW (gtk_window_new ());
  gtk_window_set_default_size (window, 100, 100);
  gtk_window_present (window);

  surface = gtk_native_get_surface (GTK_NATIVE (window));
  xid = gdk_x11_surface_get_xid (surface);

  g_print ("%lu\n", xid);

  g_main_context_iteration (NULL, TRUE);

  return EXIT_SUCCESS;
}
07070100000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000B00000000TRAILER!!!95 blocks
openSUSE Build Service is sponsored by