2006-02-18 09:20:50 +00:00
|
|
|
// FocusControl.hh
|
|
|
|
// Copyright (c) 2006 Fluxbox Team (fluxgen at fluxbox dot org)
|
|
|
|
//
|
|
|
|
// 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:
|
|
|
|
//
|
|
|
|
// The above copyright notice and this permission notice shall be included in
|
|
|
|
// all copies or substantial portions of the Software.
|
|
|
|
//
|
|
|
|
// 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 OR COPYRIGHT HOLDERS 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.
|
|
|
|
|
|
|
|
#ifndef FOCUSCONTROL_HH
|
|
|
|
#define FOCUSCONTROL_HH
|
|
|
|
|
|
|
|
#include <list>
|
|
|
|
|
|
|
|
#include "FbTk/Resource.hh"
|
2007-11-12 21:59:43 +00:00
|
|
|
#include "FocusableList.hh"
|
2006-02-18 09:20:50 +00:00
|
|
|
|
2007-10-13 21:51:37 +00:00
|
|
|
class ClientPattern;
|
2006-02-18 09:20:50 +00:00
|
|
|
class WinClient;
|
|
|
|
class FluxboxWindow;
|
2007-10-13 21:51:37 +00:00
|
|
|
class Focusable;
|
2006-02-18 09:20:50 +00:00
|
|
|
class BScreen;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Handles window focus for a specific screen.
|
|
|
|
* It also holds the static "global" focused window
|
|
|
|
*/
|
|
|
|
class FocusControl {
|
|
|
|
public:
|
2007-10-13 21:51:37 +00:00
|
|
|
typedef std::list<Focusable *> Focusables;
|
2007-04-01 11:50:32 +00:00
|
|
|
/// main focus model
|
2006-02-18 09:20:50 +00:00
|
|
|
enum FocusModel {
|
2010-05-28 17:22:13 +00:00
|
|
|
MOUSEFOCUS = 0, ///< focus follows mouse, but only when the mouse is moving
|
|
|
|
CLICKFOCUS, ///< focus on click
|
|
|
|
STRICTMOUSEFOCUS ///< focus always follows mouse, even when stationary
|
2006-02-18 09:20:50 +00:00
|
|
|
};
|
2007-04-01 11:50:32 +00:00
|
|
|
/// focus model for tabs
|
2006-02-18 09:20:50 +00:00
|
|
|
enum TabFocusModel {
|
|
|
|
MOUSETABFOCUS = 0, ///< tab focus follows mouse
|
|
|
|
CLICKTABFOCUS ///< tab focus on click
|
|
|
|
};
|
|
|
|
|
2007-04-01 11:50:32 +00:00
|
|
|
/// focus direction for windows
|
2006-02-18 09:20:50 +00:00
|
|
|
enum FocusDir {
|
2007-04-01 11:50:32 +00:00
|
|
|
FOCUSUP, ///< window is above
|
|
|
|
FOCUSDOWN, ///< window is down
|
|
|
|
FOCUSLEFT, ///< window is left
|
|
|
|
FOCUSRIGHT ///< window is right
|
2006-02-18 09:20:50 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
explicit FocusControl(BScreen &screen);
|
2007-04-01 11:50:32 +00:00
|
|
|
/// cycle previous focuable
|
2007-07-17 21:21:17 +00:00
|
|
|
void prevFocus() { cycleFocus(m_focused_list, 0, true); }
|
2007-04-01 11:50:32 +00:00
|
|
|
/// cycle next focusable
|
2007-07-17 21:21:17 +00:00
|
|
|
void nextFocus() { cycleFocus(m_focused_list, 0, false); }
|
2007-04-01 11:50:32 +00:00
|
|
|
/**
|
|
|
|
* Cycle focus for a set of windows.
|
|
|
|
* @param winlist the windowlist to cycle through
|
2007-10-13 21:51:37 +00:00
|
|
|
* @param pat pattern for matching focusables
|
2007-04-01 11:50:32 +00:00
|
|
|
* @param reverse reverse the cycle order
|
|
|
|
*/
|
2007-11-12 21:59:43 +00:00
|
|
|
void cycleFocus(const FocusableList &winlist, const ClientPattern *pat = 0,
|
2007-10-13 21:51:37 +00:00
|
|
|
bool reverse = false);
|
|
|
|
|
2007-11-12 21:59:43 +00:00
|
|
|
void goToWindowNumber(const FocusableList &winlist, int num,
|
2007-10-13 21:51:37 +00:00
|
|
|
const ClientPattern *pat = 0);
|
2007-04-01 11:50:32 +00:00
|
|
|
/// sets the focused window on a screen
|
2006-02-18 09:20:50 +00:00
|
|
|
void setScreenFocusedWindow(WinClient &win_client);
|
2007-04-01 11:50:32 +00:00
|
|
|
/// sets the main focus model
|
2006-02-18 09:20:50 +00:00
|
|
|
void setFocusModel(FocusModel model);
|
2007-04-01 11:50:32 +00:00
|
|
|
/// sets tab focus model
|
2007-10-13 21:51:37 +00:00
|
|
|
void setTabFocusModel(TabFocusModel model);
|
2007-04-01 11:50:32 +00:00
|
|
|
/// stop cycling mode
|
2006-02-18 09:20:50 +00:00
|
|
|
void stopCyclingFocus();
|
2007-04-01 11:50:32 +00:00
|
|
|
/**
|
|
|
|
* Do directional focus mode.
|
|
|
|
* @param win current window
|
|
|
|
* @param dir direction from current window to focus.
|
|
|
|
*/
|
2006-02-18 09:20:50 +00:00
|
|
|
void dirFocus(FluxboxWindow &win, FocusDir dir);
|
2007-04-01 11:50:32 +00:00
|
|
|
/// @return true if focus mode is mouse focus
|
2010-05-28 17:22:13 +00:00
|
|
|
bool isMouseFocus() const { return focusModel() != CLICKFOCUS; }
|
2007-04-01 11:50:32 +00:00
|
|
|
/// @return true if tab focus mode is mouse tab focus
|
2006-02-18 09:20:50 +00:00
|
|
|
bool isMouseTabFocus() const { return tabFocusModel() == MOUSETABFOCUS; }
|
2009-01-30 15:41:27 +00:00
|
|
|
|
|
|
|
/// Set the "ignore" pointer location to the current pointer location
|
2010-05-28 19:50:15 +00:00
|
|
|
/// @param force If true, ignore even in StrictMouseFocus mode
|
|
|
|
void ignoreAtPointer(bool force = false);
|
2009-01-30 15:41:27 +00:00
|
|
|
/// Set the "ignore" pointer location to the given coordinates
|
2010-05-28 19:50:15 +00:00
|
|
|
/// @param x Current X position of the pointer
|
|
|
|
/// @param y Current Y position of the pointer
|
|
|
|
/// @param force If true, ignore even in StrictMouseFocus mode
|
|
|
|
void ignoreAt(int x, int y, bool force = false);
|
|
|
|
/// unset the "ignore" pointer location
|
|
|
|
void ignoreCancel();
|
2009-01-30 15:41:27 +00:00
|
|
|
/// @return true if events at the given X/Y coordinate should be ignored
|
|
|
|
/// (ie, they were previously cached via one of the ignoreAt calls)
|
|
|
|
bool isIgnored(int x, int y);
|
|
|
|
|
2007-04-01 11:50:32 +00:00
|
|
|
/// @return true if cycling is in progress
|
2007-03-01 21:19:04 +00:00
|
|
|
bool isCycling() const { return m_cycling_list != 0; }
|
2007-10-13 21:51:37 +00:00
|
|
|
/// Appends a client to the front of the focus list
|
2006-02-18 09:20:50 +00:00
|
|
|
void addFocusBack(WinClient &client);
|
2007-04-01 11:50:32 +00:00
|
|
|
/// Appends a client to the front of the focus list
|
2007-01-26 17:21:44 +00:00
|
|
|
void addFocusFront(WinClient &client);
|
2007-10-13 21:51:37 +00:00
|
|
|
void addFocusWinBack(Focusable &win);
|
|
|
|
void addFocusWinFront(Focusable &win);
|
2007-11-12 21:59:43 +00:00
|
|
|
void setFocusBack(FluxboxWindow &fbwin);
|
2007-04-01 11:50:32 +00:00
|
|
|
/// @return main focus model
|
2006-02-18 09:20:50 +00:00
|
|
|
FocusModel focusModel() const { return *m_focus_model; }
|
2007-04-01 11:50:32 +00:00
|
|
|
/// @return tab focus model
|
2006-02-18 09:20:50 +00:00
|
|
|
TabFocusModel tabFocusModel() const { return *m_tab_focus_model; }
|
2007-04-01 11:50:32 +00:00
|
|
|
/// @return true if newly created windows are focused
|
2006-02-18 09:20:50 +00:00
|
|
|
bool focusNew() const { return *m_focus_new; }
|
2012-11-18 19:09:35 +00:00
|
|
|
#ifdef XINERAMA
|
|
|
|
/// @return true if focus reverts to same head only
|
|
|
|
bool focusSameHead() const { return *m_focus_same_head; }
|
|
|
|
#endif // XINERAMA
|
2007-10-13 21:51:37 +00:00
|
|
|
|
2007-04-01 11:50:32 +00:00
|
|
|
/// @return last focused client in a specific workspace, or NULL.
|
2007-10-13 21:51:37 +00:00
|
|
|
Focusable *lastFocusedWindow(int workspace);
|
|
|
|
|
|
|
|
WinClient *lastFocusedWindow(FluxboxWindow &group, WinClient *ignore_client = 0);
|
2006-02-18 09:20:50 +00:00
|
|
|
|
2007-04-01 11:50:32 +00:00
|
|
|
/// @return focus list in creation order
|
2007-11-12 21:59:43 +00:00
|
|
|
const FocusableList &creationOrderList() const { return m_creation_order_list; }
|
2007-10-13 21:51:37 +00:00
|
|
|
/// @return the focus list in focused order
|
2007-11-12 21:59:43 +00:00
|
|
|
const FocusableList &focusedOrderList() const { return m_focused_list; }
|
|
|
|
const FocusableList &creationOrderWinList() const { return m_creation_order_win_list; }
|
|
|
|
const FocusableList &focusedOrderWinList() const { return m_focused_win_list; }
|
2007-10-13 21:51:37 +00:00
|
|
|
|
|
|
|
/// remove client from focus list
|
2006-02-18 09:20:50 +00:00
|
|
|
void removeClient(WinClient &client);
|
2007-10-13 21:51:37 +00:00
|
|
|
/// remove window from focus list
|
|
|
|
void removeWindow(Focusable &win);
|
2007-04-01 11:50:32 +00:00
|
|
|
/// starts terminating this control
|
2006-07-19 07:31:39 +00:00
|
|
|
void shutdown();
|
2007-10-13 21:51:37 +00:00
|
|
|
|
2007-04-01 11:50:32 +00:00
|
|
|
/// do fallback focus for screen if normal focus control failed.
|
2006-02-18 09:20:50 +00:00
|
|
|
static void revertFocus(BScreen &screen);
|
2006-02-18 20:19:22 +00:00
|
|
|
// like revertFocus, but specifically related to this window (transients etc)
|
|
|
|
static void unfocusWindow(WinClient &client, bool full_revert = true, bool unfocus_frame = false);
|
2006-02-18 09:20:50 +00:00
|
|
|
static void setFocusedWindow(WinClient *focus_to);
|
2006-06-29 18:01:33 +00:00
|
|
|
static void setFocusedFbWindow(FluxboxWindow *focus_to) { s_focused_fbwindow = focus_to; }
|
2008-01-13 00:47:40 +00:00
|
|
|
static void setExpectingFocus(WinClient *client) { s_expecting_focus = client; }
|
2006-02-18 09:20:50 +00:00
|
|
|
static WinClient *focusedWindow() { return s_focused_window; }
|
2006-06-29 18:01:33 +00:00
|
|
|
static FluxboxWindow *focusedFbWindow() { return s_focused_fbwindow; }
|
2008-01-13 00:47:40 +00:00
|
|
|
static WinClient *expectingFocus() { return s_expecting_focus; }
|
2006-02-18 09:20:50 +00:00
|
|
|
private:
|
|
|
|
|
|
|
|
BScreen &m_screen;
|
|
|
|
|
|
|
|
FbTk::Resource<FocusModel> m_focus_model;
|
|
|
|
FbTk::Resource<TabFocusModel> m_tab_focus_model;
|
2007-01-13 18:59:49 +00:00
|
|
|
FbTk::Resource<bool> m_focus_new;
|
2012-11-18 19:09:35 +00:00
|
|
|
#ifdef XINERAMA
|
|
|
|
FbTk::Resource<bool> m_focus_same_head;
|
|
|
|
#endif // XINERAMA
|
2006-02-18 09:20:50 +00:00
|
|
|
|
|
|
|
// This list keeps the order of window focusing for this screen
|
|
|
|
// Screen global so it works for sticky windows too.
|
2007-11-12 21:59:43 +00:00
|
|
|
FocusableList m_focused_list;
|
|
|
|
FocusableList m_creation_order_list;
|
|
|
|
FocusableList m_focused_win_list;
|
|
|
|
FocusableList m_creation_order_win_list;
|
2007-10-13 21:51:37 +00:00
|
|
|
|
2007-10-24 17:09:26 +00:00
|
|
|
Focusables::const_iterator m_cycling_window;
|
2007-11-12 21:59:43 +00:00
|
|
|
const FocusableList *m_cycling_list;
|
2007-10-13 21:51:37 +00:00
|
|
|
Focusable *m_was_iconic;
|
2006-02-18 09:20:50 +00:00
|
|
|
WinClient *m_cycling_last;
|
2016-06-30 20:10:29 +00:00
|
|
|
Focusable *m_cycling_next;
|
2009-01-30 15:41:27 +00:00
|
|
|
int m_ignore_mouse_x, m_ignore_mouse_y;
|
2006-02-18 09:20:50 +00:00
|
|
|
|
|
|
|
static WinClient *s_focused_window;
|
2006-06-28 00:54:40 +00:00
|
|
|
static FluxboxWindow *s_focused_fbwindow;
|
2008-01-13 00:47:40 +00:00
|
|
|
static WinClient *s_expecting_focus;
|
2007-01-13 19:24:35 +00:00
|
|
|
static bool s_reverting;
|
2006-02-18 09:20:50 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif // FOCUSCONTROL_HH
|