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 created and
freed on cog-platform-wl.
  • Loading branch information
joantolo committed Oct 6, 2023
1 parent aa4fe4c commit 7247fff
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 3 deletions.
24 changes: 21 additions & 3 deletions platform/wayland/cog-platform-wl.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,14 @@
#include "cog-im-context-wl-v1.h"
#include "cog-im-context-wl.h"
#include "cog-popup-menu-wl.h"
#include "cog-xdp-parent-wl.h"

#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 @@ -182,6 +184,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 @@ -243,6 +246,8 @@ static struct {
struct xdg_toplevel *xdg_toplevel;
struct wl_shell_surface *shell_surface;

struct xdp_parent_wl_data *xdp_parent_wl_data;

uint32_t width;
uint32_t height;
uint32_t width_before_fullscreen;
Expand Down Expand Up @@ -832,6 +837,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 @@ -1986,6 +1993,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 @@ -2194,6 +2203,12 @@ create_window (GError **error)
configure_surface_geometry(0, 0);
}

if (wl_data.zxdg_exporter) {
win_data.xdp_parent_wl_data = g_new0 (struct xdp_parent_wl_data, 1);
win_data.xdp_parent_wl_data->zxdg_exporter = wl_data.zxdg_exporter;
win_data.xdp_parent_wl_data->wl_surface = win_data.wl_surface;
}

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 @@ -2234,6 +2249,7 @@ destroy_window (void)
g_clear_pointer (&win_data.xdg_surface, xdg_surface_destroy);
g_clear_pointer (&win_data.shell_surface, wl_shell_surface_destroy);
g_clear_pointer (&win_data.wl_surface, wl_surface_destroy);
g_clear_pointer (&win_data.xdp_parent_wl_data, g_free);

#if COG_ENABLE_WESTON_DIRECT_DISPLAY
g_clear_pointer (&win_data.video_surfaces, g_hash_table_destroy);
Expand Down Expand Up @@ -2552,9 +2568,11 @@ 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);
XdpParent *xdp_parent = xdp_parent_new_wl (win_data.xdp_parent_wl_data);

run_file_chooser (view, request, xdp_parent);

g_clear_pointer (&xdp_parent, xdp_parent_free);
}

static void
Expand Down
56 changes: 56 additions & 0 deletions platform/wayland/cog-xdp-parent-wl.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* 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
2 changes: 2 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 @@ -128,6 +129,7 @@ wayland_platform_plugin = shared_module('cogplatform-wl',
'cog-im-context-wl.c',
'cog-platform-wl.c',
'cog-popup-menu-wl.c',
'cog-xdp-parent-wl.c',
'os-compatibility.c',
wayland_platform_sources,
c_args: wayland_platform_c_args,
Expand Down

0 comments on commit 7247fff

Please sign in to comment.