mirror of
https://github.com/labwc/labwc.git
synced 2026-06-13 14:33:18 -04:00
desktop: refresh workspace appearance for workspace changes
Fix workspace state updates so panels such as sfwbar can correctly track workspace-filtered taskbars under labwc. - remove restriction that skips workspace updates when the source is OSD - trigger output_update_workspace_appearance() after workspace change - return early when no view is present to avoid inconsistent updates This resolves incorrect behavior where sfwbar (filter = workspace) does not update properly under labwc, while it works correctly on sway. Related: https://github.com/LBCrion/sfwbar/issues/412
This commit is contained in:
parent
5f668a82ee
commit
df1e8eb008
6 changed files with 97 additions and 4 deletions
|
|
@ -8,6 +8,7 @@ struct foreign_toplevel;
|
||||||
struct foreign_toplevel *foreign_toplevel_create(struct view *view);
|
struct foreign_toplevel *foreign_toplevel_create(struct view *view);
|
||||||
void foreign_toplevel_set_parent(struct foreign_toplevel *toplevel,
|
void foreign_toplevel_set_parent(struct foreign_toplevel *toplevel,
|
||||||
struct foreign_toplevel *parent);
|
struct foreign_toplevel *parent);
|
||||||
|
void foreign_toplevel_refresh(struct foreign_toplevel *toplevel);
|
||||||
void foreign_toplevel_destroy(struct foreign_toplevel *toplevel);
|
void foreign_toplevel_destroy(struct foreign_toplevel *toplevel);
|
||||||
|
|
||||||
#endif /* LABWC_FOREIGN_TOPLEVEL_H */
|
#endif /* LABWC_FOREIGN_TOPLEVEL_H */
|
||||||
|
|
|
||||||
|
|
@ -1,27 +1,75 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
#include "foreign-toplevel/foreign.h"
|
#include "foreign-toplevel/foreign.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include "common/mem.h"
|
#include "common/mem.h"
|
||||||
#include "foreign-toplevel/ext-foreign.h"
|
#include "foreign-toplevel/ext-foreign.h"
|
||||||
#include "foreign-toplevel/wlr-foreign.h"
|
#include "foreign-toplevel/wlr-foreign.h"
|
||||||
|
#include "labwc.h"
|
||||||
#include "view.h"
|
#include "view.h"
|
||||||
|
|
||||||
struct foreign_toplevel {
|
struct foreign_toplevel {
|
||||||
|
struct view *view;
|
||||||
|
|
||||||
/* *-toplevel implementations */
|
/* *-toplevel implementations */
|
||||||
struct wlr_foreign_toplevel wlr_toplevel;
|
struct wlr_foreign_toplevel wlr_toplevel;
|
||||||
struct ext_foreign_toplevel ext_toplevel;
|
struct ext_foreign_toplevel ext_toplevel;
|
||||||
|
|
||||||
/* TODO: add struct xdg_x11_mapped_toplevel at some point */
|
/* TODO: add struct xdg_x11_mapped_toplevel at some point */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static bool
|
||||||
|
should_export_to_panels(struct foreign_toplevel *toplevel)
|
||||||
|
{
|
||||||
|
struct view *view = toplevel->view;
|
||||||
|
|
||||||
|
if (!view || !view->mapped) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (view->visible_on_all_workspaces) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return view->workspace == server.workspaces.current;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
is_exported(struct foreign_toplevel *toplevel)
|
||||||
|
{
|
||||||
|
return !!toplevel->wlr_toplevel.handle || !!toplevel->ext_toplevel.handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
foreign_toplevel_refresh(struct foreign_toplevel *toplevel)
|
||||||
|
{
|
||||||
|
bool want, have;
|
||||||
|
|
||||||
|
assert(toplevel);
|
||||||
|
|
||||||
|
want = should_export_to_panels(toplevel);
|
||||||
|
have = is_exported(toplevel);
|
||||||
|
|
||||||
|
if (want == have) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (want) {
|
||||||
|
wlr_foreign_toplevel_init(&toplevel->wlr_toplevel, toplevel->view);
|
||||||
|
ext_foreign_toplevel_init(&toplevel->ext_toplevel, toplevel->view);
|
||||||
|
} else {
|
||||||
|
wlr_foreign_toplevel_finish(&toplevel->wlr_toplevel);
|
||||||
|
ext_foreign_toplevel_finish(&toplevel->ext_toplevel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct foreign_toplevel *
|
struct foreign_toplevel *
|
||||||
foreign_toplevel_create(struct view *view)
|
foreign_toplevel_create(struct view *view)
|
||||||
{
|
{
|
||||||
assert(view);
|
assert(view);
|
||||||
|
|
||||||
struct foreign_toplevel *toplevel = znew(*toplevel);
|
struct foreign_toplevel *toplevel = znew(*toplevel);
|
||||||
wlr_foreign_toplevel_init(&toplevel->wlr_toplevel, view);
|
toplevel->view = view;
|
||||||
ext_foreign_toplevel_init(&toplevel->ext_toplevel, view);
|
foreign_toplevel_refresh(toplevel);
|
||||||
|
|
||||||
return toplevel;
|
return toplevel;
|
||||||
}
|
}
|
||||||
|
|
@ -30,6 +78,11 @@ void
|
||||||
foreign_toplevel_set_parent(struct foreign_toplevel *toplevel, struct foreign_toplevel *parent)
|
foreign_toplevel_set_parent(struct foreign_toplevel *toplevel, struct foreign_toplevel *parent)
|
||||||
{
|
{
|
||||||
assert(toplevel);
|
assert(toplevel);
|
||||||
|
|
||||||
|
if (!toplevel->wlr_toplevel.handle) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
wlr_foreign_toplevel_set_parent(&toplevel->wlr_toplevel,
|
wlr_foreign_toplevel_set_parent(&toplevel->wlr_toplevel,
|
||||||
parent ? &parent->wlr_toplevel : NULL);
|
parent ? &parent->wlr_toplevel : NULL);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1581,6 +1581,10 @@ view_toggle_visible_on_all_workspaces(struct view *view)
|
||||||
assert(view);
|
assert(view);
|
||||||
view->visible_on_all_workspaces = !view->visible_on_all_workspaces;
|
view->visible_on_all_workspaces = !view->visible_on_all_workspaces;
|
||||||
ssd_update_geometry(view->ssd);
|
ssd_update_geometry(view->ssd);
|
||||||
|
|
||||||
|
if (view->foreign_toplevel) {
|
||||||
|
foreign_toplevel_refresh(view->foreign_toplevel);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -1592,6 +1596,10 @@ view_move_to_workspace(struct view *view, struct workspace *workspace)
|
||||||
view->workspace = workspace;
|
view->workspace = workspace;
|
||||||
wlr_scene_node_reparent(&view->scene_tree->node,
|
wlr_scene_node_reparent(&view->scene_tree->node,
|
||||||
workspace->view_trees[view->layer]);
|
workspace->view_trees[view->layer]);
|
||||||
|
|
||||||
|
if (view->foreign_toplevel) {
|
||||||
|
foreign_toplevel_refresh(view->foreign_toplevel);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,12 @@
|
||||||
#include "show-desktop.h"
|
#include "show-desktop.h"
|
||||||
#include "theme.h"
|
#include "theme.h"
|
||||||
#include "view.h"
|
#include "view.h"
|
||||||
|
#include "common/macros.h"
|
||||||
|
//#include "desktop.h"
|
||||||
|
#include "foreign-toplevel/foreign.h"
|
||||||
|
#include "input/keyboard.h"
|
||||||
|
#include "labwc.h"
|
||||||
|
#include "menu/menu.h"
|
||||||
|
|
||||||
#define EXT_WORKSPACES_VERSION 1
|
#define EXT_WORKSPACES_VERSION 1
|
||||||
|
|
||||||
|
|
@ -464,9 +470,16 @@ workspaces_switch_to(struct workspace *target, bool update_focus)
|
||||||
/* Save the last visited workspace */
|
/* Save the last visited workspace */
|
||||||
server.workspaces.last = server.workspaces.current;
|
server.workspaces.last = server.workspaces.current;
|
||||||
|
|
||||||
/* Make sure new views will spawn on the new workspace */
|
/* Make sure new views will spawn on the new workspace */
|
||||||
server.workspaces.current = target;
|
server.workspaces.current = target;
|
||||||
|
|
||||||
|
struct view *it;
|
||||||
|
wl_list_for_each(it, &server.views, link) {
|
||||||
|
if (it->foreign_toplevel) {
|
||||||
|
foreign_toplevel_refresh(it->foreign_toplevel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct view *grabbed_view = server.grabbed_view;
|
struct view *grabbed_view = server.grabbed_view;
|
||||||
if (grabbed_view) {
|
if (grabbed_view) {
|
||||||
view_move_to_workspace(grabbed_view, target);
|
view_move_to_workspace(grabbed_view, target);
|
||||||
|
|
|
||||||
|
|
@ -846,6 +846,11 @@ handle_map(struct wl_listener *listener, void *data)
|
||||||
}
|
}
|
||||||
|
|
||||||
view_impl_map(view);
|
view_impl_map(view);
|
||||||
|
|
||||||
|
if (view->foreign_toplevel) {
|
||||||
|
foreign_toplevel_refresh(view->foreign_toplevel);
|
||||||
|
}
|
||||||
|
|
||||||
view->been_mapped = true;
|
view->been_mapped = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -856,6 +861,10 @@ handle_unmap(struct wl_listener *listener, void *data)
|
||||||
if (view->mapped) {
|
if (view->mapped) {
|
||||||
view->mapped = false;
|
view->mapped = false;
|
||||||
view_impl_unmap(view);
|
view_impl_unmap(view);
|
||||||
|
|
||||||
|
if (view->foreign_toplevel) {
|
||||||
|
foreign_toplevel_refresh(view->foreign_toplevel);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -823,6 +823,11 @@ handle_map(struct wl_listener *listener, void *data)
|
||||||
}
|
}
|
||||||
|
|
||||||
view_impl_map(view);
|
view_impl_map(view);
|
||||||
|
|
||||||
|
if (view->foreign_toplevel) {
|
||||||
|
foreign_toplevel_refresh(view->foreign_toplevel);
|
||||||
|
}
|
||||||
|
|
||||||
view->been_mapped = true;
|
view->been_mapped = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -836,6 +841,10 @@ handle_unmap(struct wl_listener *listener, void *data)
|
||||||
view->mapped = false;
|
view->mapped = false;
|
||||||
view_impl_unmap(view);
|
view_impl_unmap(view);
|
||||||
|
|
||||||
|
if (view->foreign_toplevel) {
|
||||||
|
foreign_toplevel_refresh(view->foreign_toplevel);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Destroy the content_tree at unmap. Alternatively, we could
|
* Destroy the content_tree at unmap. Alternatively, we could
|
||||||
* let wlr_scene manage its lifetime automatically, but this
|
* let wlr_scene manage its lifetime automatically, but this
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue