1999-10-04 15:06:00 -07:00
|
|
|
/*
|
2007-01-13 11:14:29 -08:00
|
|
|
* Copyright (C) 2000-2007 Carsten Haitzler, Geoff Harrison and various contributors
|
2010-01-14 10:52:50 -08:00
|
|
|
* Copyright (C) 2004-2010 Kim Woelders
|
2000-04-05 16:22:56 -07:00
|
|
|
*
|
1999-10-04 15:06:00 -07:00
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
* of this software and associated documentation files (the "Software"), to
|
|
|
|
* deal in the Software without restriction, including without limitation the
|
|
|
|
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
|
|
* sell copies of the Software, and to permit persons to whom the Software is
|
|
|
|
* furnished to do so, subject to the following conditions:
|
2000-04-05 16:22:56 -07:00
|
|
|
*
|
1999-10-04 15:06:00 -07:00
|
|
|
* The above copyright notice and this permission notice shall be included in
|
|
|
|
* all copies of the Software, its documentation and marketing & publicity
|
|
|
|
* materials, and acknowledgment shall be given in the documentation, materials
|
|
|
|
* and software packages that this Software was used.
|
2000-04-05 16:22:56 -07:00
|
|
|
*
|
1999-10-04 15:06:00 -07:00
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
|
|
* THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
|
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
|
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
*/
|
1999-08-17 15:56:46 -07:00
|
|
|
#include "E.h"
|
2006-11-19 13:55:52 -08:00
|
|
|
#include "cursors.h"
|
2005-09-04 00:27:20 -07:00
|
|
|
#include "desktops.h" /* FIXME - Should not be here */
|
2005-10-29 01:48:40 -07:00
|
|
|
#include "dialog.h"
|
2005-07-16 09:57:45 -07:00
|
|
|
#include "emodule.h"
|
|
|
|
#include "ewins.h"
|
2006-11-19 13:55:52 -08:00
|
|
|
#include "focus.h"
|
|
|
|
#include "grabs.h"
|
2005-10-27 16:18:35 -07:00
|
|
|
#include "hints.h"
|
2010-03-20 03:41:12 -07:00
|
|
|
#include "icons.h"
|
2007-01-16 17:10:44 -08:00
|
|
|
#include "settings.h"
|
2006-04-16 06:27:38 -07:00
|
|
|
#include "timers.h"
|
2005-07-16 09:57:45 -07:00
|
|
|
#include "xwin.h"
|
1999-08-17 15:56:46 -07:00
|
|
|
|
2005-06-30 05:03:38 -07:00
|
|
|
#define EwinListFocusRaise(ewin) EobjListFocusRaise(EoObj(ewin))
|
|
|
|
|
2005-07-22 11:56:02 -07:00
|
|
|
static char focus_inhibit = 1;
|
|
|
|
static char focus_is_set = 0;
|
2007-07-11 02:30:58 -07:00
|
|
|
static char click_pending_update_grabs = 0;
|
2005-05-29 11:58:38 -07:00
|
|
|
static int focus_pending_why = 0;
|
|
|
|
static EWin *focus_pending_ewin = NULL;
|
|
|
|
static EWin *focus_pending_new = NULL;
|
2008-08-07 16:31:36 -07:00
|
|
|
static EWin *focus_pending_raise = NULL;
|
2008-05-24 11:13:17 -07:00
|
|
|
static Timer *focus_timer_autoraise = NULL;
|
2010-03-15 15:19:03 -07:00
|
|
|
static int focus_request = 0;
|
2003-06-11 13:05:59 -07:00
|
|
|
|
2005-05-29 03:20:25 -07:00
|
|
|
void
|
|
|
|
FocusEnable(int on)
|
|
|
|
{
|
|
|
|
if (on)
|
|
|
|
{
|
|
|
|
if (focus_inhibit > 0)
|
|
|
|
focus_inhibit--;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
focus_inhibit++;
|
|
|
|
}
|
|
|
|
|
2006-11-19 13:55:52 -08:00
|
|
|
if (EDebug(EDBUG_TYPE_FOCUS))
|
2005-05-29 03:20:25 -07:00
|
|
|
Eprintf("FocusEnable inhibit=%d\n", focus_inhibit);
|
|
|
|
}
|
|
|
|
|
2004-02-24 15:19:03 -08:00
|
|
|
/*
|
|
|
|
* Return !0 if it is OK to focus ewin.
|
|
|
|
*/
|
|
|
|
static int
|
2005-05-29 11:58:38 -07:00
|
|
|
FocusEwinValid(EWin * ewin, int want_on_screen, int click, int want_visible)
|
2004-02-24 15:19:03 -08:00
|
|
|
{
|
2004-07-17 01:55:34 -07:00
|
|
|
if (!ewin)
|
|
|
|
return 0;
|
|
|
|
|
2005-05-29 11:58:38 -07:00
|
|
|
#if 0
|
2005-11-12 07:17:44 -08:00
|
|
|
Eprintf("FocusEwinValid %#lx %s: st=%d sh=%d inh=%d cl=%d(%d) vis=%d(%d)\n",
|
2006-11-26 03:30:59 -08:00
|
|
|
EwinGetClientXwin(ewin), EwinGetTitle(ewin),
|
2005-11-12 07:17:44 -08:00
|
|
|
ewin->state.state, EoIsShown(ewin), ewin->state.inhibit_focus,
|
|
|
|
click, ewin->props.focusclick, want_visible, ewin->state.visibility);
|
2005-05-29 11:58:38 -07:00
|
|
|
#endif
|
|
|
|
|
2005-07-08 09:48:19 -07:00
|
|
|
if (ewin->state.inhibit_focus)
|
2004-02-24 15:19:03 -08:00
|
|
|
return 0;
|
|
|
|
|
2005-05-12 15:38:01 -07:00
|
|
|
if (!EwinIsMapped(ewin) || !EoIsShown(ewin))
|
2004-02-26 11:33:21 -08:00
|
|
|
return 0;
|
|
|
|
|
2005-07-08 09:48:19 -07:00
|
|
|
if (ewin->props.focusclick && !click)
|
2005-05-29 11:58:38 -07:00
|
|
|
return 0;
|
|
|
|
|
2005-07-08 09:48:19 -07:00
|
|
|
if (want_visible && ewin->state.visibility == VisibilityFullyObscured)
|
2005-05-29 11:58:38 -07:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
return !want_on_screen || EwinIsOnScreen(ewin);
|
2004-02-24 15:19:03 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2004-02-26 11:33:21 -08:00
|
|
|
* Return the ewin to focus after entering area or losing focused window.
|
2004-02-24 15:19:03 -08:00
|
|
|
*/
|
|
|
|
static EWin *
|
|
|
|
FocusEwinSelect(void)
|
|
|
|
{
|
2005-03-05 06:25:50 -08:00
|
|
|
EWin *const *lst, *ewin;
|
2004-02-24 15:19:03 -08:00
|
|
|
int num, i;
|
|
|
|
|
2004-03-20 07:49:05 -08:00
|
|
|
switch (Conf.focus.mode)
|
2004-02-24 15:19:03 -08:00
|
|
|
{
|
2004-02-26 11:33:21 -08:00
|
|
|
default:
|
|
|
|
case MODE_FOCUS_POINTER:
|
|
|
|
ewin = GetEwinPointerInClient();
|
2005-10-20 11:09:35 -07:00
|
|
|
if (ewin && !FocusEwinValid(ewin, 1, 0, 0))
|
|
|
|
ewin = NULL;
|
2004-02-26 11:33:21 -08:00
|
|
|
break;
|
2005-03-05 06:25:50 -08:00
|
|
|
|
2004-07-17 01:55:34 -07:00
|
|
|
case MODE_FOCUS_SLOPPY:
|
|
|
|
ewin = GetEwinPointerInClient();
|
2005-05-31 14:11:32 -07:00
|
|
|
if (ewin && FocusEwinValid(ewin, 1, 0, 0))
|
2004-07-17 01:55:34 -07:00
|
|
|
break;
|
2005-03-05 06:25:50 -08:00
|
|
|
goto do_select;
|
|
|
|
|
2004-02-26 11:33:21 -08:00
|
|
|
case MODE_FOCUS_CLICK:
|
2005-03-05 06:25:50 -08:00
|
|
|
goto do_select;
|
|
|
|
|
|
|
|
do_select:
|
|
|
|
ewin = NULL;
|
2004-12-28 15:46:49 -08:00
|
|
|
lst = EwinListFocusGet(&num);
|
2004-02-26 11:33:21 -08:00
|
|
|
for (i = 0; i < num; i++)
|
|
|
|
{
|
2005-07-08 09:48:19 -07:00
|
|
|
if (!FocusEwinValid(lst[i], 1, 0, 0) ||
|
|
|
|
lst[i]->props.skip_focuslist)
|
2004-02-26 11:33:21 -08:00
|
|
|
continue;
|
|
|
|
ewin = lst[i];
|
|
|
|
break;
|
|
|
|
}
|
2004-02-24 15:19:03 -08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ewin;
|
|
|
|
}
|
|
|
|
|
2008-05-24 11:13:17 -07:00
|
|
|
static int
|
|
|
|
AutoraiseTimeout(void *data)
|
1999-08-17 15:56:46 -07:00
|
|
|
{
|
2008-05-24 11:13:17 -07:00
|
|
|
EWin *ewin = (EWin *) data;
|
1999-08-17 15:56:46 -07:00
|
|
|
|
2004-03-20 07:49:05 -08:00
|
|
|
if (Conf.focus.mode == MODE_FOCUS_CLICK)
|
2008-05-24 11:13:17 -07:00
|
|
|
goto done;
|
2004-01-28 12:09:07 -08:00
|
|
|
|
2008-05-24 11:13:17 -07:00
|
|
|
if (EwinFindByPtr(ewin)) /* May be gone */
|
2006-05-03 13:52:15 -07:00
|
|
|
EwinRaise(ewin);
|
2008-05-24 11:13:17 -07:00
|
|
|
|
|
|
|
done:
|
|
|
|
focus_timer_autoraise = NULL;
|
|
|
|
return 0;
|
1999-08-17 15:56:46 -07:00
|
|
|
}
|
|
|
|
|
2008-08-07 16:31:36 -07:00
|
|
|
static void
|
|
|
|
FocusRaisePending(void)
|
1999-08-17 15:56:46 -07:00
|
|
|
{
|
2008-08-07 16:31:36 -07:00
|
|
|
EWin *ewin = focus_pending_raise;
|
|
|
|
unsigned int mask;
|
|
|
|
|
|
|
|
/* The focusing cycle ends when no more modifiers are depressed */
|
|
|
|
mask = 0;
|
|
|
|
EQueryPointer(NULL, NULL, NULL, NULL, &mask);
|
|
|
|
if ((mask & Mode.masks.mod_key_mask) != 0)
|
|
|
|
return;
|
1999-08-17 15:56:46 -07:00
|
|
|
|
2008-05-24 11:13:17 -07:00
|
|
|
if (EwinFindByPtr(ewin)) /* May be gone */
|
2004-12-28 15:46:49 -08:00
|
|
|
EwinListFocusRaise(ewin);
|
2008-05-24 11:13:17 -07:00
|
|
|
|
2008-08-07 16:31:36 -07:00
|
|
|
GrabKeyboardRelease();
|
|
|
|
|
|
|
|
focus_pending_raise = NULL;
|
1999-08-17 15:56:46 -07:00
|
|
|
}
|
|
|
|
|
2008-09-13 09:00:43 -07:00
|
|
|
/*
|
|
|
|
* dir > 0: Focus previously focused window
|
|
|
|
* else : Focus least recently focused window
|
|
|
|
*/
|
2005-10-30 11:40:49 -08:00
|
|
|
static void
|
2008-09-13 09:00:43 -07:00
|
|
|
FocusCycleEwin(int dir)
|
1999-08-17 15:56:46 -07:00
|
|
|
{
|
2004-07-23 13:05:50 -07:00
|
|
|
EWin *const *lst;
|
|
|
|
EWin *ewin;
|
2008-08-07 16:31:36 -07:00
|
|
|
int i, j, num;
|
2004-01-21 15:32:45 -08:00
|
|
|
|
2004-12-28 15:46:49 -08:00
|
|
|
lst = EwinListFocusGet(&num);
|
2004-07-23 13:05:50 -07:00
|
|
|
if (num <= 1)
|
|
|
|
return;
|
2004-01-21 15:32:45 -08:00
|
|
|
|
2008-09-13 09:00:43 -07:00
|
|
|
dir = (dir > 0) ? 1 : -1;
|
|
|
|
|
2008-08-07 16:31:36 -07:00
|
|
|
for (j = 0; j < num; j++)
|
2000-07-26 11:00:47 -07:00
|
|
|
{
|
2008-08-07 16:31:36 -07:00
|
|
|
if (lst[j] == Mode.focuswin)
|
|
|
|
break;
|
2000-07-26 11:00:47 -07:00
|
|
|
}
|
2005-07-13 12:39:22 -07:00
|
|
|
for (i = 1; i < num; i++)
|
2004-07-23 13:05:50 -07:00
|
|
|
{
|
2008-09-13 09:00:43 -07:00
|
|
|
ewin = lst[(j + i * dir + num) % num];
|
2008-08-07 16:31:36 -07:00
|
|
|
if (!FocusEwinValid(ewin, 1, 0, 0) || ewin->props.skip_focuslist)
|
2004-07-23 13:05:50 -07:00
|
|
|
continue;
|
2008-08-07 16:31:36 -07:00
|
|
|
FocusToEWin(ewin, FOCUS_PREV);
|
2004-07-23 13:05:50 -07:00
|
|
|
break;
|
|
|
|
}
|
1999-08-17 15:56:46 -07:00
|
|
|
}
|
|
|
|
|
2005-12-08 10:45:41 -08:00
|
|
|
static void
|
2007-07-11 02:30:58 -07:00
|
|
|
ClickGrabsSet(EWin * ewin)
|
2004-02-01 03:28:06 -08:00
|
|
|
{
|
2005-10-18 12:21:25 -07:00
|
|
|
int set = 0;
|
|
|
|
|
2007-07-18 04:08:21 -07:00
|
|
|
if ((Conf.focus.clickraises && !EwinListStackIsRaised(ewin)) ||
|
2008-08-07 16:23:39 -07:00
|
|
|
(!ewin->state.active && !ewin->state.inhibit_focus))
|
2005-10-18 12:21:25 -07:00
|
|
|
set = 1;
|
|
|
|
|
|
|
|
if (set)
|
|
|
|
{
|
|
|
|
if (!ewin->state.click_grab_isset)
|
|
|
|
{
|
2006-08-07 13:20:16 -07:00
|
|
|
GrabButtonSet(AnyButton, AnyModifier, EwinGetContainerWin(ewin),
|
2005-10-18 12:21:25 -07:00
|
|
|
ButtonPressMask, ECSR_PGRAB, 1);
|
2006-11-19 13:55:52 -08:00
|
|
|
if (EDebug(EDBUG_TYPE_GRABS))
|
2007-07-11 02:30:58 -07:00
|
|
|
Eprintf("ClickGrabsSet: %#lx set %s\n",
|
2006-11-26 03:30:59 -08:00
|
|
|
EwinGetClientXwin(ewin), EwinGetTitle(ewin));
|
2005-10-18 12:21:25 -07:00
|
|
|
ewin->state.click_grab_isset = 1;
|
|
|
|
}
|
2004-02-01 03:28:06 -08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2005-10-18 12:21:25 -07:00
|
|
|
if (ewin->state.click_grab_isset)
|
|
|
|
{
|
|
|
|
GrabButtonRelease(AnyButton, AnyModifier,
|
2006-08-07 13:20:16 -07:00
|
|
|
EwinGetContainerWin(ewin));
|
2006-11-19 13:55:52 -08:00
|
|
|
if (EDebug(EDBUG_TYPE_GRABS))
|
2007-07-11 02:30:58 -07:00
|
|
|
Eprintf("ClickGrabsSet: %#lx unset %s\n",
|
2006-11-26 03:30:59 -08:00
|
|
|
EwinGetClientXwin(ewin), EwinGetTitle(ewin));
|
2005-10-18 12:21:25 -07:00
|
|
|
ewin->state.click_grab_isset = 0;
|
|
|
|
}
|
2004-02-01 03:28:06 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-04-01 14:41:22 -08:00
|
|
|
static void
|
|
|
|
FocusEwinSetActive(EWin * ewin, int active)
|
|
|
|
{
|
2007-01-16 17:10:44 -08:00
|
|
|
if (ewin->state.active == (unsigned)active)
|
2005-11-03 09:59:38 -08:00
|
|
|
return;
|
|
|
|
|
2005-07-08 09:48:19 -07:00
|
|
|
ewin->state.active = active;
|
2004-06-07 09:46:08 -07:00
|
|
|
EwinBorderUpdateState(ewin);
|
2006-04-02 01:45:40 -08:00
|
|
|
EwinUpdateOpacity(ewin);
|
2004-04-01 14:41:22 -08:00
|
|
|
|
2005-07-08 09:48:19 -07:00
|
|
|
if (active && ewin->state.attention)
|
2005-06-02 15:11:09 -07:00
|
|
|
{
|
2005-07-08 09:48:19 -07:00
|
|
|
ewin->state.attention = 0;
|
2005-06-02 15:11:09 -07:00
|
|
|
HintsSetWindowState(ewin);
|
|
|
|
}
|
2004-04-01 14:41:22 -08:00
|
|
|
}
|
|
|
|
|
2005-10-30 11:40:49 -08:00
|
|
|
static void
|
2007-07-11 02:30:58 -07:00
|
|
|
doClickGrabsUpdate(void)
|
1999-08-17 15:56:46 -07:00
|
|
|
{
|
2004-03-26 13:21:47 -08:00
|
|
|
EWin *const *lst, *ewin;
|
1999-08-17 15:56:46 -07:00
|
|
|
int i, num;
|
|
|
|
|
2004-04-01 14:41:22 -08:00
|
|
|
lst = EwinListGetAll(&num);
|
2004-02-01 03:28:06 -08:00
|
|
|
for (i = 0; i < num; i++)
|
2000-07-26 11:00:47 -07:00
|
|
|
{
|
2004-02-01 03:28:06 -08:00
|
|
|
ewin = lst[i];
|
2007-07-11 02:30:58 -07:00
|
|
|
ClickGrabsSet(ewin);
|
2000-07-26 11:00:47 -07:00
|
|
|
}
|
2007-07-11 02:30:58 -07:00
|
|
|
click_pending_update_grabs = 0;
|
2005-12-08 10:45:41 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2007-07-11 02:30:58 -07:00
|
|
|
ClickGrabsUpdate(void)
|
2005-12-08 10:45:41 -08:00
|
|
|
{
|
2007-07-11 02:30:58 -07:00
|
|
|
click_pending_update_grabs = 1;
|
1999-08-17 15:56:46 -07:00
|
|
|
}
|
|
|
|
|
2005-05-29 11:58:38 -07:00
|
|
|
static void
|
|
|
|
doFocusToEwin(EWin * ewin, int why)
|
1999-08-17 15:56:46 -07:00
|
|
|
{
|
2005-06-17 16:34:13 -07:00
|
|
|
int do_focus = 0;
|
2004-07-23 13:05:50 -07:00
|
|
|
int do_raise = 0, do_warp = 0;
|
1999-08-17 15:56:46 -07:00
|
|
|
|
2005-05-29 03:20:25 -07:00
|
|
|
if (focus_inhibit)
|
|
|
|
return;
|
|
|
|
|
2006-11-19 13:55:52 -08:00
|
|
|
if (EDebug(EDBUG_TYPE_FOCUS))
|
2005-05-29 11:58:38 -07:00
|
|
|
Eprintf("doFocusToEWin %#lx %s why=%d\n",
|
2006-08-07 13:20:16 -07:00
|
|
|
(ewin) ? EwinGetClientXwin(ewin) : 0,
|
2006-11-26 03:30:59 -08:00
|
|
|
(ewin) ? EwinGetTitle(ewin) : "None", why);
|
1999-10-03 09:02:09 -07:00
|
|
|
|
2004-02-01 03:28:06 -08:00
|
|
|
switch (why)
|
|
|
|
{
|
2004-07-23 13:05:50 -07:00
|
|
|
case FOCUS_NEXT:
|
|
|
|
case FOCUS_PREV:
|
|
|
|
if (Conf.focus.raise_on_next)
|
|
|
|
do_raise = 1;
|
|
|
|
if (Conf.focus.warp_on_next)
|
|
|
|
do_warp = 1;
|
|
|
|
/* Fall thru */
|
2004-02-01 03:28:06 -08:00
|
|
|
default:
|
2004-07-17 01:55:34 -07:00
|
|
|
case FOCUS_SET:
|
|
|
|
case FOCUS_ENTER:
|
|
|
|
case FOCUS_LEAVE: /* Unused */
|
|
|
|
case FOCUS_CLICK:
|
2005-10-20 11:09:35 -07:00
|
|
|
if (ewin && ewin == Mode.focuswin)
|
2005-01-25 13:58:28 -08:00
|
|
|
return;
|
2004-07-17 01:55:34 -07:00
|
|
|
if (ewin == NULL) /* Unfocus */
|
|
|
|
break;
|
2005-05-29 11:58:38 -07:00
|
|
|
if (!FocusEwinValid(ewin, 1, why == FOCUS_CLICK, 0))
|
2005-01-25 13:58:28 -08:00
|
|
|
return;
|
2004-07-17 01:55:34 -07:00
|
|
|
break;
|
|
|
|
|
2005-06-30 05:03:38 -07:00
|
|
|
case FOCUS_INIT:
|
2004-07-17 01:55:34 -07:00
|
|
|
case FOCUS_DESK_ENTER:
|
|
|
|
ewin = FocusEwinSelect();
|
|
|
|
break;
|
|
|
|
|
|
|
|
case FOCUS_DESK_LEAVE:
|
2005-09-05 15:26:51 -07:00
|
|
|
focus_is_set = 0;
|
2010-06-06 03:05:53 -07:00
|
|
|
/* FALLTHROUGH */
|
2005-09-05 15:26:51 -07:00
|
|
|
case FOCUS_NONE:
|
2004-07-17 01:55:34 -07:00
|
|
|
ewin = NULL;
|
2004-03-20 07:49:05 -08:00
|
|
|
if (ewin == Mode.focuswin)
|
2005-01-25 13:58:28 -08:00
|
|
|
return;
|
2004-02-01 03:28:06 -08:00
|
|
|
break;
|
1999-10-03 09:02:09 -07:00
|
|
|
|
2006-06-02 15:53:23 -07:00
|
|
|
case FOCUS_EWIN_UNMAP:
|
2005-06-30 05:03:38 -07:00
|
|
|
if (Mode.focuswin)
|
2005-01-25 13:58:28 -08:00
|
|
|
return;
|
2004-07-17 01:55:34 -07:00
|
|
|
ewin = FocusEwinSelect();
|
|
|
|
if (ewin == Mode.focuswin)
|
2004-04-08 08:51:26 -07:00
|
|
|
ewin = NULL;
|
2004-02-26 11:33:21 -08:00
|
|
|
break;
|
1999-10-03 09:02:09 -07:00
|
|
|
|
2004-02-01 03:28:06 -08:00
|
|
|
case FOCUS_EWIN_NEW:
|
2004-03-20 07:49:05 -08:00
|
|
|
if (Conf.focus.all_new_windows_get_focus)
|
2010-05-02 13:26:49 -07:00
|
|
|
goto check_focus_new;
|
|
|
|
|
|
|
|
if (Mode.place.doing_manual)
|
|
|
|
goto check_focus_new;
|
2005-11-13 04:40:13 -08:00
|
|
|
|
|
|
|
if (ewin->props.focus_when_mapped)
|
2010-05-02 13:26:49 -07:00
|
|
|
goto check_focus_new;
|
2004-02-01 03:28:06 -08:00
|
|
|
|
2010-05-02 13:26:54 -07:00
|
|
|
if (Conf.focus.new_windows_get_focus_if_group_focused && Mode.focuswin)
|
|
|
|
{
|
|
|
|
if (EwinGetWindowGroup(ewin) == EwinGetWindowGroup(Mode.focuswin))
|
|
|
|
goto check_focus_new;
|
|
|
|
}
|
|
|
|
|
2005-08-01 10:34:53 -07:00
|
|
|
if (EwinIsTransient(ewin))
|
2004-02-01 03:28:06 -08:00
|
|
|
{
|
2005-06-17 16:34:13 -07:00
|
|
|
if (Conf.focus.new_transients_get_focus)
|
|
|
|
{
|
2010-05-02 13:26:49 -07:00
|
|
|
do_focus = 1;
|
2005-06-17 16:34:13 -07:00
|
|
|
}
|
2010-05-02 13:26:51 -07:00
|
|
|
else if (Conf.focus.new_transients_get_focus_if_group_focused &&
|
|
|
|
Mode.focuswin)
|
2005-06-17 16:34:13 -07:00
|
|
|
{
|
2010-05-02 13:26:51 -07:00
|
|
|
if ((EwinGetTransientFor(ewin) ==
|
|
|
|
EwinGetClientXwin(Mode.focuswin)) ||
|
|
|
|
(EwinGetWindowGroup(ewin) ==
|
|
|
|
EwinGetWindowGroup(Mode.focuswin)))
|
2010-05-02 13:26:49 -07:00
|
|
|
do_focus = 1;
|
2005-06-17 16:34:13 -07:00
|
|
|
}
|
|
|
|
|
2010-05-02 13:26:49 -07:00
|
|
|
if (!do_focus)
|
|
|
|
return;
|
|
|
|
DeskGotoByEwin(ewin);
|
|
|
|
goto check_focus_new;
|
2004-02-01 03:28:06 -08:00
|
|
|
}
|
|
|
|
|
2010-05-02 13:26:49 -07:00
|
|
|
return;
|
|
|
|
|
|
|
|
check_focus_new:
|
2005-06-17 16:34:13 -07:00
|
|
|
if (!FocusEwinValid(ewin, 1, 0, 0))
|
2005-01-25 13:58:28 -08:00
|
|
|
return;
|
2004-02-01 03:28:06 -08:00
|
|
|
break;
|
2000-07-26 11:00:47 -07:00
|
|
|
}
|
2004-02-01 03:28:06 -08:00
|
|
|
|
2005-07-22 11:56:02 -07:00
|
|
|
if (ewin == Mode.focuswin && focus_is_set)
|
2005-01-25 13:58:28 -08:00
|
|
|
return;
|
2004-07-15 16:31:02 -07:00
|
|
|
|
2004-07-17 01:55:34 -07:00
|
|
|
/* Check if ewin is a valid focus window target */
|
2004-02-01 03:28:06 -08:00
|
|
|
|
2004-07-17 01:55:34 -07:00
|
|
|
if (!ewin)
|
|
|
|
goto done;
|
2004-02-01 03:28:06 -08:00
|
|
|
|
2004-07-17 01:55:34 -07:00
|
|
|
/* NB! ewin != NULL */
|
2004-02-01 03:28:06 -08:00
|
|
|
|
2005-07-08 09:48:19 -07:00
|
|
|
if (why != FOCUS_CLICK && ewin->props.focusclick)
|
2005-03-05 06:25:50 -08:00
|
|
|
return;
|
|
|
|
|
2004-03-20 07:49:05 -08:00
|
|
|
if (Conf.autoraise.enable)
|
2000-07-26 11:00:47 -07:00
|
|
|
{
|
2008-05-24 11:13:17 -07:00
|
|
|
TIMER_DEL(focus_timer_autoraise);
|
2004-02-01 03:28:06 -08:00
|
|
|
|
2004-03-20 07:49:05 -08:00
|
|
|
if (Conf.focus.mode != MODE_FOCUS_CLICK)
|
2008-05-24 11:13:17 -07:00
|
|
|
TIMER_ADD(focus_timer_autoraise, 0.001 * Conf.autoraise.delay,
|
|
|
|
AutoraiseTimeout, ewin);
|
2000-07-26 11:00:47 -07:00
|
|
|
}
|
2004-02-01 03:28:06 -08:00
|
|
|
|
2004-07-23 13:05:50 -07:00
|
|
|
if (do_raise)
|
2006-05-03 13:52:15 -07:00
|
|
|
EwinRaise(ewin);
|
2004-02-01 03:28:06 -08:00
|
|
|
|
2005-05-25 15:57:38 -07:00
|
|
|
if (Conf.focus.warp_always)
|
|
|
|
do_warp = 1;
|
2008-01-19 05:44:54 -08:00
|
|
|
if (do_warp)
|
|
|
|
EwinWarpTo(ewin);
|
2004-02-01 03:28:06 -08:00
|
|
|
|
2004-07-23 13:05:50 -07:00
|
|
|
switch (why)
|
|
|
|
{
|
|
|
|
case FOCUS_PREV:
|
2008-08-07 16:31:36 -07:00
|
|
|
case FOCUS_NEXT:
|
|
|
|
GrabKeyboardSet(VROOT); /* Causes idler to be called on KeyRelease */
|
|
|
|
focus_pending_raise = ewin;
|
2004-07-23 13:05:50 -07:00
|
|
|
break;
|
|
|
|
case FOCUS_DESK_ENTER:
|
2006-02-03 15:50:38 -08:00
|
|
|
if (Conf.focus.mode == MODE_FOCUS_CLICK)
|
|
|
|
break;
|
2010-06-06 03:05:53 -07:00
|
|
|
/* FALLTHROUGH */
|
2005-09-05 15:08:50 -07:00
|
|
|
default:
|
2005-06-30 05:03:38 -07:00
|
|
|
case FOCUS_INIT:
|
2004-12-28 15:46:49 -08:00
|
|
|
EwinListFocusRaise(ewin);
|
2004-07-23 13:05:50 -07:00
|
|
|
break;
|
|
|
|
}
|
2004-02-01 03:28:06 -08:00
|
|
|
|
2008-12-14 08:44:45 -08:00
|
|
|
SoundPlay(SOUND_FOCUS_SET);
|
2004-03-20 07:49:05 -08:00
|
|
|
done:
|
2005-01-10 15:34:46 -08:00
|
|
|
|
2007-07-18 04:08:21 -07:00
|
|
|
ClickGrabsUpdate();
|
|
|
|
|
2004-04-01 14:41:22 -08:00
|
|
|
/* Unset old focus window (if any) highlighting */
|
|
|
|
if (Mode.focuswin)
|
|
|
|
FocusEwinSetActive(Mode.focuswin, 0);
|
2004-02-01 03:28:06 -08:00
|
|
|
ICCCM_Cmap(ewin);
|
2005-01-13 16:03:50 -08:00
|
|
|
|
|
|
|
/* Quit if pointer is not on our screen */
|
2010-03-15 15:18:56 -07:00
|
|
|
|
|
|
|
if (!Mode.events.on_screen)
|
2005-01-13 16:03:50 -08:00
|
|
|
{
|
|
|
|
Mode.focuswin = NULL;
|
2005-01-25 13:58:28 -08:00
|
|
|
return;
|
2005-01-13 16:03:50 -08:00
|
|
|
}
|
|
|
|
|
2004-04-01 14:41:22 -08:00
|
|
|
/* Set new focus window (if any) highlighting */
|
2005-01-13 16:03:50 -08:00
|
|
|
Mode.focuswin = ewin;
|
2004-04-01 14:41:22 -08:00
|
|
|
if (Mode.focuswin)
|
|
|
|
FocusEwinSetActive(Mode.focuswin, 1);
|
2006-02-03 11:08:45 -08:00
|
|
|
|
|
|
|
if (why == FOCUS_DESK_LEAVE)
|
|
|
|
return;
|
|
|
|
|
|
|
|
ICCCM_Focus(ewin);
|
2005-07-22 11:56:02 -07:00
|
|
|
focus_is_set = 1;
|
1999-08-17 15:56:46 -07:00
|
|
|
}
|
|
|
|
|
2005-05-29 11:58:38 -07:00
|
|
|
void
|
|
|
|
FocusToEWin(EWin * ewin, int why)
|
|
|
|
{
|
2006-11-19 13:55:52 -08:00
|
|
|
if (EDebug(EDBUG_TYPE_FOCUS))
|
2005-05-29 11:58:38 -07:00
|
|
|
Eprintf("FocusToEWin(%d) %#lx %s why=%d\n", focus_inhibit,
|
2006-08-07 13:20:16 -07:00
|
|
|
(ewin) ? EwinGetClientXwin(ewin) : 0,
|
2006-11-26 03:30:59 -08:00
|
|
|
(ewin) ? EwinGetTitle(ewin) : "None", why);
|
2005-05-29 11:58:38 -07:00
|
|
|
|
|
|
|
switch (why)
|
|
|
|
{
|
|
|
|
case FOCUS_EWIN_NEW:
|
2005-10-06 09:51:54 -07:00
|
|
|
if (!FocusEwinValid(ewin, 0, 0, 0))
|
2005-07-09 08:42:04 -07:00
|
|
|
break;
|
2005-05-29 11:58:38 -07:00
|
|
|
focus_pending_new = ewin;
|
2005-07-09 08:42:04 -07:00
|
|
|
focus_pending_why = why;
|
|
|
|
focus_pending_ewin = ewin;
|
|
|
|
break;
|
|
|
|
|
2005-05-29 11:58:38 -07:00
|
|
|
default:
|
2005-11-12 07:17:44 -08:00
|
|
|
if (ewin && !FocusEwinValid(ewin, 0, why == FOCUS_CLICK, 0))
|
2005-07-09 08:42:04 -07:00
|
|
|
break;
|
2005-05-29 11:58:38 -07:00
|
|
|
focus_pending_why = why;
|
|
|
|
focus_pending_ewin = ewin;
|
|
|
|
break;
|
|
|
|
|
2006-06-02 15:53:23 -07:00
|
|
|
case FOCUS_EWIN_UNMAP:
|
2005-06-30 05:03:38 -07:00
|
|
|
focus_pending_why = why;
|
|
|
|
focus_pending_ewin = NULL;
|
2005-05-29 11:58:38 -07:00
|
|
|
if (ewin == Mode.focuswin)
|
2005-07-22 11:56:02 -07:00
|
|
|
{
|
|
|
|
Mode.focuswin = NULL;
|
|
|
|
focus_is_set = 0;
|
2006-06-02 15:53:23 -07:00
|
|
|
if (!EoIsGone(ewin))
|
|
|
|
FocusEwinSetActive(ewin, 0);
|
2005-07-22 11:56:02 -07:00
|
|
|
}
|
2005-05-29 11:58:38 -07:00
|
|
|
if (ewin == focus_pending_new)
|
|
|
|
focus_pending_new = NULL;
|
|
|
|
break;
|
|
|
|
}
|
2010-04-02 08:28:08 -07:00
|
|
|
focus_request = (int)NextRequest(disp) - 1;
|
2005-05-29 11:58:38 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
FocusSet(void)
|
|
|
|
{
|
|
|
|
if (focus_pending_new && Conf.focus.all_new_windows_get_focus)
|
|
|
|
doFocusToEwin(focus_pending_new, FOCUS_EWIN_NEW);
|
|
|
|
else
|
|
|
|
doFocusToEwin(focus_pending_ewin, focus_pending_why);
|
|
|
|
focus_pending_why = 0;
|
|
|
|
focus_pending_ewin = focus_pending_new = NULL;
|
|
|
|
}
|
|
|
|
|
1999-08-17 15:56:46 -07:00
|
|
|
void
|
2004-01-21 15:32:45 -08:00
|
|
|
FocusNewDeskBegin(void)
|
1999-08-17 15:56:46 -07:00
|
|
|
{
|
2006-02-03 11:08:45 -08:00
|
|
|
/* Freeze keyboard */
|
2008-03-24 04:12:40 -07:00
|
|
|
XGrabKeyboard(disp, WinGetXwin(VROOT), False, GrabModeAsync,
|
|
|
|
GrabModeSync, CurrentTime);
|
2006-02-03 11:08:45 -08:00
|
|
|
|
2005-10-16 09:02:56 -07:00
|
|
|
focus_pending_new = NULL;
|
|
|
|
doFocusToEwin(NULL, FOCUS_DESK_LEAVE);
|
1999-08-17 15:56:46 -07:00
|
|
|
}
|
|
|
|
|
2005-05-29 11:58:38 -07:00
|
|
|
void
|
|
|
|
FocusNewDesk(void)
|
2005-01-10 15:34:46 -08:00
|
|
|
{
|
2007-07-28 01:39:55 -07:00
|
|
|
FocusToEWin(NULL, FOCUS_DESK_ENTER);
|
2006-02-03 11:08:45 -08:00
|
|
|
|
|
|
|
/* Unfreeze keyboard */
|
|
|
|
XUngrabKeyboard(disp, CurrentTime);
|
2005-01-10 15:34:46 -08:00
|
|
|
}
|
|
|
|
|
2010-04-05 10:48:37 -07:00
|
|
|
static void
|
|
|
|
_FocusScreenSendEvent(Window xwin, int x, int y, Time t, int enter)
|
|
|
|
{
|
|
|
|
XEvent xe;
|
|
|
|
|
|
|
|
xe.type = (enter) ? EnterNotify : LeaveNotify;
|
|
|
|
xe.xcrossing.window = xwin;
|
|
|
|
xe.xcrossing.root = xwin;
|
|
|
|
xe.xcrossing.subwindow = 0;
|
|
|
|
xe.xcrossing.time = t;
|
|
|
|
xe.xcrossing.x = xe.xcrossing.x_root = x;
|
|
|
|
xe.xcrossing.y = xe.xcrossing.y_root = y;
|
|
|
|
xe.xcrossing.mode = NotifyNormal;
|
|
|
|
xe.xcrossing.detail = NotifyNonlinear;
|
|
|
|
xe.xcrossing.same_screen = (enter) ? True : False;
|
|
|
|
xe.xcrossing.focus = (enter) ? False : True;
|
|
|
|
xe.xcrossing.state = 0;
|
|
|
|
|
|
|
|
XSendEvent(disp, xwin, False, EnterWindowMask | LeaveWindowMask, &xe);
|
|
|
|
}
|
|
|
|
|
2009-03-16 14:15:06 -07:00
|
|
|
void
|
2010-04-05 10:48:37 -07:00
|
|
|
FocusScreen(int scr)
|
2009-03-16 14:15:06 -07:00
|
|
|
{
|
2010-04-05 10:48:37 -07:00
|
|
|
Window xwin;
|
|
|
|
Time t;
|
|
|
|
int x, y;
|
|
|
|
|
|
|
|
if (scr < 0 || scr >= ScreenCount(disp))
|
|
|
|
return;
|
2009-03-16 14:15:06 -07:00
|
|
|
|
2010-04-05 10:48:37 -07:00
|
|
|
/* IIRC warping to a different screen once did cause
|
|
|
|
* LeaveNotify's on the current root window. This does not
|
|
|
|
* happen in xorg 1.5.3 (and probably other versions).
|
|
|
|
* So, send LeaveNotify to current root and EnterNotify
|
|
|
|
* to new root. */
|
|
|
|
|
|
|
|
t = EGetTimestamp();
|
|
|
|
|
|
|
|
/* Report LeaveNotify on current root window */
|
|
|
|
xwin = WinGetXwin(VROOT);
|
|
|
|
EXQueryPointer(xwin, &x, &y, NULL, NULL);
|
|
|
|
_FocusScreenSendEvent(xwin, x, y, t, 0);
|
|
|
|
|
|
|
|
/* Do warp and report EnterNotify on new root window */
|
|
|
|
xwin = RootWindow(disp, scr);
|
|
|
|
x = DisplayWidth(disp, scr) / 2;
|
|
|
|
y = DisplayHeight(disp, scr) / 2;
|
|
|
|
EXWarpPointer(xwin, x, y);
|
|
|
|
_FocusScreenSendEvent(xwin, x, y, t, 1);
|
2009-03-16 14:15:06 -07:00
|
|
|
}
|
|
|
|
|
2005-01-10 15:34:46 -08:00
|
|
|
static void
|
2005-05-29 11:58:38 -07:00
|
|
|
FocusInit(void)
|
1999-08-17 15:56:46 -07:00
|
|
|
{
|
2005-05-29 11:58:38 -07:00
|
|
|
/* Start focusing windows */
|
|
|
|
FocusEnable(1);
|
2003-06-11 13:05:59 -07:00
|
|
|
|
2005-06-30 05:03:38 -07:00
|
|
|
FocusToEWin(NULL, FOCUS_INIT);
|
2005-06-17 16:34:13 -07:00
|
|
|
FocusSet();
|
2005-05-29 11:58:38 -07:00
|
|
|
|
|
|
|
/* Enable window placement features */
|
2007-06-17 01:33:22 -07:00
|
|
|
Mode.place.enable_features++;
|
2005-05-29 11:58:38 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
FocusExit(void)
|
|
|
|
{
|
1999-08-17 15:56:46 -07:00
|
|
|
}
|
|
|
|
|
2004-02-01 03:28:06 -08:00
|
|
|
/*
|
|
|
|
* Focus event handlers
|
|
|
|
*/
|
|
|
|
|
1999-08-17 15:56:46 -07:00
|
|
|
void
|
2004-12-28 15:46:49 -08:00
|
|
|
FocusHandleEnter(EWin * ewin, XEvent * ev)
|
1999-08-17 15:56:46 -07:00
|
|
|
{
|
2004-12-28 15:46:49 -08:00
|
|
|
Mode.mouse_over_ewin = ewin;
|
1999-08-17 15:56:46 -07:00
|
|
|
|
2004-12-28 15:46:49 -08:00
|
|
|
if (!ewin)
|
2004-04-01 14:41:22 -08:00
|
|
|
{
|
2004-12-28 15:46:49 -08:00
|
|
|
/* Entering root may mean entering this screen */
|
2010-04-05 10:48:35 -07:00
|
|
|
FocusToEWin(NULL, FOCUS_DESK_ENTER);
|
|
|
|
return;
|
2004-04-01 14:41:22 -08:00
|
|
|
}
|
|
|
|
|
2007-03-25 01:53:36 -07:00
|
|
|
if (ev->xcrossing.mode == NotifyUngrab &&
|
|
|
|
ev->xcrossing.detail == NotifyNonlinearVirtual)
|
|
|
|
return;
|
|
|
|
|
2010-03-15 15:19:03 -07:00
|
|
|
if ((int)ev->xcrossing.serial - focus_request < 0)
|
|
|
|
{
|
|
|
|
/* This event was caused by a request older than the latest
|
|
|
|
* focus assignment request - ignore */
|
|
|
|
if (EDebug(EDBUG_TYPE_FOCUS))
|
|
|
|
Eprintf("FocusHandleEnter: Ignore serial < %#x\n", focus_request);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2004-03-20 07:49:05 -08:00
|
|
|
switch (Conf.focus.mode)
|
2004-01-28 12:09:07 -08:00
|
|
|
{
|
2004-02-01 03:28:06 -08:00
|
|
|
default:
|
|
|
|
case MODE_FOCUS_CLICK:
|
|
|
|
break;
|
|
|
|
case MODE_FOCUS_SLOPPY:
|
2005-05-29 11:58:38 -07:00
|
|
|
if (FocusEwinValid(ewin, 1, 0, 0))
|
|
|
|
FocusToEWin(ewin, FOCUS_ENTER);
|
2004-02-01 03:28:06 -08:00
|
|
|
break;
|
|
|
|
case MODE_FOCUS_POINTER:
|
2010-04-05 10:48:35 -07:00
|
|
|
if (FocusEwinValid(ewin, 1, 0, 0))
|
2005-05-29 11:58:38 -07:00
|
|
|
FocusToEWin(ewin, FOCUS_ENTER);
|
2010-04-05 10:48:35 -07:00
|
|
|
else
|
|
|
|
FocusToEWin(NULL, FOCUS_NONE);
|
2004-02-01 03:28:06 -08:00
|
|
|
break;
|
2004-01-28 12:09:07 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2010-04-05 10:48:35 -07:00
|
|
|
FocusHandleLeave(EWin * ewin, XEvent * ev)
|
2004-01-28 12:09:07 -08:00
|
|
|
{
|
2010-05-08 06:04:35 -07:00
|
|
|
if ((int)ev->xcrossing.serial - focus_request < 0)
|
|
|
|
{
|
|
|
|
/* This event was caused by a request older than the latest
|
|
|
|
* focus assignment request - ignore */
|
|
|
|
if (EDebug(EDBUG_TYPE_FOCUS))
|
|
|
|
Eprintf("FocusHandleLeave: Ignore serial < %#x\n", focus_request);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2004-02-16 14:58:21 -08:00
|
|
|
/* Leaving root may mean entering other screen */
|
2010-04-05 10:48:35 -07:00
|
|
|
if (!ewin)
|
2010-01-31 06:57:20 -08:00
|
|
|
{
|
2010-04-05 10:48:35 -07:00
|
|
|
if (ev->xcrossing.mode == NotifyNormal &&
|
|
|
|
ev->xcrossing.detail != NotifyInferior)
|
2010-01-31 06:57:20 -08:00
|
|
|
FocusToEWin(NULL, FOCUS_DESK_LEAVE);
|
|
|
|
}
|
2004-01-28 12:09:07 -08:00
|
|
|
}
|
|
|
|
|
2005-11-15 15:24:20 -08:00
|
|
|
void
|
|
|
|
FocusHandleChange(EWin * ewin __UNUSED__, XEvent * ev __UNUSED__)
|
|
|
|
{
|
|
|
|
#if 0 /* Debug */
|
|
|
|
if (ewin == Mode.focuswin && ev->type == FocusOut)
|
2006-11-26 03:30:59 -08:00
|
|
|
Eprintf("??? Lost focus: %s\n", EwinGetTitle(ewin));
|
2005-11-15 15:24:20 -08:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2004-02-01 03:28:06 -08:00
|
|
|
void
|
2006-04-29 12:39:21 -07:00
|
|
|
FocusHandleClick(EWin * ewin, Win win)
|
2004-02-01 03:28:06 -08:00
|
|
|
{
|
2005-12-22 11:05:20 -08:00
|
|
|
if (Conf.focus.clickraises)
|
2006-05-03 13:52:15 -07:00
|
|
|
EwinRaise(ewin);
|
2004-02-01 03:28:06 -08:00
|
|
|
|
2007-07-11 02:30:58 -07:00
|
|
|
FocusToEWin(ewin, FOCUS_CLICK);
|
2004-02-01 03:28:06 -08:00
|
|
|
|
2005-12-22 11:05:20 -08:00
|
|
|
/* Allow click to pass thorugh */
|
2006-11-19 13:55:52 -08:00
|
|
|
if (EDebug(EDBUG_TYPE_GRABS))
|
2006-08-07 13:47:12 -07:00
|
|
|
Eprintf("FocusHandleClick %#lx %#lx\n", WinGetXwin(win),
|
2006-08-07 13:20:16 -07:00
|
|
|
EwinGetContainerXwin(ewin));
|
|
|
|
if (win == EwinGetContainerWin(ewin))
|
2004-02-01 03:28:06 -08:00
|
|
|
{
|
2008-02-13 13:31:29 -08:00
|
|
|
ESync(ESYNC_FOCUS);
|
2005-12-22 11:05:20 -08:00
|
|
|
XAllowEvents(disp, ReplayPointer, CurrentTime);
|
2008-02-13 13:31:29 -08:00
|
|
|
ESync(ESYNC_FOCUS);
|
2004-02-01 03:28:06 -08:00
|
|
|
}
|
|
|
|
}
|
2004-12-28 15:46:49 -08:00
|
|
|
|
2009-01-24 00:31:50 -08:00
|
|
|
#if ENABLE_DIALOGS
|
2005-05-25 15:57:38 -07:00
|
|
|
/*
|
|
|
|
* Configuration dialog
|
|
|
|
*/
|
2009-11-05 10:46:00 -08:00
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
struct {
|
|
|
|
int mode;
|
|
|
|
char clickalways;
|
|
|
|
char new_focus;
|
2010-05-02 13:26:54 -07:00
|
|
|
char new_focus_if_group;
|
2009-11-05 10:46:00 -08:00
|
|
|
char popup_focus;
|
2010-05-02 13:26:54 -07:00
|
|
|
char popup_focus_if_group;
|
2009-11-05 10:46:00 -08:00
|
|
|
char raise_focus;
|
|
|
|
char warp_focus;
|
|
|
|
char warp_always;
|
|
|
|
} focus;
|
|
|
|
|
|
|
|
struct {
|
|
|
|
char enable;
|
|
|
|
int time;
|
|
|
|
} autoraise;
|
|
|
|
|
|
|
|
struct {
|
|
|
|
char enable;
|
|
|
|
char warp_after_focus;
|
|
|
|
char raise_after_focus;
|
|
|
|
char showsticky;
|
|
|
|
char showshaded;
|
|
|
|
char showiconified;
|
|
|
|
char showalldesks;
|
|
|
|
char warpfocused;
|
|
|
|
int icon_mode;
|
|
|
|
} focuslist;
|
|
|
|
} FocusDlgData;
|
2005-05-25 15:57:38 -07:00
|
|
|
|
|
|
|
static void
|
2009-11-05 10:46:00 -08:00
|
|
|
CB_ConfigureFocus(Dialog * d, int val, void *data __UNUSED__)
|
2005-05-25 15:57:38 -07:00
|
|
|
{
|
2009-11-05 10:46:00 -08:00
|
|
|
FocusDlgData *dd = DLG_DATA_GET(d, FocusDlgData);
|
|
|
|
|
|
|
|
if (val >= 2)
|
|
|
|
return;
|
|
|
|
|
|
|
|
Conf.focus.mode = dd->focus.mode;
|
|
|
|
Conf.focus.clickraises = dd->focus.clickalways;
|
|
|
|
Conf.focus.all_new_windows_get_focus = dd->focus.new_focus;
|
2010-05-02 13:26:54 -07:00
|
|
|
Conf.focus.new_windows_get_focus_if_group_focused =
|
|
|
|
dd->focus.new_focus_if_group;
|
2009-11-05 10:46:00 -08:00
|
|
|
Conf.focus.new_transients_get_focus = dd->focus.popup_focus;
|
|
|
|
Conf.focus.new_transients_get_focus_if_group_focused =
|
2010-05-02 13:26:54 -07:00
|
|
|
dd->focus.popup_focus_if_group;
|
2009-11-05 10:46:00 -08:00
|
|
|
Conf.focus.raise_on_next = dd->focus.raise_focus;
|
|
|
|
Conf.focus.warp_on_next = dd->focus.warp_focus;
|
|
|
|
Conf.focus.warp_always = dd->focus.warp_always;
|
|
|
|
|
|
|
|
Conf.autoraise.enable = dd->autoraise.enable;
|
|
|
|
Conf.autoraise.delay = 10 * dd->autoraise.time;
|
|
|
|
|
|
|
|
Conf.warplist.enable = dd->focuslist.enable;
|
|
|
|
Conf.warplist.warp_on_select = dd->focuslist.warp_after_focus;
|
|
|
|
Conf.warplist.raise_on_select = dd->focuslist.raise_after_focus;
|
|
|
|
Conf.warplist.showsticky = dd->focuslist.showsticky;
|
|
|
|
Conf.warplist.showshaded = dd->focuslist.showshaded;
|
|
|
|
Conf.warplist.showiconified = dd->focuslist.showiconified;
|
|
|
|
Conf.warplist.showalldesks = dd->focuslist.showalldesks;
|
|
|
|
Conf.warplist.warpfocused = dd->focuslist.warpfocused;
|
|
|
|
Conf.warplist.icon_mode = dd->focuslist.icon_mode;
|
|
|
|
|
|
|
|
ClickGrabsUpdate();
|
|
|
|
|
2005-05-25 15:57:38 -07:00
|
|
|
autosave();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2009-11-05 10:46:00 -08:00
|
|
|
_DlgFillFocus(Dialog * d, DItem * table, void *data __UNUSED__)
|
2005-05-25 15:57:38 -07:00
|
|
|
{
|
2006-07-20 20:17:18 -07:00
|
|
|
DItem *di, *radio, *radio2;
|
2009-11-05 10:46:00 -08:00
|
|
|
FocusDlgData *dd;
|
|
|
|
|
|
|
|
dd = DLG_DATA_SET(d, FocusDlgData);
|
|
|
|
if (!dd)
|
|
|
|
return;
|
2005-05-25 15:57:38 -07:00
|
|
|
|
2009-11-05 10:46:00 -08:00
|
|
|
dd->focus.mode = Conf.focus.mode;
|
|
|
|
dd->focus.clickalways = Conf.focus.clickraises;
|
|
|
|
dd->focus.new_focus = Conf.focus.all_new_windows_get_focus;
|
2010-05-02 13:26:54 -07:00
|
|
|
dd->focus.new_focus_if_group =
|
|
|
|
Conf.focus.new_windows_get_focus_if_group_focused;
|
2009-11-05 10:46:00 -08:00
|
|
|
dd->focus.popup_focus = Conf.focus.new_transients_get_focus;
|
2010-05-02 13:26:54 -07:00
|
|
|
dd->focus.popup_focus_if_group =
|
2009-11-05 10:46:00 -08:00
|
|
|
Conf.focus.new_transients_get_focus_if_group_focused;
|
|
|
|
dd->focus.raise_focus = Conf.focus.raise_on_next;
|
|
|
|
dd->focus.warp_focus = Conf.focus.warp_on_next;
|
|
|
|
dd->focus.warp_always = Conf.focus.warp_always;
|
|
|
|
|
|
|
|
dd->autoraise.enable = Conf.autoraise.enable;
|
|
|
|
dd->autoraise.time = Conf.autoraise.delay / 10;
|
|
|
|
|
|
|
|
dd->focuslist.enable = Conf.warplist.enable;
|
|
|
|
dd->focuslist.raise_after_focus = Conf.warplist.raise_on_select;
|
|
|
|
dd->focuslist.warp_after_focus = Conf.warplist.warp_on_select;
|
|
|
|
dd->focuslist.showsticky = Conf.warplist.showsticky;
|
|
|
|
dd->focuslist.showshaded = Conf.warplist.showshaded;
|
|
|
|
dd->focuslist.showiconified = Conf.warplist.showiconified;
|
|
|
|
dd->focuslist.showalldesks = Conf.warplist.showalldesks;
|
|
|
|
dd->focuslist.warpfocused = Conf.warplist.warpfocused;
|
|
|
|
dd->focuslist.icon_mode = Conf.warplist.icon_mode;
|
2005-05-25 15:57:38 -07:00
|
|
|
|
|
|
|
DialogItemTableSetOptions(table, 2, 0, 0, 0);
|
|
|
|
|
|
|
|
radio = di = DialogAddItem(table, DITEM_RADIOBUTTON);
|
|
|
|
DialogItemSetColSpan(di, 2);
|
2005-08-02 09:50:40 -07:00
|
|
|
DialogItemSetText(di, _("Focus follows pointer"));
|
2005-05-25 15:57:38 -07:00
|
|
|
DialogItemRadioButtonSetFirst(di, radio);
|
|
|
|
DialogItemRadioButtonGroupSetVal(di, 0);
|
|
|
|
|
|
|
|
di = DialogAddItem(table, DITEM_RADIOBUTTON);
|
|
|
|
DialogItemSetColSpan(di, 2);
|
2005-08-02 09:50:40 -07:00
|
|
|
DialogItemSetText(di, _("Focus follows pointer sloppily"));
|
2005-05-25 15:57:38 -07:00
|
|
|
DialogItemRadioButtonSetFirst(di, radio);
|
|
|
|
DialogItemRadioButtonGroupSetVal(di, 1);
|
|
|
|
|
|
|
|
di = DialogAddItem(table, DITEM_RADIOBUTTON);
|
|
|
|
DialogItemSetColSpan(di, 2);
|
2005-08-02 09:50:40 -07:00
|
|
|
DialogItemSetText(di, _("Focus follows mouse clicks"));
|
2005-05-25 15:57:38 -07:00
|
|
|
DialogItemRadioButtonSetFirst(di, radio);
|
|
|
|
DialogItemRadioButtonGroupSetVal(di, 2);
|
2009-11-05 10:46:00 -08:00
|
|
|
DialogItemRadioButtonGroupSetValPtr(radio, &dd->focus.mode);
|
2005-05-25 15:57:38 -07:00
|
|
|
|
|
|
|
di = DialogAddItem(table, DITEM_SEPARATOR);
|
|
|
|
DialogItemSetColSpan(di, 2);
|
|
|
|
|
|
|
|
di = DialogAddItem(table, DITEM_CHECKBUTTON);
|
|
|
|
DialogItemSetColSpan(di, 2);
|
2005-08-02 09:50:40 -07:00
|
|
|
DialogItemSetText(di, _("Clicking in a window always raises it"));
|
2009-11-05 10:46:00 -08:00
|
|
|
DialogItemCheckButtonSetPtr(di, &dd->focus.clickalways);
|
2005-05-25 15:57:38 -07:00
|
|
|
|
|
|
|
di = DialogAddItem(table, DITEM_SEPARATOR);
|
|
|
|
DialogItemSetColSpan(di, 2);
|
|
|
|
|
|
|
|
di = DialogAddItem(table, DITEM_CHECKBUTTON);
|
|
|
|
DialogItemSetColSpan(di, 2);
|
2005-08-02 09:50:40 -07:00
|
|
|
DialogItemSetText(di, _("All new windows first get the focus"));
|
2009-11-05 10:46:00 -08:00
|
|
|
DialogItemCheckButtonSetPtr(di, &dd->focus.new_focus);
|
2005-05-25 15:57:38 -07:00
|
|
|
|
2010-05-02 13:26:54 -07:00
|
|
|
di = DialogAddItem(table, DITEM_CHECKBUTTON);
|
|
|
|
DialogItemSetColSpan(di, 2);
|
|
|
|
DialogItemSetText(di,
|
|
|
|
_
|
|
|
|
("New windows get the focus if their window group is focused"));
|
|
|
|
DialogItemCheckButtonSetPtr(di, &dd->focus.new_focus_if_group);
|
|
|
|
|
2005-05-25 15:57:38 -07:00
|
|
|
di = DialogAddItem(table, DITEM_CHECKBUTTON);
|
|
|
|
DialogItemSetColSpan(di, 2);
|
2005-08-02 09:50:40 -07:00
|
|
|
DialogItemSetText(di, _("Only new dialog windows get the focus"));
|
2009-11-05 10:46:00 -08:00
|
|
|
DialogItemCheckButtonSetPtr(di, &dd->focus.popup_focus);
|
2005-05-25 15:57:38 -07:00
|
|
|
|
|
|
|
di = DialogAddItem(table, DITEM_CHECKBUTTON);
|
|
|
|
DialogItemSetColSpan(di, 2);
|
2005-08-02 09:50:40 -07:00
|
|
|
DialogItemSetText(di,
|
|
|
|
_
|
|
|
|
("Only new dialogs whose owner is focused get the focus"));
|
2010-05-02 13:26:54 -07:00
|
|
|
DialogItemCheckButtonSetPtr(di, &dd->focus.popup_focus_if_group);
|
2005-05-25 15:57:38 -07:00
|
|
|
|
|
|
|
di = DialogAddItem(table, DITEM_CHECKBUTTON);
|
|
|
|
DialogItemSetColSpan(di, 2);
|
2005-08-02 09:50:40 -07:00
|
|
|
DialogItemSetText(di, _("Raise windows while switching focus"));
|
2009-11-05 10:46:00 -08:00
|
|
|
DialogItemCheckButtonSetPtr(di, &dd->focus.raise_focus);
|
2005-05-25 15:57:38 -07:00
|
|
|
|
|
|
|
di = DialogAddItem(table, DITEM_CHECKBUTTON);
|
|
|
|
DialogItemSetColSpan(di, 2);
|
2005-08-02 09:50:40 -07:00
|
|
|
DialogItemSetText(di,
|
|
|
|
_("Send mouse pointer to window while switching focus"));
|
2009-11-05 10:46:00 -08:00
|
|
|
DialogItemCheckButtonSetPtr(di, &dd->focus.warp_focus);
|
2005-05-25 15:57:38 -07:00
|
|
|
|
|
|
|
di = DialogAddItem(table, DITEM_CHECKBUTTON);
|
|
|
|
DialogItemSetColSpan(di, 2);
|
2005-08-02 09:50:40 -07:00
|
|
|
DialogItemSetText(di,
|
|
|
|
_("Always send mouse pointer to window on focus switch"));
|
2009-11-05 10:46:00 -08:00
|
|
|
DialogItemCheckButtonSetPtr(di, &dd->focus.warp_always);
|
2005-05-25 15:57:38 -07:00
|
|
|
|
|
|
|
di = DialogAddItem(table, DITEM_SEPARATOR);
|
|
|
|
DialogItemSetColSpan(di, 2);
|
|
|
|
|
|
|
|
di = DialogAddItem(table, DITEM_CHECKBUTTON);
|
2009-11-05 10:45:55 -08:00
|
|
|
DialogItemSetColSpan(di, 2);
|
|
|
|
DialogItemSetText(di, _("Raise windows automatically"));
|
2009-11-05 10:46:00 -08:00
|
|
|
DialogItemCheckButtonSetPtr(di, &dd->autoraise.enable);
|
2009-11-05 10:45:55 -08:00
|
|
|
|
|
|
|
di = DialogAddItem(table, DITEM_TEXT);
|
|
|
|
DialogItemSetFill(di, 0, 0);
|
|
|
|
DialogItemSetAlign(di, 0, 512);
|
|
|
|
DialogItemSetText(di, _("Autoraise delay:"));
|
|
|
|
|
|
|
|
di = DialogAddItem(table, DITEM_SLIDER);
|
|
|
|
DialogItemSliderSetBounds(di, 0, 300);
|
|
|
|
DialogItemSliderSetUnits(di, 10);
|
|
|
|
DialogItemSliderSetJump(di, 25);
|
2009-11-05 10:46:00 -08:00
|
|
|
DialogItemSliderSetValPtr(di, &dd->autoraise.time);
|
2009-11-05 10:45:55 -08:00
|
|
|
|
|
|
|
di = DialogAddItem(table, DITEM_SEPARATOR);
|
|
|
|
DialogItemSetColSpan(di, 2);
|
|
|
|
|
|
|
|
di = DialogAddItem(table, DITEM_CHECKBUTTON);
|
2005-05-25 15:57:38 -07:00
|
|
|
DialogItemSetColSpan(di, 2);
|
2005-08-02 09:50:40 -07:00
|
|
|
DialogItemSetText(di, _("Display and use focus list"));
|
2009-11-05 10:46:00 -08:00
|
|
|
DialogItemCheckButtonSetPtr(di, &dd->focuslist.enable);
|
2005-05-25 15:57:38 -07:00
|
|
|
|
|
|
|
di = DialogAddItem(table, DITEM_CHECKBUTTON);
|
|
|
|
DialogItemSetColSpan(di, 2);
|
2005-08-02 09:50:40 -07:00
|
|
|
DialogItemSetText(di, _("Include sticky windows in focus list"));
|
2009-11-05 10:46:00 -08:00
|
|
|
DialogItemCheckButtonSetPtr(di, &dd->focuslist.showsticky);
|
2005-05-25 15:57:38 -07:00
|
|
|
|
|
|
|
di = DialogAddItem(table, DITEM_CHECKBUTTON);
|
|
|
|
DialogItemSetColSpan(di, 2);
|
2005-08-02 09:50:40 -07:00
|
|
|
DialogItemSetText(di, _("Include shaded windows in focus list"));
|
2009-11-05 10:46:00 -08:00
|
|
|
DialogItemCheckButtonSetPtr(di, &dd->focuslist.showshaded);
|
2005-05-25 15:57:38 -07:00
|
|
|
|
|
|
|
di = DialogAddItem(table, DITEM_CHECKBUTTON);
|
|
|
|
DialogItemSetColSpan(di, 2);
|
2005-08-02 09:50:40 -07:00
|
|
|
DialogItemSetText(di, _("Include iconified windows in focus list"));
|
2009-11-05 10:46:00 -08:00
|
|
|
DialogItemCheckButtonSetPtr(di, &dd->focuslist.showiconified);
|
2005-05-25 15:57:38 -07:00
|
|
|
|
2007-03-05 19:33:31 -08:00
|
|
|
di = DialogAddItem(table, DITEM_CHECKBUTTON);
|
|
|
|
DialogItemSetColSpan(di, 2);
|
|
|
|
DialogItemSetText(di, _("Include windows on other desks in focus list"));
|
2009-11-05 10:46:00 -08:00
|
|
|
DialogItemCheckButtonSetPtr(di, &dd->focuslist.showalldesks);
|
2007-03-05 19:33:31 -08:00
|
|
|
|
2005-05-25 15:57:38 -07:00
|
|
|
di = DialogAddItem(table, DITEM_CHECKBUTTON);
|
|
|
|
DialogItemSetColSpan(di, 2);
|
2005-08-02 09:50:40 -07:00
|
|
|
DialogItemSetText(di, _("Focus windows while switching"));
|
2009-11-05 10:46:00 -08:00
|
|
|
DialogItemCheckButtonSetPtr(di, &dd->focuslist.warpfocused);
|
2005-05-25 15:57:38 -07:00
|
|
|
|
|
|
|
di = DialogAddItem(table, DITEM_CHECKBUTTON);
|
|
|
|
DialogItemSetColSpan(di, 2);
|
2005-08-02 09:50:40 -07:00
|
|
|
DialogItemSetText(di, _("Raise windows after focus switch"));
|
2009-11-05 10:46:00 -08:00
|
|
|
DialogItemCheckButtonSetPtr(di, &dd->focuslist.raise_after_focus);
|
2005-05-25 15:57:38 -07:00
|
|
|
|
|
|
|
di = DialogAddItem(table, DITEM_CHECKBUTTON);
|
|
|
|
DialogItemSetColSpan(di, 2);
|
2005-08-02 09:50:40 -07:00
|
|
|
DialogItemSetText(di, _("Send mouse pointer to window after focus switch"));
|
2009-11-05 10:46:00 -08:00
|
|
|
DialogItemCheckButtonSetPtr(di, &dd->focuslist.warp_after_focus);
|
2005-05-25 15:57:38 -07:00
|
|
|
|
|
|
|
di = DialogAddItem(table, DITEM_SEPARATOR);
|
|
|
|
DialogItemSetColSpan(di, 2);
|
|
|
|
|
|
|
|
di = DialogAddItem(table, DITEM_TEXT);
|
|
|
|
DialogItemSetColSpan(di, 2);
|
2005-08-02 09:50:40 -07:00
|
|
|
DialogItemSetText(di,
|
|
|
|
_
|
|
|
|
("Focuslist image display policy (if one operation fails, try the next):"));
|
2005-05-25 15:57:38 -07:00
|
|
|
|
|
|
|
radio2 = di = DialogAddItem(table, DITEM_RADIOBUTTON);
|
|
|
|
DialogItemSetColSpan(di, 2);
|
2005-08-02 09:50:40 -07:00
|
|
|
DialogItemSetText(di, _("First E Icon, then App Icon"));
|
2005-05-25 15:57:38 -07:00
|
|
|
DialogItemRadioButtonSetFirst(di, radio2);
|
2010-03-20 03:41:12 -07:00
|
|
|
DialogItemRadioButtonGroupSetVal(di, EWIN_ICON_MODE_IMG_APP);
|
2005-05-25 15:57:38 -07:00
|
|
|
|
|
|
|
di = DialogAddItem(table, DITEM_RADIOBUTTON);
|
|
|
|
DialogItemSetColSpan(di, 2);
|
2005-08-02 09:50:40 -07:00
|
|
|
DialogItemSetText(di, _("First App Icon, then E Icon"));
|
2005-05-25 15:57:38 -07:00
|
|
|
DialogItemRadioButtonSetFirst(di, radio2);
|
2010-03-20 03:41:12 -07:00
|
|
|
DialogItemRadioButtonGroupSetVal(di, EWIN_ICON_MODE_APP_IMG);
|
2005-05-25 15:57:38 -07:00
|
|
|
|
|
|
|
di = DialogAddItem(table, DITEM_RADIOBUTTON);
|
|
|
|
DialogItemSetColSpan(di, 2);
|
2005-08-02 09:50:40 -07:00
|
|
|
DialogItemSetText(di, _("None"));
|
2005-05-25 15:57:38 -07:00
|
|
|
DialogItemRadioButtonSetFirst(di, radio2);
|
2010-03-20 03:41:12 -07:00
|
|
|
DialogItemRadioButtonGroupSetVal(di, EWIN_ICON_MODE_NONE);
|
2009-11-05 10:46:00 -08:00
|
|
|
DialogItemRadioButtonGroupSetValPtr(radio2, &dd->focuslist.icon_mode);
|
2005-05-25 15:57:38 -07:00
|
|
|
}
|
|
|
|
|
2006-07-20 20:17:18 -07:00
|
|
|
const DialogDef DlgFocus = {
|
|
|
|
"CONFIGURE_FOCUS",
|
|
|
|
N_("Focus"),
|
|
|
|
N_("Focus Settings"),
|
2008-12-14 08:44:45 -08:00
|
|
|
SOUND_SETTINGS_FOCUS,
|
2006-07-26 21:52:50 -07:00
|
|
|
"pix/focus.png",
|
2010-05-09 12:03:19 -07:00
|
|
|
N_("Enlightenment Focus\n" "Settings Dialog"),
|
2006-08-07 20:58:42 -07:00
|
|
|
_DlgFillFocus,
|
|
|
|
DLG_OAC, CB_ConfigureFocus,
|
2006-07-20 20:17:18 -07:00
|
|
|
};
|
2009-01-24 00:31:50 -08:00
|
|
|
#endif /* ENABLE_DIALOGS */
|
2006-07-20 20:17:18 -07:00
|
|
|
|
2005-01-10 15:34:46 -08:00
|
|
|
/*
|
|
|
|
* Focus Module
|
|
|
|
*/
|
|
|
|
|
2008-05-24 11:13:17 -07:00
|
|
|
static int
|
|
|
|
FocusInitTimeout(void *data __UNUSED__)
|
2005-03-05 06:25:50 -08:00
|
|
|
{
|
|
|
|
FocusInit();
|
2008-05-24 11:13:17 -07:00
|
|
|
return 0;
|
2005-03-05 06:25:50 -08:00
|
|
|
}
|
|
|
|
|
2006-04-09 03:18:34 -07:00
|
|
|
static void
|
|
|
|
_FocusIdler(void *data __UNUSED__)
|
|
|
|
{
|
|
|
|
if (!focus_inhibit && focus_pending_why)
|
|
|
|
FocusSet();
|
2007-07-11 02:30:58 -07:00
|
|
|
if (click_pending_update_grabs)
|
|
|
|
doClickGrabsUpdate();
|
2008-08-07 16:31:36 -07:00
|
|
|
if (focus_pending_raise)
|
|
|
|
FocusRaisePending();
|
2006-04-09 03:18:34 -07:00
|
|
|
}
|
|
|
|
|
2005-01-10 15:34:46 -08:00
|
|
|
static void
|
|
|
|
FocusSighan(int sig, void *prm __UNUSED__)
|
|
|
|
{
|
2008-05-24 11:13:17 -07:00
|
|
|
Timer *focus_init_timer;
|
|
|
|
|
2005-01-10 15:34:46 -08:00
|
|
|
switch (sig)
|
|
|
|
{
|
|
|
|
case ESIGNAL_START:
|
2005-03-05 06:25:50 -08:00
|
|
|
/* Delay focusing a bit to allow things to settle down */
|
2008-05-10 16:15:32 -07:00
|
|
|
IdlerAdd(_FocusIdler, NULL);
|
2008-05-24 11:13:17 -07:00
|
|
|
TIMER_ADD(focus_init_timer, 0.5, FocusInitTimeout, NULL);
|
2005-01-10 15:34:46 -08:00
|
|
|
break;
|
2005-03-05 06:25:50 -08:00
|
|
|
|
2005-01-10 15:34:46 -08:00
|
|
|
case ESIGNAL_EXIT:
|
|
|
|
FocusExit();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-12-28 15:46:49 -08:00
|
|
|
static void
|
2007-05-18 01:25:06 -07:00
|
|
|
FocusIpc(const char *params)
|
2004-12-28 15:46:49 -08:00
|
|
|
{
|
|
|
|
const char *p;
|
|
|
|
char cmd[128], prm[4096];
|
|
|
|
int len;
|
|
|
|
|
|
|
|
cmd[0] = prm[0] = '\0';
|
|
|
|
p = params;
|
|
|
|
if (p)
|
|
|
|
{
|
|
|
|
len = 0;
|
|
|
|
sscanf(p, "%100s %4000s %n", cmd, prm, &len);
|
|
|
|
p += len;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!p || cmd[0] == '?')
|
|
|
|
{
|
|
|
|
EWin *ewin;
|
|
|
|
|
|
|
|
ewin = GetFocusEwin();
|
|
|
|
if (ewin)
|
2006-08-07 13:20:16 -07:00
|
|
|
IpcPrintf("Focused: %#lx\n", EwinGetClientXwin(ewin));
|
2004-12-28 15:46:49 -08:00
|
|
|
else
|
|
|
|
IpcPrintf("Focused: none\n");
|
|
|
|
}
|
|
|
|
else if (!strncmp(cmd, "mode", 2))
|
|
|
|
{
|
|
|
|
int mode = Conf.focus.mode;
|
|
|
|
|
|
|
|
if (!strcmp(prm, "click"))
|
|
|
|
{
|
|
|
|
mode = MODE_FOCUS_CLICK;
|
|
|
|
Mode.grabs.pointer_grab_active = 1;
|
|
|
|
}
|
|
|
|
else if (!strcmp(prm, "clicknograb"))
|
|
|
|
{
|
|
|
|
mode = MODE_FOCUS_CLICK;
|
|
|
|
Mode.grabs.pointer_grab_active = 0;
|
|
|
|
}
|
|
|
|
else if (!strcmp(prm, "pointer"))
|
|
|
|
{
|
|
|
|
mode = MODE_FOCUS_POINTER;
|
|
|
|
}
|
|
|
|
else if (!strcmp(prm, "sloppy"))
|
|
|
|
{
|
|
|
|
mode = MODE_FOCUS_SLOPPY;
|
|
|
|
}
|
|
|
|
else if (!strcmp(prm, "?"))
|
|
|
|
{
|
|
|
|
if (Conf.focus.mode == MODE_FOCUS_CLICK)
|
|
|
|
{
|
|
|
|
if (Mode.grabs.pointer_grab_active)
|
|
|
|
p = "click";
|
|
|
|
else
|
|
|
|
p = "clicknograb";
|
|
|
|
}
|
|
|
|
else if (Conf.focus.mode == MODE_FOCUS_SLOPPY)
|
|
|
|
p = "sloppy";
|
|
|
|
else if (Conf.focus.mode == MODE_FOCUS_POINTER)
|
|
|
|
p = "pointer";
|
|
|
|
else
|
|
|
|
p = "unknown";
|
|
|
|
IpcPrintf("Focus Mode: %s\n", p);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
IpcPrintf("Error: unknown focus type\n");
|
|
|
|
}
|
|
|
|
if (Conf.focus.mode != mode)
|
|
|
|
{
|
|
|
|
Conf.focus.mode = mode;
|
2007-07-11 02:30:58 -07:00
|
|
|
ClickGrabsUpdate();
|
2004-12-28 15:46:49 -08:00
|
|
|
autosave();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (!strncmp(cmd, "next", 2))
|
|
|
|
{
|
2008-09-13 09:00:43 -07:00
|
|
|
/* Focus previously focused window */
|
2004-12-28 15:46:49 -08:00
|
|
|
if (Conf.warplist.enable)
|
|
|
|
WarpFocus(1);
|
|
|
|
else
|
2008-09-13 09:00:43 -07:00
|
|
|
FocusCycleEwin(1);
|
2004-12-28 15:46:49 -08:00
|
|
|
}
|
|
|
|
else if (!strncmp(cmd, "prev", 2))
|
|
|
|
{
|
2008-09-13 09:00:43 -07:00
|
|
|
/* Focus least recently focused window */
|
2005-07-13 12:39:22 -07:00
|
|
|
if (Conf.warplist.enable)
|
|
|
|
WarpFocus(-1);
|
|
|
|
else
|
2008-09-13 09:00:43 -07:00
|
|
|
FocusCycleEwin(-1);
|
2004-12-28 15:46:49 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-10-30 11:40:49 -08:00
|
|
|
static const IpcItem FocusIpcArray[] = {
|
2004-12-28 15:46:49 -08:00
|
|
|
{
|
|
|
|
FocusIpc,
|
|
|
|
"focus", "sf",
|
|
|
|
"Focus functions",
|
|
|
|
" focus ? Show focus info\n"
|
|
|
|
" focus mode Set focus mode. Modes:\n"
|
|
|
|
" click: The traditional click-to-focus mode.\n"
|
|
|
|
" clicknograb: A similar focus mode, but without the grabbing of the click\n"
|
|
|
|
" (you cannot click anywhere in a window to focus it)\n"
|
|
|
|
" pointer: The focus will follow the mouse pointer\n"
|
|
|
|
" sloppy: The focus follows the mouse, but when over the desktop background\n"
|
|
|
|
" the last window does not lose the focus\n"}
|
|
|
|
,
|
|
|
|
};
|
|
|
|
#define N_IPC_FUNCS (sizeof(FocusIpcArray)/sizeof(IpcItem))
|
|
|
|
|
|
|
|
static const CfgItem FocusCfgItems[] = {
|
|
|
|
CFG_ITEM_INT(Conf.focus, mode, MODE_FOCUS_SLOPPY),
|
2005-12-22 11:05:20 -08:00
|
|
|
CFG_ITEM_BOOL(Conf.focus, clickraises, 1),
|
2004-12-28 15:46:49 -08:00
|
|
|
CFG_ITEM_BOOL(Conf.focus, transientsfollowleader, 1),
|
|
|
|
CFG_ITEM_BOOL(Conf.focus, switchfortransientmap, 1),
|
|
|
|
CFG_ITEM_BOOL(Conf.focus, all_new_windows_get_focus, 0),
|
2010-05-02 13:26:54 -07:00
|
|
|
CFG_ITEM_BOOL(Conf.focus, new_windows_get_focus_if_group_focused, 1),
|
2004-12-28 15:46:49 -08:00
|
|
|
CFG_ITEM_BOOL(Conf.focus, new_transients_get_focus, 0),
|
|
|
|
CFG_ITEM_BOOL(Conf.focus, new_transients_get_focus_if_group_focused, 1),
|
|
|
|
CFG_ITEM_BOOL(Conf.focus, raise_on_next, 1),
|
|
|
|
CFG_ITEM_BOOL(Conf.focus, warp_on_next, 0),
|
2005-05-25 15:57:38 -07:00
|
|
|
CFG_ITEM_BOOL(Conf.focus, warp_always, 0),
|
2004-12-28 15:46:49 -08:00
|
|
|
|
|
|
|
CFG_ITEM_BOOL(Conf, autoraise.enable, 0),
|
|
|
|
CFG_ITEM_INT(Conf, autoraise.delay, 500),
|
|
|
|
};
|
|
|
|
#define N_CFG_ITEMS (sizeof(FocusCfgItems)/sizeof(CfgItem))
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Module descriptor
|
|
|
|
*/
|
2007-01-16 17:10:44 -08:00
|
|
|
extern const EModule ModFocus;
|
2006-04-21 15:52:59 -07:00
|
|
|
const EModule ModFocus = {
|
2004-12-28 15:46:49 -08:00
|
|
|
"focus", NULL,
|
2005-01-10 15:34:46 -08:00
|
|
|
FocusSighan,
|
2004-12-28 15:46:49 -08:00
|
|
|
{N_IPC_FUNCS, FocusIpcArray},
|
|
|
|
{N_CFG_ITEMS, FocusCfgItems}
|
|
|
|
};
|