mirror of
https://github.com/labwc/labwc.git
synced 2026-04-09 08:21:18 -04:00
view: Add simple window animations
This commit is contained in:
parent
97ce4131bb
commit
21e93e480a
3 changed files with 93 additions and 0 deletions
|
|
@ -201,6 +201,9 @@ struct view {
|
||||||
struct wlr_scene_tree *scene_tree;
|
struct wlr_scene_tree *scene_tree;
|
||||||
struct wlr_scene_tree *content_tree;
|
struct wlr_scene_tree *content_tree;
|
||||||
|
|
||||||
|
struct wlr_scene_buffer *animation;
|
||||||
|
uint64_t animation_start_time;
|
||||||
|
|
||||||
bool mapped;
|
bool mapped;
|
||||||
bool been_mapped;
|
bool been_mapped;
|
||||||
bool ssd_enabled;
|
bool ssd_enabled;
|
||||||
|
|
@ -278,6 +281,7 @@ struct view {
|
||||||
struct wl_listener request_maximize;
|
struct wl_listener request_maximize;
|
||||||
struct wl_listener request_fullscreen;
|
struct wl_listener request_fullscreen;
|
||||||
struct wl_listener set_title;
|
struct wl_listener set_title;
|
||||||
|
struct wl_listener output_commit;
|
||||||
|
|
||||||
struct foreign_toplevel *foreign_toplevel;
|
struct foreign_toplevel *foreign_toplevel;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,92 @@
|
||||||
/* view-impl-common.c: common code for shell view->impl functions */
|
/* view-impl-common.c: common code for shell view->impl functions */
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <wlr/types/wlr_output.h>
|
||||||
#include "foreign-toplevel.h"
|
#include "foreign-toplevel.h"
|
||||||
#include "labwc.h"
|
#include "labwc.h"
|
||||||
#include "view.h"
|
#include "view.h"
|
||||||
#include "view-impl-common.h"
|
#include "view-impl-common.h"
|
||||||
#include "window-rules.h"
|
#include "window-rules.h"
|
||||||
|
#include "workspaces.h"
|
||||||
|
|
||||||
|
static inline uint64_t
|
||||||
|
timespec_to_us(const struct timespec *ts)
|
||||||
|
{
|
||||||
|
return (uint64_t)ts->tv_sec * UINT64_C(1000000) +
|
||||||
|
(uint64_t)ts->tv_nsec / UINT64_C(1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint64_t
|
||||||
|
gettime_us(void)
|
||||||
|
{
|
||||||
|
struct timespec ts = { 0 };
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||||
|
return timespec_to_us(&ts);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
adjust_scaled_position(struct view *view, double scale)
|
||||||
|
{
|
||||||
|
int x = view->current.x;
|
||||||
|
int y = view->current.y;
|
||||||
|
double width = view->current.width;
|
||||||
|
double height = view->current.height;
|
||||||
|
|
||||||
|
int x_pos = x + round(width * (1.0 - scale) / 2.0);
|
||||||
|
int y_pos = y + round(height * (1.0 - scale) / 2.0);
|
||||||
|
|
||||||
|
wlr_scene_node_set_position(&view->scene_tree->node, x_pos, y_pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
view_run_animation(struct view *view, uint64_t now)
|
||||||
|
{
|
||||||
|
uint64_t elapsed_us = now - view->animation_start_time;
|
||||||
|
double t = (double)elapsed_us * 1e-6;
|
||||||
|
double duration = 0.2; // s
|
||||||
|
double scale = fmax(t / duration, 0.01);
|
||||||
|
|
||||||
|
if (scale < 1.0) {
|
||||||
|
wlr_scene_node_set_scale(&view->scene_tree->node, scale);
|
||||||
|
adjust_scaled_position(view, scale);
|
||||||
|
} else {
|
||||||
|
int x = view->current.x;
|
||||||
|
int y = view->current.y;
|
||||||
|
wlr_scene_node_set_position(&view->scene_tree->node, x, y);
|
||||||
|
wlr_scene_node_set_scale(&view->scene_tree->node, 1.0);
|
||||||
|
wl_list_remove(&view->output_commit.link);
|
||||||
|
wl_list_init(&view->output_commit.link);
|
||||||
|
view->animation_start_time = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
handle_output_commit(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
struct wlr_output_event_commit *event = data;
|
||||||
|
struct view *view = wl_container_of(listener, view, output_commit);
|
||||||
|
|
||||||
|
if (!(event->state->committed & WLR_OUTPUT_STATE_BUFFER)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
view_run_animation(view, gettime_us());
|
||||||
|
|
||||||
|
wlr_output_update_needs_frame(event->output);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
view_start_animation(struct view *view)
|
||||||
|
{
|
||||||
|
view->output_commit.notify = handle_output_commit;
|
||||||
|
wl_signal_add(&view->output->wlr_output->events.commit, &view->output_commit);
|
||||||
|
|
||||||
|
uint64_t now = gettime_us();
|
||||||
|
view->animation_start_time = now;
|
||||||
|
view_run_animation(view, now);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
view_impl_map(struct view *view)
|
view_impl_map(struct view *view)
|
||||||
|
|
@ -16,6 +97,7 @@ view_impl_map(struct view *view)
|
||||||
view_update_app_id(view);
|
view_update_app_id(view);
|
||||||
if (!view->been_mapped) {
|
if (!view->been_mapped) {
|
||||||
window_rules_apply(view, LAB_WINDOW_RULE_EVENT_ON_FIRST_MAP);
|
window_rules_apply(view, LAB_WINDOW_RULE_EVENT_ON_FIRST_MAP);
|
||||||
|
view_start_animation(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -104,4 +186,8 @@ view_impl_apply_geometry(struct view *view, int w, int h)
|
||||||
if (!wlr_box_equal(current, &old)) {
|
if (!wlr_box_equal(current, &old)) {
|
||||||
view_moved(view);
|
view_moved(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (view->animation_start_time) {
|
||||||
|
adjust_scaled_position(view, view->scene_tree->node.scale);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2558,6 +2558,9 @@ view_destroy(struct view *view)
|
||||||
wl_list_remove(&view->set_title.link);
|
wl_list_remove(&view->set_title.link);
|
||||||
wl_list_remove(&view->destroy.link);
|
wl_list_remove(&view->destroy.link);
|
||||||
|
|
||||||
|
wl_list_remove(&view->output_commit.link);
|
||||||
|
wl_list_init(&view->output_commit.link);
|
||||||
|
|
||||||
if (view->foreign_toplevel) {
|
if (view->foreign_toplevel) {
|
||||||
foreign_toplevel_destroy(view->foreign_toplevel);
|
foreign_toplevel_destroy(view->foreign_toplevel);
|
||||||
view->foreign_toplevel = NULL;
|
view->foreign_toplevel = NULL;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue