diff --git a/etc/hikari/hikari.conf b/etc/hikari/hikari.conf index c23ada6..7d70d15 100644 --- a/etc/hikari/hikari.conf +++ b/etc/hikari/hikari.conf @@ -151,6 +151,7 @@ bindings { "L+f" = view-toggle-maximize-full "L5+plus" = view-toggle-floating "L+i" = view-toggle-invisible + "L5+p" = view-toggle-public "LS+o" = group-only "LS+h" = group-hide diff --git a/include/hikari/output.h b/include/hikari/output.h index 916f11f..ad73497 100644 --- a/include/hikari/output.h +++ b/include/hikari/output.h @@ -78,7 +78,7 @@ hikari_output_render_background(struct hikari_output *output, float alpha); void -hikari_output_render_sticky( +hikari_output_render_visible_views( struct hikari_output *output, struct hikari_render_data *render_data); void diff --git a/include/hikari/server.h b/include/hikari/server.h index aed5c4d..4716fb7 100644 --- a/include/hikari/server.h +++ b/include/hikari/server.h @@ -310,6 +310,7 @@ WORKSPACE_ACTION(toggle_view_horizontal_maximize) WORKSPACE_ACTION(toggle_view_full_maximize) WORKSPACE_ACTION(toggle_view_floating) WORKSPACE_ACTION(toggle_view_invisible) +WORKSPACE_ACTION(toggle_view_public) WORKSPACE_ACTION(only_view) WORKSPACE_ACTION(only_group) WORKSPACE_ACTION(hide_view) diff --git a/include/hikari/view.h b/include/hikari/view.h index 3a1c7eb..9977d33 100644 --- a/include/hikari/view.h +++ b/include/hikari/view.h @@ -132,6 +132,8 @@ hikari_view_subsurface_fini(struct hikari_view_subsurface *view_subsurface); FLAG(hidden, 0UL) FLAG(invisible, 1UL) FLAG(floating, 2UL) +FLAG(public, 3UL) +FLAG(forced, 4UL) #undef FLAG void @@ -160,6 +162,7 @@ VIEW_ACTION(top_left_cursor) VIEW_ACTION(bottom_right_cursor) VIEW_ACTION(center_cursor) VIEW_ACTION(toggle_invisible) +VIEW_ACTION(toggle_public) VIEW_ACTION(reset_geometry) #undef VIEW_ACTION diff --git a/include/hikari/view_autoconf.h b/include/hikari/view_autoconf.h index 23f5c81..2324047 100644 --- a/include/hikari/view_autoconf.h +++ b/include/hikari/view_autoconf.h @@ -25,6 +25,7 @@ struct hikari_view_autoconf { bool focus; bool invisible; bool floating; + bool publicview; }; void @@ -70,6 +71,13 @@ hikari_view_autoconf_resolve_floating( return view_autoconf->floating; } +static inline bool +hikari_view_autoconf_resolve_public(struct hikari_view_autoconf *view_autoconf) +{ + assert(view_autoconf != NULL); + return view_autoconf->publicview; +} + static inline struct hikari_mark * hikari_view_autoconf_resolve_mark(struct hikari_view_autoconf *view_autoconf) { diff --git a/include/hikari/workspace.h b/include/hikari/workspace.h index b690f47..eb3fb02 100644 --- a/include/hikari/workspace.h +++ b/include/hikari/workspace.h @@ -139,6 +139,7 @@ WORKSPACE_ACTION(pin_view_to_sheet_next) WORKSPACE_ACTION(pin_view_to_sheet_prev) WORKSPACE_ACTION(toggle_view_invisible) WORKSPACE_ACTION(toggle_view_floating) +WORKSPACE_ACTION(toggle_view_public) WORKSPACE_ACTION(toggle_view_full_maximize) WORKSPACE_ACTION(toggle_view_vertical_maximize) WORKSPACE_ACTION(toggle_view_horizontal_maximize) diff --git a/share/man/man1/hikari.md b/share/man/man1/hikari.md index c8ff06c..ca69a0c 100644 --- a/share/man/man1/hikari.md +++ b/share/man/man1/hikari.md @@ -66,6 +66,12 @@ several states. **x** is the sheet the _view_ is a member of and **y** is the sheet that is currently borrowing the _view_. +* **public** + + *Public* views are also displayed on the lock screen, in this case they will + never accept input. Views that display sensible information should never be + marked as *public*. + Workspace --------- A _workspace_ is the set of views that are currently visible. Unlike in most @@ -164,7 +170,9 @@ General actions needs pam.conf(5) to be aware of its existence, therefore there must be a _hikari-unlocker_ service file in _pam.d_. - The lock screen displays all visible sheets that are a member of sheet 0. + The lock screen displays all views that are marked as **public** which allows + applications to provide information to the user when the computer is locked + (e.g. a clock). * **quit** diff --git a/src/configuration.c b/src/configuration.c index 0d04d33..aec43d3 100644 --- a/src/configuration.c +++ b/src/configuration.c @@ -867,6 +867,17 @@ parse_autoconf(struct hikari_configuration *configuration, } (*autoconf)->floating = floating; + } else if (!strcmp(key, "public")) { + bool publicview; + + if (!ucl_object_toboolean_safe(cur, &publicview)) { + fprintf(stderr, + "configuration error: expected boolean for \"views\" " + "\"public\"\n"); + goto done; + } + + (*autoconf)->publicview = publicview; } else { fprintf( stderr, "configuration error: unkown \"views\" key \"%s\"\n", key); @@ -1240,6 +1251,9 @@ parse_binding(struct hikari_configuration *configuration, } else if (!strcmp(str, "view-toggle-invisible")) { *action = hikari_server_toggle_view_invisible; *arg = NULL; + } else if (!strcmp(str, "view-toggle-public")) { + *action = hikari_server_toggle_view_public; + *arg = NULL; } else if (!strcmp(str, "view-raise")) { *action = hikari_server_raise_view; diff --git a/src/indicator.c b/src/indicator.c index 32d4880..0c3c110 100644 --- a/src/indicator.c +++ b/src/indicator.c @@ -105,10 +105,15 @@ hikari_indicator_update_sheet(struct hikari_indicator *indicator, { bool invisible = flags & hikari_view_invisible_flag; bool floating = flags & hikari_view_floating_flag; + bool publicview = flags & hikari_view_public_flag; char *output_name = sheet->workspace->output->wlr_output->name; int i = 0; - char *text = hikari_malloc(strlen(output_name) + 12); + char *text = hikari_malloc(strlen(output_name) + 13); + + if (publicview) { + text[i++] = '!'; + } if (floating) { text[i++] = '~'; diff --git a/src/lock_mode.c b/src/lock_mode.c index 046379f..cb4c4a7 100644 --- a/src/lock_mode.c +++ b/src/lock_mode.c @@ -256,10 +256,30 @@ render(struct hikari_output *output, struct hikari_render_data *render_data) struct hikari_lock_mode *mode = get_mode(); hikari_output_render_background(output, render_data, 0.1); - hikari_output_render_sticky(output, render_data); + hikari_output_render_visible_views(output, render_data); hikari_lock_indicator_render(mode->lock_indicator, render_data); } +static void +reset_visibility(void) +{ + struct hikari_output *output; + wl_list_for_each (output, &hikari_server.outputs, server_outputs) { + struct hikari_view *view; + wl_list_for_each (view, &output->views, output_views) { + if (hikari_view_is_forced(view)) { + hikari_view_unset_forced(view); + + if (hikari_view_is_hidden(view)) { + hikari_view_unset_hidden(view); + } else { + hikari_view_set_hidden(view); + } + } + } + } +} + static void cancel(void) { @@ -280,6 +300,8 @@ cancel(void) hikari_free(mode->lock_indicator); mode->lock_indicator = NULL; + reset_visibility(); + hikari_cursor_activate(&hikari_server.cursor); } @@ -319,6 +341,28 @@ hikari_lock_mode_fini(struct hikari_lock_mode *lock_mode) munlock(input_buffer, BUFFER_SIZE); } +static void +override_visibility(void) +{ + struct hikari_output *output; + wl_list_for_each (output, &hikari_server.outputs, server_outputs) { + struct hikari_view *view; + wl_list_for_each (view, &output->views, output_views) { + if (hikari_view_is_public(view)) { + if (hikari_view_is_hidden(view)) { + hikari_view_set_forced(view); + hikari_view_unset_hidden(view); + } + } else { + if (!hikari_view_is_hidden(view)) { + hikari_view_set_forced(view); + hikari_view_set_hidden(view); + } + } + } + } +} + void hikari_lock_mode_enter(void) { @@ -361,6 +405,7 @@ hikari_lock_mode_enter(void) clear_buffer(); start_unlocker(); + override_visibility(); mode->disable_outputs = wl_event_loop_add_timer( hikari_server.event_loop, disable_outputs_handler, NULL); diff --git a/src/output.c b/src/output.c index a03f3ea..6b52388 100644 --- a/src/output.c +++ b/src/output.c @@ -246,12 +246,11 @@ render_layer(struct wl_list *layers, struct hikari_render_data *render_data) #endif void -hikari_output_render_sticky( +hikari_output_render_visible_views( struct hikari_output *output, struct hikari_render_data *render_data) { struct hikari_view *view; - wl_list_for_each_reverse ( - view, &output->workspace->sheets[0].views, sheet_views) { + wl_list_for_each_reverse (view, &output->views, output_views) { if (!hikari_view_is_hidden(view)) { render_data->geometry = hikari_view_border_geometry(view); diff --git a/src/view.c b/src/view.c index 5e05214..3260eb0 100644 --- a/src/view.c +++ b/src/view.c @@ -886,6 +886,16 @@ hikari_view_toggle_full_maximize(struct hikari_view *view) hikari_view_set_dirty(view); } +void +hikari_view_toggle_public(struct hikari_view *view) +{ + if (hikari_view_is_public(view)) { + hikari_view_unset_public(view); + } else { + hikari_view_set_public(view); + } +} + static void queue_horizontal_maximize(struct hikari_view *view) { @@ -1666,7 +1676,7 @@ hikari_view_configure(struct hikari_view *view, struct hikari_output *output; struct wlr_box *geometry = &view->geometry; int x, y; - bool invisible, floating; + bool invisible, floating, publicview; set_app_id(view, app_id); @@ -1676,6 +1686,7 @@ hikari_view_configure(struct hikari_view *view, invisible = hikari_view_autoconf_resolve_invisible(view_autoconf); floating = hikari_view_autoconf_resolve_floating(view_autoconf); + publicview = hikari_view_autoconf_resolve_public(view_autoconf); hikari_view_autoconf_resolve_position(view_autoconf, view, &x, &y); } else { @@ -1684,6 +1695,7 @@ hikari_view_configure(struct hikari_view *view, invisible = false; floating = false; + publicview = false; x = hikari_server.cursor.wlr_cursor->x - output->geometry.x; y = hikari_server.cursor.wlr_cursor->y - output->geometry.y; @@ -1703,6 +1715,10 @@ hikari_view_configure(struct hikari_view *view, hikari_view_set_floating(view); } + if (publicview) { + hikari_view_set_public(view); + } + hikari_geometry_constrain_absolute(geometry, &output->usable_area, x, y); hikari_view_refresh_geometry(view, geometry); } diff --git a/src/view_autoconf.c b/src/view_autoconf.c index 0707bc9..293e169 100644 --- a/src/view_autoconf.c +++ b/src/view_autoconf.c @@ -18,6 +18,7 @@ hikari_view_autoconf_init(struct hikari_view_autoconf *view_autoconf) view_autoconf->focus = false; view_autoconf->invisible = false; view_autoconf->floating = false; + view_autoconf->publicview = false; hikari_position_config_init(&view_autoconf->position); } diff --git a/src/workspace.c b/src/workspace.c index 2b7ff29..efdfe26 100644 --- a/src/workspace.c +++ b/src/workspace.c @@ -776,6 +776,32 @@ hikari_workspace_toggle_view_invisible(struct hikari_workspace *workspace) } } +void +hikari_workspace_toggle_view_public(struct hikari_workspace *workspace) +{ + FOCUS_GUARD(workspace, focus_view); + + hikari_view_toggle_public(focus_view); + + struct hikari_output *output = workspace->output; + struct hikari_indicator *indicator = &hikari_server.indicator; + struct wlr_box *geometry = hikari_view_border_geometry(focus_view); + + if (hikari_server_is_indicating()) { + hikari_indicator_damage_sheet(indicator, output, geometry); + } + + hikari_indicator_update_sheet(indicator, + output, + focus_view->sheet, + focus_view->flags, + hikari_configuration->indicator_selected); + + if (hikari_server_is_indicating()) { + hikari_indicator_damage_sheet(indicator, output, geometry); + } +} + void hikari_workspace_toggle_view_floating(struct hikari_workspace *workspace) {