-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adds events for wlmtk_window_t, and a signal for window state changes. (
#148) * Adds wlmtk_window_events_t.* * Wires up state-changed signal when (un)maximizing window. * Adds missing doxygen comment. * Clarify window state scope. * Wires up state_changed signal in fullscreen call. * Adds tests for window shading, and document behaviour on client-side-decoration. * Wires up state_change signal from window-shading.
- Loading branch information
Showing
2 changed files
with
143 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -77,6 +77,9 @@ struct _wlmtk_window_t { | |
/** Virtual method table. */ | ||
wlmtk_window_vmt_t vmt; | ||
|
||
/** Events for this window. */ | ||
wlmtk_window_events_t events; | ||
|
||
/** Box: In `super_bordered`, holds surface, title bar and resizebar. */ | ||
wlmtk_box_t box; | ||
|
||
|
@@ -263,6 +266,13 @@ void wlmtk_window_destroy(wlmtk_window_t *window_ptr) | |
free(window_ptr); | ||
} | ||
|
||
/* ------------------------------------------------------------------------- */ | ||
wlmtk_window_events_t *wlmtk_window_events( | ||
wlmtk_window_t *window_ptr) | ||
{ | ||
return &window_ptr->events; | ||
} | ||
|
||
/* ------------------------------------------------------------------------- */ | ||
wlmtk_element_t *wlmtk_window_element(wlmtk_window_t *window_ptr) | ||
{ | ||
|
@@ -315,8 +325,14 @@ void wlmtk_window_set_server_side_decorated( | |
bool decorated) | ||
{ | ||
if (window_ptr->server_side_decorated == decorated) return; | ||
|
||
if (!decorated && wlmtk_window_is_shaded(window_ptr)) { | ||
wlmtk_window_request_shaded(window_ptr, false); | ||
} | ||
|
||
window_ptr->server_side_decorated = decorated; | ||
_wlmtk_window_apply_decoration(window_ptr); | ||
|
||
} | ||
|
||
/* ------------------------------------------------------------------------- */ | ||
|
@@ -430,6 +446,7 @@ void wlmtk_window_commit_maximized( | |
if (window_ptr->maximized == maximized) return; | ||
|
||
window_ptr->maximized = maximized; | ||
wl_signal_emit(&window_ptr->events.state_changed, window_ptr); | ||
} | ||
|
||
/* ------------------------------------------------------------------------- */ | ||
|
@@ -494,6 +511,7 @@ void wlmtk_window_commit_fullscreen( | |
|
||
wlmtk_workspace_window_to_fullscreen( | ||
wlmtk_window_get_workspace(window_ptr), window_ptr, fullscreen); | ||
wl_signal_emit(&window_ptr->events.state_changed, window_ptr); | ||
} | ||
|
||
/* ------------------------------------------------------------------------- */ | ||
|
@@ -517,6 +535,7 @@ void wlmtk_window_request_shaded(wlmtk_window_t *window_ptr, bool shaded) | |
} | ||
|
||
window_ptr->shaded = shaded; | ||
wl_signal_emit(&window_ptr->events.state_changed, window_ptr); | ||
} | ||
|
||
/* ------------------------------------------------------------------------- */ | ||
|
@@ -725,6 +744,8 @@ bool _wlmtk_window_init( | |
|
||
wlmtk_box_add_element_front(&window_ptr->box, element_ptr); | ||
wlmtk_element_set_visible(element_ptr, true); | ||
|
||
wl_signal_init(&window_ptr->events.state_changed); | ||
return true; | ||
} | ||
|
||
|
@@ -1263,6 +1284,7 @@ static void test_server_side_decorated_properties(bs_test_t *test_ptr); | |
static void test_maximize(bs_test_t *test_ptr); | ||
static void test_fullscreen(bs_test_t *test_ptr); | ||
static void test_fullscreen_unmap(bs_test_t *test_ptr); | ||
static void test_shade(bs_test_t *test_ptr); | ||
static void test_fake(bs_test_t *test_ptr); | ||
|
||
const bs_test_case_t wlmtk_window_test_cases[] = { | ||
|
@@ -1276,10 +1298,18 @@ const bs_test_case_t wlmtk_window_test_cases[] = { | |
{ 1, "maximize", test_maximize }, | ||
{ 1, "fullscreen", test_fullscreen }, | ||
{ 1, "fullscreen_unmap", test_fullscreen_unmap }, | ||
{ 1, "shade", test_shade }, | ||
{ 1, "fake", test_fake }, | ||
{ 0, NULL, NULL } | ||
}; | ||
|
||
/** For testing: Tracks whether handle_state_change was called. */ | ||
static bool _wlmtk_window_test_handle_state_changed_called; | ||
|
||
static void _wlmtk_window_test_handle_state_changed( | ||
struct wl_listener *listener_ptr, | ||
void *data_ptr); | ||
|
||
/* ------------------------------------------------------------------------- */ | ||
/** Tests setup and teardown. */ | ||
void test_create_destroy(bs_test_t *test_ptr) | ||
|
@@ -1449,12 +1479,18 @@ void test_server_side_decorated_properties(bs_test_t *test_ptr) | |
void test_maximize(bs_test_t *test_ptr) | ||
{ | ||
struct wlr_box box; | ||
struct wl_listener listener; | ||
|
||
wlmtk_workspace_t *ws_ptr = wlmtk_workspace_create_for_test(1024, 768, 0); | ||
BS_TEST_VERIFY_NEQ_OR_RETURN(test_ptr, NULL, ws_ptr); | ||
wlmtk_fake_window_t *fw_ptr = wlmtk_fake_window_create(); | ||
BS_TEST_VERIFY_NEQ_OR_RETURN(test_ptr, NULL, fw_ptr); | ||
|
||
wlmtk_util_connect_listener_signal( | ||
&wlmtk_window_events(fw_ptr->window_ptr)->state_changed, | ||
&listener, | ||
_wlmtk_window_test_handle_state_changed); | ||
|
||
// Window must be mapped to get maximized: Need workspace dimensions. | ||
wlmtk_workspace_map_window(ws_ptr, fw_ptr->window_ptr); | ||
|
||
|
@@ -1485,16 +1521,20 @@ void test_maximize(bs_test_t *test_ptr) | |
BS_TEST_VERIFY_EQ(test_ptr, 100, box.height); | ||
|
||
// Maximize. | ||
_wlmtk_window_test_handle_state_changed_called = false; | ||
wlmtk_window_request_maximized(fw_ptr->window_ptr, true); | ||
BS_TEST_VERIFY_FALSE(test_ptr, wlmtk_window_is_maximized(fw_ptr->window_ptr)); | ||
wlmtk_fake_window_commit_size(fw_ptr); | ||
BS_TEST_VERIFY_FALSE(test_ptr, _wlmtk_window_test_handle_state_changed_called); | ||
wlmtk_window_commit_maximized(fw_ptr->window_ptr, true); | ||
box = wlmtk_window_get_position_and_size(fw_ptr->window_ptr); | ||
BS_TEST_VERIFY_EQ(test_ptr, 0, box.x); | ||
BS_TEST_VERIFY_EQ(test_ptr, 0, box.y); | ||
BS_TEST_VERIFY_EQ(test_ptr, 960, box.width); | ||
BS_TEST_VERIFY_EQ(test_ptr, 704, box.height); | ||
BS_TEST_VERIFY_TRUE(test_ptr, wlmtk_window_is_maximized(fw_ptr->window_ptr)); | ||
BS_TEST_VERIFY_TRUE(test_ptr, _wlmtk_window_test_handle_state_changed_called); | ||
_wlmtk_window_test_handle_state_changed_called = false; | ||
|
||
// A second commit: should not overwrite the organic dimension. | ||
wlmtk_fake_window_commit_size(fw_ptr); | ||
|
@@ -1503,20 +1543,23 @@ void test_maximize(bs_test_t *test_ptr) | |
wlmtk_window_request_maximized(fw_ptr->window_ptr, false); | ||
BS_TEST_VERIFY_TRUE(test_ptr, wlmtk_window_is_maximized(fw_ptr->window_ptr)); | ||
wlmtk_fake_window_commit_size(fw_ptr); | ||
BS_TEST_VERIFY_FALSE(test_ptr, _wlmtk_window_test_handle_state_changed_called); | ||
wlmtk_window_commit_maximized(fw_ptr->window_ptr, false); | ||
box = wlmtk_window_get_position_and_size(fw_ptr->window_ptr); | ||
BS_TEST_VERIFY_EQ(test_ptr, 50, box.x); | ||
BS_TEST_VERIFY_EQ(test_ptr, 30, box.y); | ||
BS_TEST_VERIFY_EQ(test_ptr, 200, box.width); | ||
BS_TEST_VERIFY_EQ(test_ptr, 100, box.height); | ||
BS_TEST_VERIFY_FALSE(test_ptr, wlmtk_window_is_maximized(fw_ptr->window_ptr)); | ||
BS_TEST_VERIFY_TRUE(test_ptr, _wlmtk_window_test_handle_state_changed_called); | ||
|
||
// TODO([email protected]): Define what should happen when a maximized | ||
// window is moved. Should it lose maximization? Should it not move? | ||
// Or just move on? | ||
// Window Maker keeps maximization, but it's ... odd. | ||
|
||
wlmtk_workspace_unmap_window(ws_ptr, fw_ptr->window_ptr); | ||
wlmtk_util_disconnect_listener(&listener); | ||
wlmtk_fake_window_destroy(fw_ptr); | ||
wlmtk_workspace_destroy(ws_ptr); | ||
} | ||
|
@@ -1526,12 +1569,18 @@ void test_maximize(bs_test_t *test_ptr) | |
void test_fullscreen(bs_test_t *test_ptr) | ||
{ | ||
struct wlr_box box; | ||
struct wl_listener listener; | ||
|
||
wlmtk_workspace_t *ws_ptr = wlmtk_workspace_create_for_test(1024, 768, 0); | ||
BS_TEST_VERIFY_NEQ_OR_RETURN(test_ptr, NULL, ws_ptr); | ||
wlmtk_fake_window_t *fw_ptr = wlmtk_fake_window_create(); | ||
BS_TEST_VERIFY_NEQ_OR_RETURN(test_ptr, NULL, fw_ptr); | ||
|
||
wlmtk_util_connect_listener_signal( | ||
&wlmtk_window_events(fw_ptr->window_ptr)->state_changed, | ||
&listener, | ||
_wlmtk_window_test_handle_state_changed); | ||
|
||
wlmtk_window_set_server_side_decorated(fw_ptr->window_ptr, true); | ||
wlmtk_workspace_map_window(ws_ptr, fw_ptr->window_ptr); | ||
|
||
|
@@ -1552,11 +1601,13 @@ void test_fullscreen(bs_test_t *test_ptr) | |
BS_TEST_VERIFY_FALSE(test_ptr, fw_ptr->window_ptr->inorganic_sizing); | ||
|
||
// Request fullscreen. Does not take immediate effect. | ||
_wlmtk_window_test_handle_state_changed_called = false; | ||
wlmtk_window_request_fullscreen(fw_ptr->window_ptr, true); | ||
BS_TEST_VERIFY_FALSE(test_ptr, wlmtk_window_is_fullscreen(fw_ptr->window_ptr)); | ||
BS_TEST_VERIFY_TRUE( | ||
test_ptr, | ||
wlmtk_titlebar_is_activated(fw_ptr->window_ptr->titlebar_ptr)); | ||
BS_TEST_VERIFY_FALSE(test_ptr, _wlmtk_window_test_handle_state_changed_called); | ||
|
||
// Only after "commit", it will take effect. | ||
wlmtk_fake_window_commit_size(fw_ptr); | ||
|
@@ -1567,6 +1618,8 @@ void test_fullscreen(bs_test_t *test_ptr) | |
BS_TEST_VERIFY_EQ(test_ptr, 0, box.y); | ||
BS_TEST_VERIFY_EQ(test_ptr, 1024, box.width); | ||
BS_TEST_VERIFY_EQ(test_ptr, 768, box.height); | ||
BS_TEST_VERIFY_TRUE(test_ptr, _wlmtk_window_test_handle_state_changed_called); | ||
_wlmtk_window_test_handle_state_changed_called = false; | ||
|
||
BS_TEST_VERIFY_TRUE(test_ptr, fw_ptr->fake_content_ptr->activated); | ||
BS_TEST_VERIFY_EQ( | ||
|
@@ -1581,6 +1634,7 @@ void test_fullscreen(bs_test_t *test_ptr) | |
// Request to end fullscreen. Not taking immediate effect. | ||
wlmtk_window_request_fullscreen(fw_ptr->window_ptr, false); | ||
BS_TEST_VERIFY_TRUE(test_ptr, wlmtk_window_is_fullscreen(fw_ptr->window_ptr)); | ||
BS_TEST_VERIFY_FALSE(test_ptr, _wlmtk_window_test_handle_state_changed_called); | ||
|
||
// Takes effect after commit. We'll want the same position as before. | ||
wlmtk_fake_window_commit_size(fw_ptr); | ||
|
@@ -1600,14 +1654,16 @@ void test_fullscreen(bs_test_t *test_ptr) | |
test_ptr, | ||
fw_ptr->window_ptr, | ||
wlmtk_workspace_get_activated_window(ws_ptr)); | ||
BS_TEST_VERIFY_TRUE(test_ptr, _wlmtk_window_test_handle_state_changed_called); | ||
_wlmtk_window_test_handle_state_changed_called = false; | ||
|
||
BS_TEST_VERIFY_TRUE(test_ptr, fw_ptr->window_ptr->server_side_decorated); | ||
BS_TEST_VERIFY_NEQ(test_ptr, NULL, fw_ptr->window_ptr->titlebar_ptr); | ||
BS_TEST_VERIFY_NEQ(test_ptr, NULL, fw_ptr->window_ptr->resizebar_ptr); | ||
|
||
wlmtk_workspace_unmap_window(ws_ptr, fw_ptr->window_ptr); | ||
wlmtk_util_disconnect_listener(&listener); | ||
wlmtk_fake_window_destroy(fw_ptr); | ||
|
||
wlmtk_workspace_destroy(ws_ptr); | ||
} | ||
|
||
|
@@ -1656,6 +1712,59 @@ void test_fullscreen_unmap(bs_test_t *test_ptr) | |
wlmtk_workspace_destroy(ws_ptr); | ||
} | ||
|
||
/* ------------------------------------------------------------------------- */ | ||
/** Verifies that window shading hides the element and raises signal. */ | ||
void test_shade(bs_test_t *test_ptr) | ||
{ | ||
struct wl_listener listener; | ||
|
||
wlmtk_fake_window_t *fw_ptr = wlmtk_fake_window_create(); | ||
BS_TEST_VERIFY_NEQ_OR_RETURN(test_ptr, NULL, fw_ptr); | ||
wlmtk_util_connect_listener_signal( | ||
&wlmtk_window_events(fw_ptr->window_ptr)->state_changed, | ||
&listener, | ||
_wlmtk_window_test_handle_state_changed); | ||
|
||
BS_TEST_VERIFY_FALSE(test_ptr, wlmtk_window_is_shaded(fw_ptr->window_ptr)); | ||
_wlmtk_window_test_handle_state_changed_called = false; | ||
|
||
// Shading only works on server-side-decorated windows. | ||
wlmtk_window_set_server_side_decorated(fw_ptr->window_ptr, true); | ||
|
||
wlmtk_window_request_shaded(fw_ptr->window_ptr, true); | ||
BS_TEST_VERIFY_TRUE(test_ptr, wlmtk_window_is_shaded(fw_ptr->window_ptr)); | ||
BS_TEST_VERIFY_FALSE( | ||
test_ptr, | ||
wlmtk_content_element(&fw_ptr->fake_content_ptr->content)->visible); | ||
BS_TEST_VERIFY_TRUE(test_ptr, _wlmtk_window_test_handle_state_changed_called); | ||
_wlmtk_window_test_handle_state_changed_called = false; | ||
|
||
wlmtk_window_request_shaded(fw_ptr->window_ptr, false); | ||
BS_TEST_VERIFY_FALSE(test_ptr, wlmtk_window_is_shaded(fw_ptr->window_ptr)); | ||
BS_TEST_VERIFY_TRUE(test_ptr, _wlmtk_window_test_handle_state_changed_called); | ||
_wlmtk_window_test_handle_state_changed_called = false; | ||
|
||
// Shading not supported on client-side decoration. Must be disabled. | ||
wlmtk_window_request_shaded(fw_ptr->window_ptr, true); | ||
BS_TEST_VERIFY_TRUE(test_ptr, wlmtk_window_is_shaded(fw_ptr->window_ptr)); | ||
BS_TEST_VERIFY_TRUE(test_ptr, _wlmtk_window_test_handle_state_changed_called); | ||
_wlmtk_window_test_handle_state_changed_called = false; | ||
|
||
wlmtk_window_set_server_side_decorated(fw_ptr->window_ptr, false); | ||
BS_TEST_VERIFY_FALSE(test_ptr, wlmtk_window_is_shaded(fw_ptr->window_ptr)); | ||
BS_TEST_VERIFY_TRUE(test_ptr, _wlmtk_window_test_handle_state_changed_called); | ||
_wlmtk_window_test_handle_state_changed_called = false; | ||
|
||
// Verify that 'shading' on client decorations does not do anything. | ||
wlmtk_window_set_server_side_decorated(fw_ptr->window_ptr, false); | ||
wlmtk_window_request_shaded(fw_ptr->window_ptr, true); | ||
BS_TEST_VERIFY_FALSE(test_ptr, wlmtk_window_is_shaded(fw_ptr->window_ptr)); | ||
BS_TEST_VERIFY_FALSE(test_ptr, _wlmtk_window_test_handle_state_changed_called); | ||
|
||
wlmtk_util_disconnect_listener(&listener); | ||
wlmtk_fake_window_destroy(fw_ptr); | ||
} | ||
|
||
/* ------------------------------------------------------------------------- */ | ||
/** Tests fake window ctor and dtor. */ | ||
void test_fake(bs_test_t *test_ptr) | ||
|
@@ -1665,4 +1774,13 @@ void test_fake(bs_test_t *test_ptr) | |
wlmtk_fake_window_destroy(fake_window_ptr); | ||
} | ||
|
||
/* ------------------------------------------------------------------------- */ | ||
/** Reports a state change. */ | ||
void _wlmtk_window_test_handle_state_changed( | ||
__UNUSED__ struct wl_listener *listener_ptr, | ||
__UNUSED__ void *data_ptr) | ||
{ | ||
_wlmtk_window_test_handle_state_changed_called = true; | ||
} | ||
|
||
/* == End of window.c ====================================================== */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters