*/
#define MOVE_COUNTER_LIMIT 50
+#define PARENT_ACTIVATE_TIME 200
+#define PARENT_ACTIVATE_LIMIT 2
+
EINTERN void _e_main_cb_x_fatal(void *data EINA_UNUSED);
typedef struct _Frame_Extents Frame_Extents;
}
static void
+_e_comp_x_client_modal_setup(E_Client *ec)
+{
+ E_Comp_X_Client_Data *pcd;
+
+ ec->parent->modal = ec;
+ ec->parent->lock_close = 1;
+ pcd = _e_comp_x_client_data_get(ec->parent);
+ if (!pcd->lock_win)
+ {
+ eina_hash_add(clients_win_hash, &pcd->lock_win, ec->parent);
+ pcd->lock_win = ecore_x_window_input_new(e_client_util_pwin_get(ec->parent), 0, 0, ec->parent->w, ec->parent->h);
+ e_comp_ignore_win_add(E_PIXMAP_TYPE_X, pcd->lock_win);
+ ecore_x_window_show(pcd->lock_win);
+ ecore_x_icccm_name_class_set(pcd->lock_win, "comp_data->lock_win", "comp_data->lock_win");
+ }
+}
+
+static void
_e_comp_x_client_frame_update(E_Client *ec, int l, int r, int t, int b)
{
ecore_x_netwm_frame_size_set(e_client_util_win_get(ec), l, r, t, b);
(!ec->desk->visible))
e_client_urgent_set(ec, 1);
else
- e_client_activate(ec, EINA_TRUE);
+ {
+ /* some apps, eg. libreoffice, create "modal" windows which
+ * do not have the netwm modal state set. instead, attempting to
+ * focus the parent window results in the app immediately trying to
+ * activate the "modal" window, triggering an infinite loop.
+ *
+ * by treating this "modal" window as a genuine modal window,
+ * we (eventually) can ignore this type of bad behavior and
+ * give the application/user the expected behavior
+ */
+ if (ec->parent && (!ec->parent->modal) && (e_client_focused_get() == ec->parent) &&
+ (ev->time - focus_time < PARENT_ACTIVATE_TIME))
+ {
+ E_Comp_X_Client_Data *cd;
+
+ cd = _e_comp_x_client_data_get(ec);
+ if (cd)
+ {
+ cd->parent_activate_count++;
+ if (cd->parent_activate_count >= PARENT_ACTIVATE_LIMIT)
+ _e_comp_x_client_modal_setup(ec);
+ }
+ }
+ e_client_activate(ec, EINA_TRUE);
+ }
}
else
evas_object_raise(ec->frame);
{
evas_object_layer_set(ec->frame, ec->parent->layer);
if (ec->netwm.state.modal)
- {
- E_Comp_X_Client_Data *pcd;
-
- ec->parent->modal = ec;
- ec->parent->lock_close = 1;
- pcd = _e_comp_x_client_data_get(ec->parent);
- if (!pcd->lock_win)
- {
- eina_hash_add(clients_win_hash, &pcd->lock_win, ec->parent);
- pcd->lock_win = ecore_x_window_input_new(e_client_util_pwin_get(ec->parent), 0, 0, ec->parent->w, ec->parent->h);
- e_comp_ignore_win_add(E_PIXMAP_TYPE_X, pcd->lock_win);
- ecore_x_window_show(pcd->lock_win);
- ecore_x_icccm_name_class_set(pcd->lock_win, "comp_data->lock_win", "comp_data->lock_win");
- }
- }
+ _e_comp_x_client_modal_setup(ec);
if (e_config->focus_setting == E_FOCUS_NEW_DIALOG ||
(ec->parent->focused && (e_config->focus_setting == E_FOCUS_NEW_DIALOG_IF_OWNER_FOCUSED)))