1 #ifndef __HERBSTLUFT_TAG_H_
2 #define __HERBSTLUFT_TAG_H_
3 
4 #include <memory>
5 #include <vector>
6 
7 #include "attribute_.h"
8 #include "child.h"
9 #include "object.h"
10 #include "signal.h"
11 
12 #define TAG_SET_FLAG(tag, flag) \
13     ((tag)->flags |= (flag))
14 
15 enum {
16     TAG_FLAG_URGENT = 0x01, // is there a urgent window?
17     TAG_FLAG_USED   = 0x02, // the opposite of empty
18 };
19 
20 class Client;
21 class Completion;
22 class FrameLeaf;
23 class FrameTree;
24 class Settings;
25 class Stack;
26 class TagManager;
27 
28 class HSTag : public Object {
29 public:
30     HSTag(std::string name, TagManager* tags, Settings* settings);
31     ~HSTag() override;
32     Child_<FrameTree>        frame;  // the frame tree
33     Attribute_<unsigned long> index;
34     Attribute_<bool>         visible;
35     Attribute_<bool>         floating;
36     Attribute_<bool>         floating_focused; // if a floating client is focused
37     Attribute_<std::string>  name;   // name of this tag
38     DynAttribute_<int> frame_count;
39     DynAttribute_<int> client_count;
40     DynAttribute_<int> urgent_count; //! The number of urgent clients
41     DynAttribute_<int> curframe_windex;
42     DynAttribute_<int> curframe_wcount;
43     DynChild_<Client> focused_client;
44     int             flags;
45     std::vector<Client*> floating_clients_; //! the clients in floating mode
46     // the tag must assert that the floating layer is only
47     // focused if this tag hasVisibleFloatingClients()
48     size_t               floating_clients_focus_; //! focus in the floating clients
49     std::shared_ptr<Stack> stack;
50     void setIndexAttribute(unsigned long new_index) override;
51     bool focusClient(Client* client);
52     void applyClientState(Client* client);
53     void setVisible(bool newVisible);
54     bool removeClient(Client* client);
55     bool hasVisibleFloatingClients() const;
56     void foreachClient(std::function<void(Client*)> loopBody);
57     void focusFrame(std::shared_ptr<FrameLeaf> frameToFocus);
58     Client* focusedClient();
59     std::string oldName_;  // Previous name of the tag, in case it got renamed
60 
61     void insertClient(Client* client, std::string frameIndex = {}, bool focus = true);
62     Signal needsRelayout_;
63 
64     //! add the client's slice to this tag's stack
65     void insertClientSlice(Client* client);
66     //! remove the client's slice from this tag's stack
67     void removeClientSlice(Client* client);
68 
69     int focusInDirCommand(Input input, Output output);
70     void focusInDirCompletion(Completion& complete);
71     int shiftInDirCommand(Input input, Output output);
72     void shiftInDirCompletion(Completion& complete);
73 
74     int cycleAllCommand(Input input, Output output);
75     void cycleAllCompletion(Completion& complete);
76 
77     int resizeCommand(Input input, Output output);
78     void resizeCompletion(Completion& complete);
79 
80     int closeAndRemoveCommand();
81     int closeOrRemoveCommand();
82 private:
83     std::string isValidTagIndex(unsigned long newIndex);
84     std::string floatingLayerCanBeFocused(bool floatingFocused);
85     void onGlobalFloatingChange(bool newState);
86     void fixFocusIndex();
87     //! get the number of clients on this tag
88     int computeClientCount();
89     //! get the number of clients on this tag
90     int computeFrameCount();
91     //! get the number of urgent clients on this tag
92     int countUrgentClients();
93     TagManager* tags_;
94     Settings* settings_;
95 };
96 
97 // for tags
98 HSTag* find_tag(const char* name);
99 HSTag* get_tag_by_index(int index);
100 int    tag_get_count();
101 void tag_force_update_flags();
102 void tag_update_flags();
103 void tag_set_flags_dirty();
104 
105 #endif
106 
107