Skip to content

Commit

Permalink
wl: Add an XdpParent on file chooser dialog
Browse files Browse the repository at this point in the history
The XdpParent needs to know the "parent_window" string to keep the dialog on top.
On wayland this "parent_window" can be obtained using the xdg-foreign protocol.
This protocol is used on this XdpParent implementation.
First it must call export_toplevel method, and then register a callback to
receive a handle which is the "parent_window".

To store the required data for this XdpParent implementation it is used the
private "data" pointer property as a xdp_parent_wl_data.
XdpParent isn't responsible of freeing it, so that data is handled at
cog-platform-wl.
  • Loading branch information
joantolo committed Oct 18, 2023
1 parent 86f9eb8 commit 0933cb8
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 3 deletions.
28 changes: 25 additions & 3 deletions platform/wayland/cog-platform-wl.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,16 @@
#include "cog-im-context-wl-v1.h"
#include "cog-im-context-wl.h"
#include "cog-popup-menu-wl.h"
#if COG_HAVE_LIBPORTAL
# include "cog-xdp-parent-wl.h"
#endif /* COG_HAVE_LIBPORTAL */

#include "fullscreen-shell-unstable-v1-client.h"
#include "linux-dmabuf-unstable-v1-client.h"
#include "presentation-time-client.h"
#include "text-input-unstable-v1-client.h"
#include "text-input-unstable-v3-client.h"
#include "xdg-foreign-unstable-v2-client.h"
#include "xdg-shell-client.h"

#if COG_ENABLE_WESTON_DIRECT_DISPLAY
Expand Down Expand Up @@ -184,6 +188,7 @@ static struct {

struct zwp_text_input_manager_v3 *text_input_manager;
struct zwp_text_input_manager_v1 *text_input_manager_v1;
struct zxdg_exporter_v2 *zxdg_exporter;

struct wp_presentation *presentation;

Expand Down Expand Up @@ -245,6 +250,10 @@ static struct {
struct xdg_toplevel *xdg_toplevel;
struct wl_shell_surface *shell_surface;

#if COG_HAVE_LIBPORTAL
struct xdp_parent_wl_data xdp_parent_wl_data;
#endif /* COG_HAVE_LIBPORTAL */

uint32_t width;
uint32_t height;
uint32_t width_before_fullscreen;
Expand Down Expand Up @@ -834,6 +843,8 @@ registry_global (void *data,
wl_data.text_input_manager = wl_registry_bind(registry, name, &zwp_text_input_manager_v3_interface, 1);
} else if (strcmp(interface, zwp_text_input_manager_v1_interface.name) == 0) {
wl_data.text_input_manager_v1 = wl_registry_bind(registry, name, &zwp_text_input_manager_v1_interface, 1);
} else if (strcmp(interface, zxdg_exporter_v2_interface.name) == 0) {
wl_data.zxdg_exporter = wl_registry_bind(registry, name, &zxdg_exporter_v2_interface, 1);
} else if (strcmp(interface, wp_presentation_interface.name) == 0) {
wl_data.presentation = wl_registry_bind(registry, name, &wp_presentation_interface, 1);
} else {
Expand Down Expand Up @@ -1988,6 +1999,8 @@ clear_wayland (void)
zwp_fullscreen_shell_v1_destroy (wl_data.fshell);
if (wl_data.shell != NULL)
wl_shell_destroy (wl_data.shell);
if (wl_data.zxdg_exporter != NULL)
zxdg_exporter_v2_destroy(wl_data.zxdg_exporter);

g_clear_pointer (&wl_data.shm, wl_shm_destroy);
g_clear_pointer (&wl_data.subcompositor, wl_subcompositor_destroy);
Expand Down Expand Up @@ -2196,6 +2209,11 @@ create_window (GError **error)
configure_surface_geometry(0, 0);
}

#if COG_HAVE_LIBPORTAL
win_data.xdp_parent_wl_data.zxdg_exporter = wl_data.zxdg_exporter;
win_data.xdp_parent_wl_data.wl_surface = win_data.wl_surface;
#endif /* COG_HAVE_LIBPORTAL */

const char *env_var;
if ((env_var = g_getenv("COG_PLATFORM_WL_VIEW_FULLSCREEN")) && g_ascii_strtoll(env_var, NULL, 10) > 0) {
win_data.is_maximized = false;
Expand Down Expand Up @@ -2555,9 +2573,13 @@ on_show_option_menu(WebKitWebView *view, WebKitOptionMenu *menu, WebKitRectangle
static void
on_run_file_chooser(WebKitWebView *view, WebKitFileChooserRequest *request)
{
/* TODO: Disable input of main window and keep this new file chooser
* window always on top. This could be done adding an XdpParent. */
run_file_chooser(view, request, NULL);
g_autoptr(XdpParent) xdp_parent = NULL;

if (win_data.xdp_parent_wl_data.zxdg_exporter && win_data.xdp_parent_wl_data.wl_surface) {
xdp_parent = xdp_parent_new_wl(&win_data.xdp_parent_wl_data);
}

run_file_chooser(view, request, xdp_parent);
}
#endif /* COG_HAVE_LIBPORTAL */

Expand Down
54 changes: 54 additions & 0 deletions platform/wayland/cog-xdp-parent-wl.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* cog-xdp-parent-wl.c
* Copyright (C) 2023 SUSE Software Solutions Germany GmbH
*
* Distributed under terms of the MIT license.
*/

#include "cog-xdp-parent-wl.h"

#include "../common/xdp-parent-private.h"

static void
handle_exported(void *data, struct zxdg_exported_v2 *zxdg_exported_v2, const char *handle)
{
XdpParent *parent = data;
struct xdp_parent_wl_data *wl_data = (struct xdp_parent_wl_data *) parent->data;
g_autofree char *handle_str = g_strdup_printf("wayland:%s", handle);

parent->callback(parent, handle_str, wl_data->user_data);
}

static const struct zxdg_exported_v2_listener zxdg_exported_listener = {
.handle = handle_exported,
};

static gboolean
xdp_parent_export_wl(XdpParent *parent, XdpParentExported callback, gpointer user_data)
{
struct xdp_parent_wl_data *wl_data = (struct xdp_parent_wl_data *) parent->data;

parent->callback = callback;
wl_data->user_data = user_data;
wl_data->zxdg_exported = zxdg_exporter_v2_export_toplevel(wl_data->zxdg_exporter, wl_data->wl_surface);

return zxdg_exported_v2_add_listener(wl_data->zxdg_exported, &zxdg_exported_listener, parent);
}

static void
xdp_parent_unexport_wl(XdpParent *parent)
{
struct xdp_parent_wl_data *wl_data = (struct xdp_parent_wl_data *) parent->data;

zxdg_exported_v2_destroy(wl_data->zxdg_exported);
}

XdpParent *
xdp_parent_new_wl(struct xdp_parent_wl_data *wl_data)
{
XdpParent *parent = g_new0(XdpParent, 1);
parent->parent_export = xdp_parent_export_wl;
parent->parent_unexport = xdp_parent_unexport_wl;
parent->data = (gpointer) wl_data;
return parent;
}
25 changes: 25 additions & 0 deletions platform/wayland/cog-xdp-parent-wl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* cog-xdp-parent-wl.h
* Copyright (C) 2023 SUSE Software Solutions Germany GmbH
*
* Distributed under terms of the MIT license.
*/

#pragma once

#include <libportal/types.h>

#include "xdg-foreign-unstable-v2-client.h"

G_BEGIN_DECLS

struct xdp_parent_wl_data {
struct wl_surface *wl_surface;
struct zxdg_exporter_v2 *zxdg_exporter;
struct zxdg_exported_v2 *zxdg_exported;
gpointer user_data;
};

XdpParent *xdp_parent_new_wl(struct xdp_parent_wl_data *wl_data);

G_END_DECLS
5 changes: 5 additions & 0 deletions platform/wayland/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ wayland_platform_protocols = {
['linux-dmabuf', 1],
['text-input', 1],
['text-input', 3],
['xdg-foreign', 2],
],
'weston': wayland_platform_weston_protocols,
}
Expand Down Expand Up @@ -118,6 +119,10 @@ if wayland_cursor_dep.found()
wayland_platform_c_args += ['-DCOG_USE_WAYLAND_CURSOR=1']
endif

if libportal_dep.found()
wayland_platform_sources += ['cog-xdp-parent-wl.c']
endif

cc = meson.get_compiler('c')
if cc.has_header_symbol('sys/mman.h', 'memfd_create', args : '-D_GNU_SOURCE')
wayland_platform_c_args += ['-DHAVE_MEMFD_CREATE']
Expand Down

0 comments on commit 0933cb8

Please sign in to comment.