aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--legacy/elementary/src/lib/elm_general.eot3
-rw-r--r--legacy/elementary/src/lib/elm_win.c64
-rw-r--r--legacy/elementary/src/lib/elm_win.eo28
-rw-r--r--legacy/elementary/src/lib/elm_win.h2
-rw-r--r--legacy/elementary/src/tests/elm_test_win.c131
5 files changed, 219 insertions, 9 deletions
diff --git a/legacy/elementary/src/lib/elm_general.eot b/legacy/elementary/src/lib/elm_general.eot
index b492041b9e..9b7fe19b93 100644
--- a/legacy/elementary/src/lib/elm_general.eot
+++ b/legacy/elementary/src/lib/elm_general.eot
@@ -26,7 +26,8 @@ enum Elm.Policy.Quit
{
[[Possible values for the #ELM_POLICY_QUIT policy]]
none = 0, [[never quit the application automatically]]
- last_window_closed [[quit when the application's last window is closed]]
+ last_window_closed, [[quit when the application's last window is closed]]
+ last_window_hidden [[quit when the application's last window is hidden @since 1.14]]
}
enum Elm.Policy.Exit
diff --git a/legacy/elementary/src/lib/elm_win.c b/legacy/elementary/src/lib/elm_win.c
index e41113a7df..0b68128e5f 100644
--- a/legacy/elementary/src/lib/elm_win.c
+++ b/legacy/elementary/src/lib/elm_win.c
@@ -212,6 +212,7 @@ struct _Elm_Win_Data
Eina_Bool modal : 1;
Eina_Bool demand_attention : 1;
Eina_Bool autodel : 1;
+ Eina_Bool autohide : 1;
Eina_Bool constrain : 1;
Eina_Bool resizing : 1;
Eina_Bool iconified : 1;
@@ -503,6 +504,41 @@ _elm_win_state_eval(void *data EINA_UNUSED)
return EINA_FALSE;
}
+static Eina_Bool
+_elm_win_policy_quit_triggered(Eo* triggering_obj)
+{
+ if ((!_elm_win_list) &&
+ (elm_policy_get(ELM_POLICY_QUIT) == ELM_POLICY_QUIT_LAST_WINDOW_CLOSED))
+ {
+ return EINA_TRUE;
+ }
+
+ if (elm_policy_get(ELM_POLICY_QUIT) == ELM_POLICY_QUIT_LAST_WINDOW_HIDDEN)
+ {
+ Eina_List *l;
+ Evas_Object *win;
+
+ EINA_LIST_FOREACH(_elm_win_list, l, win)
+ if (win != triggering_obj && evas_object_visible_get(win) == EINA_TRUE)
+ {
+ return EINA_FALSE;
+ }
+ return EINA_TRUE;
+ }
+
+ return EINA_FALSE;
+}
+
+static void
+_elm_win_flush_cache_and_exit(Eo *obj)
+{
+ edje_file_cache_flush();
+ edje_collection_cache_flush();
+ evas_image_cache_flush(evas_object_evas_get(obj));
+ evas_font_cache_flush(evas_object_evas_get(obj));
+ elm_exit();
+}
+
static void
_elm_win_state_eval_queue(void)
{
@@ -1544,6 +1580,9 @@ _elm_win_evas_object_smart_hide(Eo *obj, Elm_Win_Data *sd)
}
if (_elm_config->atspi_mode)
eo_do(obj, eo_event_callback_call(ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_DESTROYED, NULL));
+
+ if (_elm_win_policy_quit_triggered(obj))
+ _elm_win_flush_cache_and_exit(obj);
}
static void
@@ -1866,14 +1905,9 @@ _elm_win_evas_object_smart_del(Eo *obj, Elm_Win_Data *sd)
eo_do_super(obj, MY_CLASS, evas_obj_smart_del());
- if ((!_elm_win_list) &&
- (elm_policy_get(ELM_POLICY_QUIT) == ELM_POLICY_QUIT_LAST_WINDOW_CLOSED))
+ if (_elm_win_policy_quit_triggered(obj))
{
- edje_file_cache_flush();
- edje_collection_cache_flush();
- evas_image_cache_flush(evas_object_evas_get(obj));
- evas_font_cache_flush(evas_object_evas_get(obj));
- elm_exit();
+ _elm_win_flush_cache_and_exit(obj);
}
if (_elm_config->atspi_mode)
@@ -1992,6 +2026,8 @@ _elm_win_delete_request(Ecore_Evas *ee)
sd->autodel_clear = &autodel;
evas_object_ref(obj);
evas_object_smart_callback_call(obj, SIG_DELETE_REQUEST, NULL);
+ if (sd->autohide)
+ evas_object_hide(obj);
// FIXME: if above callback deletes - then the below will be invalid
if (_elm_config->atspi_mode)
eo_do(obj, eo_event_callback_call(ELM_INTERFACE_ATSPI_WINDOW_EVENT_WINDOW_DESTROYED, NULL));
@@ -2795,6 +2831,8 @@ _elm_win_frame_cb_close(void *data,
sd->autodel_clear = &autodel;
evas_object_ref(win);
evas_object_smart_callback_call(win, SIG_DELETE_REQUEST, NULL);
+ if (sd->autohide)
+ evas_object_hide(win);
// FIXME: if above callback deletes - then the below will be invalid
if (autodel) evas_object_del(win);
else sd->autodel_clear = NULL;
@@ -3998,6 +4036,18 @@ _elm_win_autodel_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
}
EOLIAN static void
+_elm_win_autohide_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, Eina_Bool autohide)
+{
+ sd->autohide = autohide;
+}
+
+EOLIAN static Eina_Bool
+_elm_win_autohide_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
+{
+ return sd->autohide;
+}
+
+EOLIAN static void
_elm_win_activate(Eo *obj EINA_UNUSED, Elm_Win_Data *sd)
{
TRAP(sd, activate);
diff --git a/legacy/elementary/src/lib/elm_win.eo b/legacy/elementary/src/lib/elm_win.eo
index 6bfa43f58e..eb39c84f25 100644
--- a/legacy/elementary/src/lib/elm_win.eo
+++ b/legacy/elementary/src/lib/elm_win.eo
@@ -211,6 +211,34 @@ class Elm.Win (Elm.Widget, Elm_Interface_Atspi_Window,
closed */
}
}
+ @property autohide {
+ [[Window's autohide state.
+
+ This property works similarly to @c autodel, automatically handling
+ "delete,request" signals when set to @c EINA_TRUE, with the difference
+ that it will hide the window, instead of destroying it.
+
+ It is specially designed to work together with @c ELM_POLICY_QUIT_LAST_WINDOW_HIDDEN
+ which allows exiting Elementary's main loop when all the windows
+ are hidden.
+
+ @see elm_win_autodel_set()
+
+ @note @c autodel and @c autohide are not mutually exclusive. The window
+ will be deleted if both are set to @c EINA_TRUE.
+
+ @ingroup Win
+ ]]
+
+ set {
+ }
+ get {
+ }
+ values {
+ autohide: bool; /*@ If true, the window will automatically hide itself when
+ closed */
+ }
+ }
@property override {
set {
/*@
diff --git a/legacy/elementary/src/lib/elm_win.h b/legacy/elementary/src/lib/elm_win.h
index 3b43b18111..b94f6f9ad3 100644
--- a/legacy/elementary/src/lib/elm_win.h
+++ b/legacy/elementary/src/lib/elm_win.h
@@ -69,7 +69,7 @@
* Signals that you can add callbacks for are:
*
* @li "delete,request": the user requested to close the window. See
- * elm_win_autodel_set().
+ * elm_win_autodel_set() and elm_win_autohide_set().
* @li "focus,in": window got focus (deprecated. use "focused" instead.)
* @li "focus,out": window lost focus (deprecated. use "unfocused" instead.)
* @li "moved": window that holds the canvas was moved
diff --git a/legacy/elementary/src/tests/elm_test_win.c b/legacy/elementary/src/tests/elm_test_win.c
index 702d2c735e..6fc07ef81e 100644
--- a/legacy/elementary/src/tests/elm_test_win.c
+++ b/legacy/elementary/src/tests/elm_test_win.c
@@ -5,8 +5,58 @@
#define ELM_INTERFACE_ATSPI_ACCESSIBLE_PROTECTED
#define ELM_INTERFACE_ATSPI_COMPONENT_PROTECTED
#include <Elementary.h>
+#include <Ecore_X.h>
#include "elm_suite.h"
+static const double _timeout1 = 0.01;
+static const double _timeout2 = 0.02;
+static const double _timeout_fail = 2.0;
+
+static void
+_do_delete_request(Eo *win)
+{
+#ifdef HAVE_ELEMENTARY_X
+ Ecore_X_Window xwin;
+ eo_do(win, xwin = elm_obj_win_xwindow_get());
+ ecore_x_window_delete_request_send(xwin);
+#endif
+
+ (void) win;
+}
+
+
+static Eina_Bool
+_timer_delete_request_cb(void *data)
+{
+ Eo *win = (Eo*) data;
+ _do_delete_request(win);
+ return ECORE_CALLBACK_PASS_ON;
+}
+
+static Eina_Bool
+_timer_hide_window_cb(void *data)
+{
+ Eo *win = (Eo*) data;
+ eo_do(win, efl_gfx_visible_set(EINA_FALSE));
+ return ECORE_CALLBACK_PASS_ON;
+}
+
+static Eina_Bool
+_timer_exit_cb(void *data EINA_UNUSED)
+{
+ elm_exit();
+ return ECORE_CALLBACK_PASS_ON;
+}
+
+static Eina_Bool
+_timer_fail_flag_cb(void *data)
+{
+ Eina_Bool *fail_flag = (Eina_Bool*) data;
+ *fail_flag = EINA_TRUE;
+ elm_exit();
+ return ECORE_CALLBACK_PASS_ON;
+}
+
START_TEST (elm_atspi_role_get)
{
@@ -66,9 +116,90 @@ START_TEST (elm_atspi_component_size)
}
END_TEST
+START_TEST (elm_win_autohide)
+{
+ elm_init(0, NULL);
+
+ Eo *win = elm_win_add(NULL, "win", ELM_WIN_BASIC);
+ eo_do(win, elm_obj_win_autohide_set(EINA_TRUE));
+ eo_do(win, efl_gfx_visible_set(EINA_TRUE));
+
+ Eina_Bool fail_flag = EINA_FALSE;
+ ecore_timer_add(_timeout1, _timer_delete_request_cb, win);
+ ecore_timer_add(_timeout2, _timer_exit_cb, &fail_flag);
+
+ elm_run();
+
+ Eina_Bool visible;
+ eo_do(win, visible = efl_gfx_visible_get());
+
+ ck_assert(visible == EINA_FALSE);
+
+ elm_shutdown();
+}
+END_TEST
+
+START_TEST (elm_win_policy_quit_last_window_hidden)
+{
+ elm_init(0, NULL);
+
+ elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_HIDDEN);
+
+ Eo *win = elm_win_add(NULL, "win", ELM_WIN_BASIC);
+ eo_do(win, efl_gfx_visible_set(EINA_TRUE));
+
+ Eina_Bool fail_flag = EINA_FALSE;
+ ecore_timer_add(_timeout1, _timer_hide_window_cb, win);
+ ecore_timer_add(_timeout_fail, _timer_fail_flag_cb, &fail_flag);
+
+ elm_run();
+
+ Eina_Bool visible;
+ eo_do(win, visible = efl_gfx_visible_get());
+
+ ck_assert(fail_flag == EINA_FALSE);
+ ck_assert(eo_ref_get(win) >= 1);
+ ck_assert(visible == EINA_FALSE);
+
+ elm_shutdown();
+}
+END_TEST
+
+START_TEST (elm_win_autohide_and_policy_quit_last_window_hidden)
+{
+ elm_init(0, NULL);
+
+ elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_HIDDEN);
+
+ Eo *win = elm_win_add(NULL, "win", ELM_WIN_BASIC);
+ eo_do(win, elm_obj_win_autohide_set(EINA_TRUE));
+ eo_do(win, efl_gfx_visible_set(EINA_TRUE));
+
+ Eina_Bool fail_flag = EINA_FALSE;
+ ecore_timer_add(_timeout1, _timer_delete_request_cb, win);
+ ecore_timer_add(_timeout_fail, _timer_fail_flag_cb, &fail_flag);
+
+ elm_run();
+
+ Eina_Bool visible;
+ eo_do(win, visible = efl_gfx_visible_get());
+
+ ck_assert(fail_flag == EINA_FALSE);
+ ck_assert(eo_ref_get(win) >= 1);
+ ck_assert(visible == EINA_FALSE);
+
+ elm_shutdown();
+}
+END_TEST
+
void elm_test_win(TCase *tc)
{
tcase_add_test(tc, elm_atspi_role_get);
tcase_add_test(tc, elm_atspi_component_position);
tcase_add_test(tc, elm_atspi_component_size);
+ tcase_add_test(tc, elm_win_policy_quit_last_window_hidden);
+#ifdef HAVE_ELEMENTARY_X
+ tcase_add_test(tc, elm_win_autohide);
+ tcase_add_test(tc, elm_win_autohide_and_policy_quit_last_window_hidden);
+#endif
}