-
Notifications
You must be signed in to change notification settings - Fork 174
Expand file tree
/
Copy pathxcbmenu.h
More file actions
137 lines (110 loc) · 3.56 KB
/
Copy pathxcbmenu.h
File metadata and controls
137 lines (110 loc) · 3.56 KB
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
128
129
130
131
132
133
134
135
136
137
/*
* SPDX-FileCopyrightText: 2017-2017 CSSlayer <wengxt@gmail.com>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
*/
#ifndef _FCITX_UI_CLASSIC_XCBMENU_H_
#define _FCITX_UI_CLASSIC_XCBMENU_H_
#include <cstddef>
#include <memory>
#include <unordered_map>
#include <utility>
#include <vector>
#include <pango/pango-layout.h>
#include <pango/pango-types.h>
#include <xcb/xcb.h>
#include "fcitx-utils/eventloopinterface.h"
#include "fcitx-utils/rect.h"
#include "fcitx-utils/signals.h"
#include "fcitx-utils/trackableobject.h"
#include "fcitx/action.h"
#include "fcitx/inputcontext.h"
#include "fcitx/menu.h"
#include "common.h"
#include "xcbui.h"
#include "xcbwindow.h"
namespace fcitx::classicui {
class MenuPool;
struct MenuItem {
MenuItem(PangoContext *context) : layout_(pango_layout_new(context)) {}
bool hasSubMenu_ = false;
bool isHighlight_ = false;
bool isSeparator_ = false;
bool isChecked_ = false;
GObjectUniquePtr<PangoLayout> layout_;
int layoutX_ = 0, layoutY_ = 0;
Rect region_;
int textWidth_ = 0, textHeight_ = 0;
int checkBoxX_ = 0, checkBoxY_ = 0;
int subMenuX_ = 0, subMenuY_ = 0;
};
enum class ConstrainAdjustment { Slide, Flip };
class XCBMenu : public XCBWindow, public TrackableObject<XCBMenu> {
public:
XCBMenu(XCBUI *ui, MenuPool *pool, Menu *menu);
~XCBMenu();
void show(Rect rect, ConstrainAdjustment adjustY);
// Hide menu itself.
void hide();
// Hide all of its parent.
void hideParents();
// Hide all menu on the chain until the one has mouse.
void hideTillMenuHasMouseOrTopLevel();
// Hide all of its child.
void hideChilds();
void hideAll();
// Raise the menu.
void raise();
bool filterEvent(xcb_generic_event_t *event) override;
void postCreateWindow() override;
void setParent(XCBMenu *parent);
void setInputContext(TrackableObjectReference<InputContext> ic);
TrackableObjectReference<InputContext> inputContext() const {
return lastRelevantIc_;
}
bool childHasMouse() const;
private:
void handleButtonPress(int eventX, int eventY);
void handleMotionNotify(int eventX, int eventY);
XCBMenu *childByPosition(int rootX, int rootY);
void hideTillMenuHasMouseOrTopLevelHelper();
InputContext *lastRelevantIc();
void update();
void setHoveredIndex(int idx);
void setChild(XCBMenu *child);
void updateDPI(int x, int y);
double scale() const override;
std::pair<MenuItem *, Action *> actionAt(size_t index);
MenuPool *pool_;
GObjectUniquePtr<PangoFontMap> fontMap_;
GObjectUniquePtr<PangoContext> context_;
std::vector<MenuItem> items_;
ScopedConnection destroyed_;
TrackableObjectReference<InputContext> lastRelevantIc_;
Menu *menu_;
TrackableObjectReference<XCBMenu> parent_;
TrackableObjectReference<XCBMenu> child_;
int dpi_ = -1;
double fontMapDefaultDPI_ = 96.0;
int x_ = 0;
int y_ = 0;
bool hasMouse_ = false;
bool visible_ = false;
int subMenuIndex_ = -1;
int hoveredIndex_ = -1;
std::unique_ptr<EventSourceTime> activateTimer_;
};
class MenuPool {
public:
XCBMenu *requestMenu(XCBUI *ui, Menu *menu, XCBMenu *parent);
void setPopupMenuTimer(std::unique_ptr<EventSourceTime> popupMenuTimer) {
popupMenuTimer_ = std::move(popupMenuTimer);
}
private:
XCBMenu *findOrCreateMenu(XCBUI *ui, Menu *menu);
std::unordered_map<Menu *, std::pair<XCBMenu, ScopedConnection>> pool_;
std::unique_ptr<EventSourceTime> popupMenuTimer_;
};
} // namespace fcitx::classicui
#endif // _FCITX_UI_CLASSIC_XCBMENU_H_