diff --git a/cage.c b/cage.c index d01110e..f68379a 100644 --- a/cage.c +++ b/cage.c @@ -17,6 +17,8 @@ #include #include #include +#include +#include #include #include #include @@ -36,11 +38,31 @@ #include "output.h" #include "seat.h" #include "server.h" +#include "view.h" #include "xdg_shell.h" #if CAGE_HAS_XWAYLAND #include "xwayland.h" #endif +void +set_window_title(struct cg_server *server, struct cg_view *view) +{ + struct wlr_output *output = server->output->wlr_output; + bool is_wl = wlr_output_is_wl(output); + bool is_x11 = wlr_output_is_x11(output); + + if (!is_wl && !is_x11) { + return; + } + + const char *title = view_get_title(view); + if (is_wl) { + wlr_wl_output_set_title(output, title); + } else if (is_x11) { + wlr_x11_output_set_title(output, title); + } +} + static bool spawn_primary_client(char *argv[], pid_t *pid_out) { diff --git a/seat.c b/seat.c index bbb65bf..197a98b 100644 --- a/seat.c +++ b/seat.c @@ -724,7 +724,8 @@ seat_set_focus(struct cg_seat *seat, struct cg_view *view) wl_list_insert(&server->views, &view->link); } - view_activate(view, true); + view_activate(view, true); + set_window_title(server, view); struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(wlr_seat); if (keyboard) { diff --git a/server.h b/server.h index e93fd3e..f554294 100644 --- a/server.h +++ b/server.h @@ -14,6 +14,7 @@ #include "output.h" #include "seat.h" +#include "view.h" struct cg_server { struct wl_display *wl_display; @@ -37,4 +38,6 @@ struct cg_server { #endif }; +void set_window_title(struct cg_server *server, struct cg_view *view); + #endif diff --git a/view.c b/view.c index c213a65..01826f3 100644 --- a/view.c +++ b/view.c @@ -6,8 +6,11 @@ * See the LICENSE file accompanying this file. */ +#define _POSIX_C_SOURCE 200809L + #include #include +#include #include #include #include @@ -18,6 +21,13 @@ #include "server.h" #include "view.h" +char * +view_get_title(struct cg_view *view) +{ + const char *title = view->get_title(view); + return strndup(title, strlen(title)); +} + void view_activate(struct cg_view *view, bool activate) { diff --git a/view.h b/view.h index 718238d..00e3f31 100644 --- a/view.h +++ b/view.h @@ -41,6 +41,7 @@ struct cg_view { // TODO: allow applications to go to fullscreen from maximized? // struct wl_listener request_fullscreen; + char *(*get_title)(struct cg_view *view); void (*activate)(struct cg_view *view, bool activate); void (*maximize)(struct cg_view *view, int output_width, int output_height); void (*get_geometry)(struct cg_view *view, int *width_out, int *height_out); @@ -52,6 +53,7 @@ struct cg_view { bool (*is_parent)(struct cg_view *parent, struct cg_view *child); }; +char *view_get_title(struct cg_view *view); void view_activate(struct cg_view *view, bool activate); void view_for_each_surface(struct cg_view *view, wlr_surface_iterator_func_t iterator, void *data); struct wlr_surface *view_wlr_surface_at(struct cg_view *view, double sx, double sy, diff --git a/xdg_shell.c b/xdg_shell.c index 8eccae3..7a21b3e 100644 --- a/xdg_shell.c +++ b/xdg_shell.c @@ -14,6 +14,12 @@ #include "server.h" #include "view.h" +static char * +get_title(struct cg_view *view) +{ + return view->xdg_surface->toplevel->title; +} + static void activate(struct cg_view *view, bool activate) { @@ -109,6 +115,7 @@ handle_xdg_shell_surface_new(struct wl_listener *listener, void *data) view->destroy.notify = handle_xdg_shell_surface_destroy; wl_signal_add(&xdg_surface->events.destroy, &view->destroy); + view->get_title = get_title; view->activate = activate; view->maximize = maximize; view->get_geometry = get_geometry; diff --git a/xwayland.c b/xwayland.c index 7418f7b..90741ec 100644 --- a/xwayland.c +++ b/xwayland.c @@ -14,6 +14,12 @@ #include "server.h" #include "view.h" +static char * +get_title(struct cg_view *view) +{ + return view->xwayland_surface->title; +} + static void activate(struct cg_view *view, bool activate) { @@ -101,6 +107,7 @@ handle_xwayland_surface_new(struct wl_listener *listener, void *data) view->destroy.notify = handle_xwayland_surface_destroy; wl_signal_add(&xwayland_surface->events.destroy, &view->destroy); + view->get_title = get_title; view->activate = activate; view->maximize = maximize; view->get_geometry = get_geometry;