Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 17 additions & 5 deletions src/cairo-dock-user-menu.c
Original file line number Diff line number Diff line change
Expand Up @@ -2028,6 +2028,13 @@ gboolean cairo_dock_notification_build_icon_menu (G_GNUC_UNUSED gpointer *pUserD
}

//\_________________________ Other actions
gboolean bCanFullscreen = FALSE;
gboolean bCanSticky = FALSE;
gboolean bCanBelow = FALSE;
gboolean bCanAbove = FALSE;
gboolean bCanKill = FALSE;
gldi_window_manager_get_supported_actions (&bCanFullscreen, &bCanSticky, &bCanBelow, &bCanAbove, &bCanKill);

GtkWidget *pSubMenuOtherActions = cairo_dock_create_sub_menu (_("Other actions"), menu, NULL);

// Move
Expand All @@ -2037,7 +2044,8 @@ gboolean cairo_dock_notification_build_icon_menu (G_GNUC_UNUSED gpointer *pUserD
gtk_widget_set_sensitive (pMenuItem, FALSE);

// Fullscreen
_add_entry_in_menu (pAppli->bIsFullScreen ? _("Not Fullscreen") : _("Fullscreen"), pAppli->bIsFullScreen ? GLDI_ICON_NAME_LEAVE_FULLSCREEN : GLDI_ICON_NAME_FULLSCREEN, _cairo_dock_set_appli_fullscreen, pSubMenuOtherActions, params);
pMenuItem = _add_entry_in_menu (pAppli->bIsFullScreen ? _("Not Fullscreen") : _("Fullscreen"), pAppli->bIsFullScreen ? GLDI_ICON_NAME_LEAVE_FULLSCREEN : GLDI_ICON_NAME_FULLSCREEN, _cairo_dock_set_appli_fullscreen, pSubMenuOtherActions, params);
if (!bCanFullscreen) gtk_widget_set_sensitive (pMenuItem, FALSE);

// Below
if (! pAppli->bIsHidden) // this could be a button in the menu, if we find an icon that doesn't look too much like the "minimise" one
Expand All @@ -2046,18 +2054,21 @@ gboolean cairo_dock_notification_build_icon_menu (G_GNUC_UNUSED gpointer *pUserD
cLabel = g_strdup_printf ("%s (%s)", _("Below other windows"), _("middle-click"));
else
cLabel = g_strdup (_("Below other windows"));
_add_entry_in_menu (cLabel, CAIRO_DOCK_SHARE_DATA_DIR"/icons/icon-lower.svg", _cairo_dock_lower_appli, pSubMenuOtherActions, params);
pMenuItem = _add_entry_in_menu (cLabel, CAIRO_DOCK_SHARE_DATA_DIR"/icons/icon-lower.svg", _cairo_dock_lower_appli, pSubMenuOtherActions, params);
g_free (cLabel);
if (! bCanBelow) gtk_widget_set_sensitive (pMenuItem, FALSE);
}

// Above
gboolean bIsAbove=FALSE, bIsBelow=FALSE;
gldi_window_is_above_or_below (pAppli, &bIsAbove, &bIsBelow);
_add_entry_in_menu (bIsAbove ? _("Don't keep above") : _("Keep above"), bIsAbove ? GLDI_ICON_NAME_GOTO_BOTTOM : GLDI_ICON_NAME_GOTO_TOP, _cairo_dock_change_window_above, pSubMenuOtherActions, params);
pMenuItem = _add_entry_in_menu (bIsAbove ? _("Don't keep above") : _("Keep above"), bIsAbove ? GLDI_ICON_NAME_GOTO_BOTTOM : GLDI_ICON_NAME_GOTO_TOP, _cairo_dock_change_window_above, pSubMenuOtherActions, params);
if (! bCanAbove) gtk_widget_set_sensitive (pMenuItem, FALSE);

// Sticky
gboolean bIsSticky = gldi_window_is_sticky (pAppli);
_add_entry_in_menu (bIsSticky ? _("Visible only on this desktop") : _("Visible on all desktops"), GLDI_ICON_NAME_JUMP_TO, _cairo_dock_change_window_sticky, pSubMenuOtherActions, params);
pMenuItem = _add_entry_in_menu (bIsSticky ? _("Visible only on this desktop") : _("Visible on all desktops"), GLDI_ICON_NAME_JUMP_TO, _cairo_dock_change_window_sticky, pSubMenuOtherActions, params);
if (! bCanSticky) gtk_widget_set_sensitive (pMenuItem, FALSE);

if (!bIsSticky) // if the window is sticky, it's on all desktops/viewports, so you can't move it to another
_add_desktops_entry (pSubMenuOtherActions, FALSE, params);
Expand All @@ -2066,7 +2077,8 @@ gboolean cairo_dock_notification_build_icon_menu (G_GNUC_UNUSED gpointer *pUserD
pMenuItem = gtk_separator_menu_item_new ();
gtk_menu_shell_append (GTK_MENU_SHELL (pSubMenuOtherActions), pMenuItem);

_add_entry_in_menu (_("Kill"), GLDI_ICON_NAME_CLOSE, _cairo_dock_kill_appli, pSubMenuOtherActions, params);
pMenuItem = _add_entry_in_menu (_("Kill"), GLDI_ICON_NAME_CLOSE, _cairo_dock_kill_appli, pSubMenuOtherActions, params);
if (! bCanKill) gtk_widget_set_sensitive (pMenuItem, FALSE);
}
else if (CAIRO_DOCK_IS_MULTI_APPLI (icon))
{
Expand Down
8 changes: 8 additions & 0 deletions src/gldit/cairo-dock-windows-manager-priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ struct _GldiWindowManagerBackend {
void (*move_to_viewport_abs) (GldiWindowActor *actor, int iNumDesktop, int iViewportX, int iViewportY); // like move_to_nth_desktop, but use absolute viewport coordinates
gpointer flags; // GldiWMBackendFlags, cast to pointer
void (*get_menu_address) (GldiWindowActor *actor, char **service_name, char **object_path);
void (*get_supported_actions) (gboolean *bCanFullscreen, gboolean *bCanSticky, gboolean *bCanBelow, gboolean *bCanAbove, gboolean *bCanKill);
} ;

/** Register a Window Manager backend. NULL functions are simply ignored.
Expand Down Expand Up @@ -100,6 +101,13 @@ GldiWindowActor *gldi_window_pick (GtkWindow *pParentWindow);
*/
GPtrArray *gldi_window_manager_get_all (void);

/** Get whether the given additional window actions are supported by the WM backend. */
void gldi_window_manager_get_supported_actions (
gboolean *bCanFullscreen,
gboolean *bCanSticky,
gboolean *bCanBelow,
gboolean *bCanAbove,
gboolean *bCanKill);

/** Utility for parsing special cases in the window class / app ID;
* used by both the X and Wayland backends.
Expand Down
17 changes: 17 additions & 0 deletions src/gldit/cairo-dock-windows-manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,23 @@ void gldi_window_can_minimize_maximize_close (GldiWindowActor *actor, gboolean *
}
}

void gldi_window_manager_get_supported_actions (
gboolean *bCanFullscreen,
gboolean *bCanSticky,
gboolean *bCanBelow,
gboolean *bCanAbove,
gboolean *bCanKill)
{
if (bCanFullscreen) *bCanFullscreen = FALSE;
if (bCanSticky) *bCanSticky = FALSE;
if (bCanBelow) *bCanBelow = FALSE;
if (bCanAbove) *bCanAbove = FALSE;
if (bCanKill) *bCanKill = FALSE;
if (s_backend.get_supported_actions)
s_backend.get_supported_actions (bCanFullscreen, bCanSticky, bCanBelow, bCanAbove, bCanKill);
}


guint gldi_window_get_id (GldiWindowActor *actor)
{
if (actor && s_backend.get_id)
Expand Down
5 changes: 5 additions & 0 deletions src/implementations/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ if(WaylandScanner_FOUND)
cairo-dock-plasma-window-manager.c cairo-dock-plasma-window-manager.h
cairo-dock-plasma-virtual-desktop.c cairo-dock-plasma-virtual-desktop.h
cairo-dock-ext-workspaces.c cairo-dock-ext-workspaces.h
cairo-dock-ext-toplevel.c cairo-dock-ext-toplevel.h
)

ecm_add_wayland_client_protocol(
Expand Down Expand Up @@ -75,6 +76,10 @@ if(WaylandScanner_FOUND)
impl_SRCS
PROTOCOL "proto/ext-foreign-toplevel-list-v1.xml"
BASENAME "ext-toplevel-list")
ecm_add_wayland_client_protocol(
impl_SRCS
PROTOCOL "proto/ext-foreign-toplevel-state-v1.xml"
BASENAME "ext-toplevel-state")
ecm_add_wayland_client_protocol(
impl_SRCS
PROTOCOL "proto/plasma-virtual-desktop.xml"
Expand Down
10 changes: 10 additions & 0 deletions src/implementations/cairo-dock-X-manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -1580,6 +1580,15 @@ static gboolean _dispatch (G_GNUC_UNUSED GSource *source, G_GNUC_UNUSED GSourceF
return _cairo_dock_unstack_Xevents (NULL);
}

static void _get_supported_actions (gboolean *bCanFullscreen, gboolean *bCanSticky, gboolean *bCanBelow, gboolean *bCanAbove, gboolean *bCanKill)
{
// note: there is no way to test for capabilities, we just assume that everything will work
if (bCanFullscreen) *bCanFullscreen = TRUE;
if (bCanSticky) *bCanSticky = TRUE;
if (bCanBelow) *bCanBelow = TRUE;
if (bCanAbove) *bCanAbove = TRUE;
if (bCanKill) *bCanKill = TRUE;
}

static void init (void)
{
Expand Down Expand Up @@ -1696,6 +1705,7 @@ static void init (void)
wmb.can_minimize_maximize_close = _can_minimize_maximize_close;
wmb.get_id = _get_id;
wmb.pick_window = _pick_window;
wmb.get_supported_actions = _get_supported_actions;
//!! TODO: figure out GLDI_WM_NO_VIEWPORT_OVERLAP flag (depends on the WM, needs to be done in *-integration.c) !!
wmb.flags = GINT_TO_POINTER (GLDI_WM_HAVE_WINDOW_GEOMETRY | GLDI_WM_HAVE_WORKSPACES);
wmb.name = "X11";
Expand Down
26 changes: 24 additions & 2 deletions src/implementations/cairo-dock-cosmic-toplevel.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ static gboolean can_maximize = FALSE;
static gboolean can_minimize = FALSE;
static gboolean can_fullscreen = FALSE;
static gboolean can_move_workspace = FALSE;
static gboolean can_sticky = FALSE;

static gboolean list_found = FALSE;
static gboolean manager_found = FALSE;
Expand Down Expand Up @@ -171,6 +172,15 @@ static void _set_fullscreen (GldiWindowActor *actor, gboolean bFullScreen)
else zcosmic_toplevel_manager_v1_unset_fullscreen (s_ptoplevel_manager, wactor->chandle);
}

static void _set_sticky (GldiWindowActor *actor, gboolean bSticky)
{
if (!actor) return;
if (!can_sticky) return; // will be the case if compositor protocol version is < 3, in this case we should avoid this request
GldiCosmicWindowActor *wactor = (GldiCosmicWindowActor *)actor;
if (bSticky) zcosmic_toplevel_manager_v1_set_sticky (s_ptoplevel_manager, wactor->chandle);
else zcosmic_toplevel_manager_v1_unset_sticky (s_ptoplevel_manager, wactor->chandle);
}

static void _capabilities_cb (G_GNUC_UNUSED void *data, G_GNUC_UNUSED struct zcosmic_toplevel_manager_v1 *manager,
struct wl_array *c)
{
Expand All @@ -180,6 +190,7 @@ static void _capabilities_cb (G_GNUC_UNUSED void *data, G_GNUC_UNUSED struct zco
can_minimize = FALSE;
can_fullscreen = FALSE;
can_move_workspace = FALSE;
can_sticky = FALSE;

int i;
uint32_t* cdata = (uint32_t*)c->data;
Expand All @@ -195,11 +206,21 @@ static void _capabilities_cb (G_GNUC_UNUSED void *data, G_GNUC_UNUSED struct zco
can_minimize = TRUE; break;
case ZCOSMIC_TOPLEVEL_MANAGER_V1_ZCOSMIC_TOPLELEVEL_MANAGEMENT_CAPABILITIES_V1_FULLSCREEN:
can_fullscreen = TRUE; break;
case ZCOSMIC_TOPLEVEL_MANAGER_V1_ZCOSMIC_TOPLELEVEL_MANAGEMENT_CAPABILITIES_V1_MOVE_TO_WORKSPACE:
case ZCOSMIC_TOPLEVEL_MANAGER_V1_ZCOSMIC_TOPLELEVEL_MANAGEMENT_CAPABILITIES_V1_MOVE_TO_EXT_WORKSPACE:
can_move_workspace = TRUE; break;
case ZCOSMIC_TOPLEVEL_MANAGER_V1_ZCOSMIC_TOPLELEVEL_MANAGEMENT_CAPABILITIES_V1_STICKY:
can_sticky = TRUE; break;
}
}

static void _get_supported_actions (gboolean *bCanFullscreen, gboolean *bCanSticky, gboolean *bCanBelow, gboolean *bCanAbove, gboolean *bCanKill)
{
if (bCanFullscreen) *bCanFullscreen = can_fullscreen;
if (bCanSticky) *bCanSticky = can_sticky;
if (bCanBelow) *bCanBelow = FALSE; // not supported
if (bCanAbove) *bCanAbove = FALSE;
if (bCanKill) *bCanKill = FALSE;
}


/**********************************************************************
Expand Down Expand Up @@ -821,10 +842,11 @@ gboolean gldi_cosmic_toplevel_try_init (struct wl_registry *registry)
wmb.get_transient_for = _get_transient_for;
// wmb.is_above_or_below = _is_above_or_below;
// wmb.is_sticky = _is_sticky;
// wmb.set_sticky = _set_sticky;
wmb.set_sticky = _set_sticky;
wmb.can_minimize_maximize_close = _can_minimize_maximize_close;
// wmb.get_id = _get_id;
wmb.pick_window = gldi_wayland_wm_pick_window;
wmb.get_supported_actions = _get_supported_actions;
int flags = GLDI_WM_NO_VIEWPORT_OVERLAP | GLDI_WM_GEOM_REL_TO_VIEWPORT;
if (info_version >= 2) flags |= GLDI_WM_HAVE_WINDOW_GEOMETRY;
if (info_version >= 3) flags |= GLDI_WM_HAVE_WORKSPACES; // we only use ext-workspaces now, which are only available with version >= 3
Expand Down
Loading