summaryrefslogtreecommitdiff
path: root/src/FocusControl.hh
blob: d76b51dcdf2d60c2f23b0d8161c36f20f7db208d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
// 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.

// $Id$

#ifndef FOCUSCONTROL_HH
#define FOCUSCONTROL_HH

#include <list>

#include "FbTk/Resource.hh"

class WinClient;
class FluxboxWindow;
class BScreen;

/**
 * Handles window focus for a specific screen.
 * It also holds the static "global" focused window
 */
class FocusControl {
public:
    typedef std::list<WinClient *> FocusedWindows;

    enum FocusModel { 
        MOUSEFOCUS = 0, ///< focus follows 
        CLICKFOCUS ///< focus on click
    };
    enum TabFocusModel { 
        MOUSETABFOCUS = 0, ///< tab focus follows mouse
        CLICKTABFOCUS  ///< tab focus on click
    };

    enum FocusDir { 
        FOCUSUP,
        FOCUSDOWN,
        FOCUSLEFT, 
        FOCUSRIGHT 
    };

    // prevFocus/nextFocus option bits
    enum { 
        CYCLEGROUPS = 0x01, 
        CYCLESKIPSTUCK = 0x02, 
        CYCLESKIPSHADED = 0x04,
        CYCLELINEAR = 0x08, 
        CYCLEDEFAULT = 0x00 
    };

    explicit FocusControl(BScreen &screen);

    void prevFocus() { cycleFocus(0, true); }
    void nextFocus() { cycleFocus(0, false); }
    void prevFocus(int options) { cycleFocus(options, true); }
    void nextFocus(int options) { cycleFocus(options, false); }
    void cycleFocus(int options, bool cycle_reverse);

    void setScreenFocusedWindow(WinClient &win_client);
    void setFocusModel(FocusModel model);
    void setTabFocusModel(TabFocusModel model);

    void stopCyclingFocus();

    void dirFocus(FluxboxWindow &win, FocusDir dir);
    bool isMouseFocus() const { return focusModel() == MOUSEFOCUS; }
    bool isMouseTabFocus() const { return tabFocusModel() == MOUSETABFOCUS; }
    bool isCycling() const { return m_cycling_focus; }
    void addFocusFront(WinClient &client);
    void addFocusBack(WinClient &client);

    FocusModel focusModel() const { return *m_focus_model; }
    TabFocusModel tabFocusModel() const { return *m_tab_focus_model; }
    bool focusLast() const { return *m_focus_last; }
    bool focusNew() const { return *m_focus_new; }

    WinClient *lastFocusedWindow(int workspace);
    WinClient *lastFocusedWindow(FluxboxWindow &group, WinClient *ignore_client);

    void removeClient(WinClient &client);

    static void revertFocus(BScreen &screen);
    // like revertFocus, but specifically related to this window (transients etc)
    static void unfocusWindow(WinClient &client, bool full_revert = true, bool unfocus_frame = false);
    static void setFocusedWindow(WinClient *focus_to);
    static void setFocusedFbWindow(FluxboxWindow *focus_to) { s_focused_fbwindow = focus_to; }
    static WinClient *focusedWindow() { return s_focused_window; }
    static FluxboxWindow *focusedFbWindow() { return s_focused_fbwindow; }
private:

    BScreen &m_screen;

    FbTk::Resource<FocusModel> m_focus_model;    
    FbTk::Resource<TabFocusModel> m_tab_focus_model;
    FbTk::Resource<bool> m_focus_last, m_focus_new;

    // This list keeps the order of window focusing for this screen
    // Screen global so it works for sticky windows too.
    FocusedWindows m_focused_list;
    FocusedWindows m_creation_order_list;
    FocusedWindows::iterator m_cycling_window;
    bool m_cycling_focus;
    bool m_cycling_creation_order;
    WinClient *m_cycling_last;

    static WinClient *s_focused_window;
    static FluxboxWindow *s_focused_fbwindow;
};

#endif // FOCUSCONTROL_HH