aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog3
-rw-r--r--data/windowmenu1
-rw-r--r--nls/C/Translation.m1
-rw-r--r--nls/en_GB/Translation.m1
-rw-r--r--nls/en_GB/generated-ISO-8859-1.m1
-rw-r--r--nls/en_GB/generated-UTF-8.m1
-rw-r--r--nls/en_US/Translation.m1
-rw-r--r--nls/en_US/generated-ISO-8859-1.m1
-rw-r--r--nls/en_US/generated-UTF-8.m1
-rw-r--r--nls/fluxbox-nls.hh1
-rw-r--r--src/CommandDialog.cc188
-rw-r--r--src/CommandDialog.hh36
-rw-r--r--src/CurrentWindowCmd.cc37
-rw-r--r--src/CurrentWindowCmd.hh18
-rw-r--r--src/Makefile.am1
-rw-r--r--src/MenuCreator.cc7
-rw-r--r--src/TextDialog.cc191
-rw-r--r--src/TextDialog.hh64
18 files changed, 354 insertions, 200 deletions
diff --git a/ChangeLog b/ChangeLog
index 7d7b265..3b37ef0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,8 @@
1 (Format: Year/Month/Day) 1 (Format: Year/Month/Day)
2Changes for 1.1 2Changes for 1.1
3*08/08/17:
4 * Add new key commands SetTitle and SetTitleDialog (thanks Matteo Galiazzo)
5 CommandDialog.cc/hh TextDialog.cc/hh CurrentWindowCmd.cc/hh Makefile.am
3*08/08/06: 6*08/08/06:
4 * Created manual for fluxbox-remote (Mark) 7 * Created manual for fluxbox-remote (Mark)
5 doc/asciidoc/fluxbox-remote.txt doc/fluxbox-remote.1 8 doc/asciidoc/fluxbox-remote.txt doc/fluxbox-remote.1
diff --git a/data/windowmenu b/data/windowmenu
index 9e52651..d867b64 100644
--- a/data/windowmenu
+++ b/data/windowmenu
@@ -5,6 +5,7 @@
5 [iconify] 5 [iconify]
6 [raise] 6 [raise]
7 [lower] 7 [lower]
8 [settitledialog]
8 [sendto] 9 [sendto]
9 [layer] 10 [layer]
10 [alpha] 11 [alpha]
diff --git a/nls/C/Translation.m b/nls/C/Translation.m
index 16a8bb7..df07dcd 100644
--- a/nls/C/Translation.m
+++ b/nls/C/Translation.m
@@ -215,6 +215,7 @@ $set 16 #Windowmenu
2159 Stick 2159 Stick
21610 Kill 21610 Kill
21711 Use Defaults 21711 Use Defaults
21812 Set Window Title
218 219
219$set 17 #Workspace 220$set 17 #Workspace
220 221
diff --git a/nls/en_GB/Translation.m b/nls/en_GB/Translation.m
index 16a8bb7..df07dcd 100644
--- a/nls/en_GB/Translation.m
+++ b/nls/en_GB/Translation.m
@@ -215,6 +215,7 @@ $set 16 #Windowmenu
2159 Stick 2159 Stick
21610 Kill 21610 Kill
21711 Use Defaults 21711 Use Defaults
21812 Set Window Title
218 219
219$set 17 #Workspace 220$set 17 #Workspace
220 221
diff --git a/nls/en_GB/generated-ISO-8859-1.m b/nls/en_GB/generated-ISO-8859-1.m
index 16a8bb7..df07dcd 100644
--- a/nls/en_GB/generated-ISO-8859-1.m
+++ b/nls/en_GB/generated-ISO-8859-1.m
@@ -215,6 +215,7 @@ $set 16 #Windowmenu
2159 Stick 2159 Stick
21610 Kill 21610 Kill
21711 Use Defaults 21711 Use Defaults
21812 Set Window Title
218 219
219$set 17 #Workspace 220$set 17 #Workspace
220 221
diff --git a/nls/en_GB/generated-UTF-8.m b/nls/en_GB/generated-UTF-8.m
index 9d48dfe..f15bc9a 100644
--- a/nls/en_GB/generated-UTF-8.m
+++ b/nls/en_GB/generated-UTF-8.m
@@ -215,6 +215,7 @@ $set 16 #Windowmenu
2159 Stick 2159 Stick
21610 Kill 21610 Kill
21711 Use Defaults 21711 Use Defaults
21812 Set Window Title
218 219
219$set 17 #Workspace 220$set 17 #Workspace
220 221
diff --git a/nls/en_US/Translation.m b/nls/en_US/Translation.m
index 16a8bb7..df07dcd 100644
--- a/nls/en_US/Translation.m
+++ b/nls/en_US/Translation.m
@@ -215,6 +215,7 @@ $set 16 #Windowmenu
2159 Stick 2159 Stick
21610 Kill 21610 Kill
21711 Use Defaults 21711 Use Defaults
21812 Set Window Title
218 219
219$set 17 #Workspace 220$set 17 #Workspace
220 221
diff --git a/nls/en_US/generated-ISO-8859-1.m b/nls/en_US/generated-ISO-8859-1.m
index 16a8bb7..df07dcd 100644
--- a/nls/en_US/generated-ISO-8859-1.m
+++ b/nls/en_US/generated-ISO-8859-1.m
@@ -215,6 +215,7 @@ $set 16 #Windowmenu
2159 Stick 2159 Stick
21610 Kill 21610 Kill
21711 Use Defaults 21711 Use Defaults
21812 Set Window Title
218 219
219$set 17 #Workspace 220$set 17 #Workspace
220 221
diff --git a/nls/en_US/generated-UTF-8.m b/nls/en_US/generated-UTF-8.m
index 9d48dfe..f15bc9a 100644
--- a/nls/en_US/generated-UTF-8.m
+++ b/nls/en_US/generated-UTF-8.m
@@ -215,6 +215,7 @@ $set 16 #Windowmenu
2159 Stick 2159 Stick
21610 Kill 21610 Kill
21711 Use Defaults 21711 Use Defaults
21812 Set Window Title
218 219
219$set 17 #Workspace 220$set 17 #Workspace
220 221
diff --git a/nls/fluxbox-nls.hh b/nls/fluxbox-nls.hh
index c205b76..0f3ad18 100644
--- a/nls/fluxbox-nls.hh
+++ b/nls/fluxbox-nls.hh
@@ -209,6 +209,7 @@ enum {
209 WindowmenuStick = 9, 209 WindowmenuStick = 9,
210 WindowmenuKill = 10, 210 WindowmenuKill = 10,
211 WindowmenuDefaultAlpha = 11, 211 WindowmenuDefaultAlpha = 11,
212 WindowmenuSetTitle = 12,
212 213
213 WorkspaceSet = 17, 214 WorkspaceSet = 17,
214 WorkspaceDefaultNameFormat = 1, 215 WorkspaceDefaultNameFormat = 1,
diff --git a/src/CommandDialog.cc b/src/CommandDialog.cc
index 5e7aa7d..bef8a63 100644
--- a/src/CommandDialog.cc
+++ b/src/CommandDialog.cc
@@ -22,24 +22,16 @@
22 22
23#include "CommandDialog.hh" 23#include "CommandDialog.hh"
24 24
25#include "Screen.hh"
26#include "FbWinFrameTheme.hh"
27#include "WinClient.hh"
28#include "FbTk/CommandParser.hh" 25#include "FbTk/CommandParser.hh"
29#include "FocusControl.hh"
30#include "fluxbox.hh"
31
32#include "FbTk/ImageControl.hh"
33#include "FbTk/EventManager.hh"
34#include "FbTk/StringUtil.hh" 26#include "FbTk/StringUtil.hh"
35#include "FbTk/KeyUtil.hh"
36#include "FbTk/App.hh" 27#include "FbTk/App.hh"
37 28
38#include <X11/keysym.h>
39#include <X11/Xutil.h> 29#include <X11/Xutil.h>
40 30
31#include <algorithm>
41#include <memory> 32#include <memory>
42#include <stdexcept> 33#include <stdexcept>
34#include <vector>
43 35
44using std::string; 36using std::string;
45using std::vector; 37using std::vector;
@@ -47,115 +39,31 @@ using std::auto_ptr;
47using std::less; 39using std::less;
48using std::out_of_range; 40using std::out_of_range;
49 41
50CommandDialog::CommandDialog(BScreen &screen, 42CommandDialog::CommandDialog(BScreen &screen, const string &title,
51 const string &title, const string precommand) : 43 const string precommand) :
52 FbTk::FbWindow(screen.rootWindow().screenNumber(), 0, 0, 200, 1, ExposureMask), 44 TextDialog(screen, title),
53 m_textbox(*this, screen.focusedWinFrameTheme()->font(), ""), 45 m_precommand(precommand) { }
54 m_label(*this, screen.focusedWinFrameTheme()->font(), title), 46
55 m_gc(m_textbox), 47void CommandDialog::exec(const std::string &text){
56 m_screen(screen), 48
57 m_move_x(0), 49 // create Command<void> from line
58 m_move_y(0), 50 auto_ptr<FbTk::Command<void> > cmd(FbTk::CommandParser<void>::instance().parse(m_precommand + text));
59 m_pixmap(0), 51 if (cmd.get())
60 m_precommand(precommand) { 52 cmd->execute();
61 init(); 53 // post execute
62 54 if (*m_postcommand != 0)
63} 55 m_postcommand->execute();
64
65CommandDialog::~CommandDialog() {
66 FbTk::EventManager::instance()->remove(*this);
67 hide();
68 if (m_pixmap != 0)
69 m_screen.imageControl().removeImage(m_pixmap);
70}
71
72void CommandDialog::setText(const string &text) {
73 m_textbox.setText(text);
74}
75
76void CommandDialog::show() {
77 FbTk::FbWindow::show();
78 m_textbox.setInputFocus();
79 m_label.clear();
80 Fluxbox::instance()->setShowingDialog(true);
81 // resize to correct width, which should be the width of label text
82 // no need to truncate label text in this dialog
83 // but if label text size < 200 we set 200
84 if (m_label.textWidth() < 200)
85 return;
86 else {
87 resize(m_label.textWidth(), height());
88 updateSizes();
89 render();
90 }
91}
92
93void CommandDialog::hide() {
94 FbTk::FbWindow::hide();
95 Fluxbox::instance()->setShowingDialog(false);
96}
97
98void CommandDialog::exposeEvent(XExposeEvent &event) {
99 if (event.window == window())
100 clearArea(event.x, event.y, event.width, event.height);
101}
102
103void CommandDialog::buttonPressEvent(XButtonEvent &event) {
104 m_textbox.setInputFocus();
105 m_move_x = event.x_root - x();
106 m_move_y = event.y_root - y();
107}
108
109void CommandDialog::handleEvent(XEvent &event) {
110 if (event.type == ConfigureNotify && event.xconfigure.window != window()) {
111 moveResize(event.xconfigure.x, event.xconfigure.y,
112 event.xconfigure.width, event.xconfigure.height);
113 } else if (event.type == DestroyNotify)
114 delete this;
115}
116
117void CommandDialog::motionNotifyEvent(XMotionEvent &event) {
118 int new_x = event.x_root - m_move_x;
119 int new_y = event.y_root - m_move_y;
120 move(new_x, new_y);
121}
122
123void CommandDialog::keyPressEvent(XKeyEvent &event) {
124 unsigned int state = FbTk::KeyUtil::instance().isolateModifierMask(event.state);
125 if (state)
126 return;
127
128 KeySym ks;
129 char keychar;
130 XLookupString(&event, &keychar, 1, &ks, 0);
131
132 if (ks == XK_Return) {
133 // create Command<void> from line
134 auto_ptr<FbTk::Command<void> > cmd(FbTk::CommandParser<void>::instance().parse(m_precommand + m_textbox.text()));
135 if (cmd.get())
136 cmd->execute();
137 // post execute
138 if (*m_postcommand != 0)
139 m_postcommand->execute();
140
141 delete this; // end this
142 } else if (ks == XK_Escape)
143 delete this; // end this
144 else if (ks == XK_Tab) {
145 // try to expand a command
146 tabComplete();
147 }
148} 56}
149 57
150void CommandDialog::tabComplete() { 58void CommandDialog::tabComplete() {
151 try { 59 try {
152 string::size_type first = m_textbox.text().find_last_not_of("ABCDEFGHIJKLMNOPQRSTUVWXYZ" 60 string::size_type first = m_textbox.text().find_last_not_of("ABCDEFGHIJKLMNOPQRSTUVWXYZ"
153 "abcdefghijklmnopqrstuvwxyz" 61 "abcdefghijklmnopqrstuvwxyz"
154 "0123456789", 62 "0123456789", m_textbox.cursorPosition());
155 m_textbox.cursorPosition());
156 if (first == string::npos) 63 if (first == string::npos)
157 first = 0; 64 first = 0;
158 string prefix = FbTk::StringUtil::toLower(m_textbox.text().substr(first, m_textbox.cursorPosition())); 65 string prefix = FbTk::StringUtil::toLower(m_textbox.text().substr(first,
66 m_textbox.cursorPosition()));
159 if (prefix.empty()) { 67 if (prefix.empty()) {
160 XBell(FbTk::App::instance()->display(), 0); 68 XBell(FbTk::App::instance()->display(), 0);
161 return; 69 return;
@@ -181,59 +89,3 @@ void CommandDialog::tabComplete() {
181 XBell(FbTk::App::instance()->display(), 0); 89 XBell(FbTk::App::instance()->display(), 0);
182 } 90 }
183} 91}
184
185void CommandDialog::render() {
186 Pixmap tmp = m_pixmap;
187 if (!m_screen.focusedWinFrameTheme()->iconbarTheme().texture().usePixmap()) {
188 m_label.setBackgroundColor(m_screen.focusedWinFrameTheme()->iconbarTheme().texture().color());
189 m_pixmap = 0;
190 } else {
191 m_pixmap = m_screen.imageControl().renderImage(m_label.width(), m_label.height(),
192 m_screen.focusedWinFrameTheme()->iconbarTheme().texture());
193 m_label.setBackgroundPixmap(m_pixmap);
194 }
195
196 if (tmp)
197 m_screen.imageControl().removeImage(tmp);
198
199}
200
201void CommandDialog::init() {
202
203
204 // setup label
205 // we listen to motion notify too
206 m_label.setEventMask(m_label.eventMask() | ButtonPressMask | ButtonMotionMask);
207 m_label.setGC(m_screen.focusedWinFrameTheme()->iconbarTheme().text().textGC());
208 m_label.show();
209
210 // setup text box
211 FbTk::Color white("white", m_textbox.screenNumber());
212 m_textbox.setBackgroundColor(white);
213 FbTk::Color black("black", m_textbox.screenNumber());
214 m_gc.setForeground(black);
215 m_textbox.setGC(m_gc.gc());
216 m_textbox.show();
217
218 // setup this window
219 setBorderWidth(1);
220 setBackgroundColor(white);
221 // move to center of the screen
222 move((m_screen.width() - width())/2, (m_screen.height() - height())/2);
223
224 updateSizes();
225 resize(width(), m_textbox.height() + m_label.height());
226
227 render();
228
229 // we need ConfigureNotify from children
230 FbTk::EventManager::instance()->addParent(*this, *this);
231}
232
233void CommandDialog::updateSizes() {
234 m_label.moveResize(0, 0,
235 width(), m_textbox.font().height() + 2);
236
237 m_textbox.moveResize(2, m_label.height(),
238 width() - 4, m_textbox.font().height() + 2);
239}
diff --git a/src/CommandDialog.hh b/src/CommandDialog.hh
index bd0a6df..0e12ce3 100644
--- a/src/CommandDialog.hh
+++ b/src/CommandDialog.hh
@@ -23,26 +23,20 @@
23#ifndef RUNCOMMANDDIALOG_HH 23#ifndef RUNCOMMANDDIALOG_HH
24#define RUNCOMMANDDIALOG_HH 24#define RUNCOMMANDDIALOG_HH
25 25
26#include "FbTk/TextBox.hh" 26#include "TextDialog.hh"
27#include "FbTk/TextButton.hh"
28#include "FbTk/GContext.hh"
29#include "FbTk/RefCount.hh" 27#include "FbTk/RefCount.hh"
30 28
31class BScreen;
32class Command; 29class Command;
33 30
34/** 31/**
35 * Displays a fluxbox command dialog which executes fluxbox 32 * Displays a fluxbox command dialog which executes fluxbox
36 * action commands. 33 * action commands.
37 */ 34 */
38class CommandDialog: public FbTk::FbWindow, public FbTk::EventHandler { 35class CommandDialog: public TextDialog {
39public: 36public:
40 CommandDialog(BScreen &screen, const std::string &title, 37 CommandDialog(BScreen &screen, const std::string &title,
41 const std::string pre_command = ""); 38 const std::string pre_command = "");
42 virtual ~CommandDialog(); 39
43
44 /// Sets the entry text.
45 void setText(const std::string &text);
46 /** 40 /**
47 * Sets the command to be executed after the command is done. 41 * Sets the command to be executed after the command is done.
48 * @param postcommand the command. 42 * @param postcommand the command.
@@ -50,32 +44,14 @@ public:
50 void setPostCommand(FbTk::RefCount<FbTk::Command<void> > &postcommand) { 44 void setPostCommand(FbTk::RefCount<FbTk::Command<void> > &postcommand) {
51 m_postcommand = postcommand; 45 m_postcommand = postcommand;
52 } 46 }
53 void show();
54 void hide();
55
56 void exposeEvent(XExposeEvent &event);
57 void motionNotifyEvent(XMotionEvent &event);
58 void buttonPressEvent(XButtonEvent &event);
59 void handleEvent(XEvent &event);
60 void keyPressEvent(XKeyEvent &event);
61
62protected:
63 /// expand the current word, using the history as a references
64 virtual void tabComplete();
65 47
66private: 48private:
67 void init(); 49 /// expand the current word, using the history as a references
68 void render(); 50 void tabComplete();
69 void updateSizes(); 51 void exec(const std::string &string);
70 52
71 FbTk::TextBox m_textbox; //< entry field
72 FbTk::TextButton m_label; //< text in the titlebar
73 FbTk::GContext m_gc;
74 /// command to do after the first command was issued (like reconfigure) 53 /// command to do after the first command was issued (like reconfigure)
75 FbTk::RefCount<FbTk::Command<void> > m_postcommand; 54 FbTk::RefCount<FbTk::Command<void> > m_postcommand;
76 BScreen &m_screen;
77 int m_move_x, m_move_y;
78 Pixmap m_pixmap;
79 /// command to be used before the text (usefull for setting workspace name) 55 /// command to be used before the text (usefull for setting workspace name)
80 const std::string m_precommand; 56 const std::string m_precommand;
81}; 57};
diff --git a/src/CurrentWindowCmd.cc b/src/CurrentWindowCmd.cc
index 65c5711..f8c7b4b 100644
--- a/src/CurrentWindowCmd.cc
+++ b/src/CurrentWindowCmd.cc
@@ -27,10 +27,12 @@
27#include "Window.hh" 27#include "Window.hh"
28#include "WindowCmd.hh" 28#include "WindowCmd.hh"
29#include "Screen.hh" 29#include "Screen.hh"
30#include "TextDialog.hh"
30#include "WinClient.hh" 31#include "WinClient.hh"
31 32
32#include "FocusControl.hh" 33#include "FocusControl.hh"
33#include "FbTk/CommandParser.hh" 34#include "FbTk/CommandParser.hh"
35#include "FbTk/I18n.hh"
34#include "FbTk/stringstream.hh" 36#include "FbTk/stringstream.hh"
35#include "FbTk/StringUtil.hh" 37#include "FbTk/StringUtil.hh"
36 38
@@ -483,7 +485,6 @@ void ResizeToCmd::real_execute() {
483 485
484REGISTER_COMMAND(fullscreen, FullscreenCmd, void); 486REGISTER_COMMAND(fullscreen, FullscreenCmd, void);
485 487
486FullscreenCmd::FullscreenCmd() { }
487void FullscreenCmd::real_execute() { 488void FullscreenCmd::real_execute() {
488 fbwindow().setFullscreen(!fbwindow().isFullscreen()); 489 fbwindow().setFullscreen(!fbwindow().isFullscreen());
489} 490}
@@ -500,6 +501,40 @@ void SetLayerCmd::real_execute() {
500 fbwindow().moveToLayer(m_layer); 501 fbwindow().moveToLayer(m_layer);
501} 502}
502 503
504namespace {
505class SetTitleDialog: public TextDialog {
506public:
507 SetTitleDialog(FluxboxWindow &win, const string &title):
508 TextDialog(win.screen(), title), window(win) {
509 setText(win.title());
510 }
511
512private:
513 void exec(const std::string &text) {
514 window.winClient().setTitle(text);
515 }
516
517 FluxboxWindow &window;
518};
519} // end anonymous namespace
520
521REGISTER_COMMAND(settitledialog, SetTitleDialogCmd, void);
522
523void SetTitleDialogCmd::real_execute() {
524 _FB_USES_NLS;
525
526 SetTitleDialog *win = new SetTitleDialog(fbwindow(),
527 _FB_XTEXT(Windowmenu, SetTitle, "Set Title",
528 "Change the title of the window"));
529 win->show();
530}
531
532REGISTER_COMMAND_WITH_ARGS(settitle, SetTitleCmd, void);
533
534void SetTitleCmd::real_execute() {
535 fbwindow().winClient().setTitle(title);
536}
537
503FbTk::Command<void> *SetAlphaCmd::parse(const string &command, const string &args, 538FbTk::Command<void> *SetAlphaCmd::parse(const string &command, const string &args,
504 bool trusted) { 539 bool trusted) {
505 typedef std::vector<string> StringTokens; 540 typedef std::vector<string> StringTokens;
diff --git a/src/CurrentWindowCmd.hh b/src/CurrentWindowCmd.hh
index d70e2fb..4c3f91b 100644
--- a/src/CurrentWindowCmd.hh
+++ b/src/CurrentWindowCmd.hh
@@ -240,11 +240,27 @@ private:
240 240
241class FullscreenCmd: public WindowHelperCmd{ 241class FullscreenCmd: public WindowHelperCmd{
242public: 242public:
243 explicit FullscreenCmd(); 243 explicit FullscreenCmd() { }
244protected: 244protected:
245 void real_execute(); 245 void real_execute();
246}; 246};
247 247
248class SetTitleDialogCmd: public WindowHelperCmd {
249public:
250 explicit SetTitleDialogCmd() { }
251protected:
252 void real_execute();
253};
254
255class SetTitleCmd: public WindowHelperCmd {
256public:
257 explicit SetTitleCmd(std::string newtitle): title(newtitle) { }
258protected:
259 void real_execute();
260private:
261 std::string title;
262};
263
248class SetAlphaCmd: public WindowHelperCmd { 264class SetAlphaCmd: public WindowHelperCmd {
249public: 265public:
250 SetAlphaCmd(int focus, bool rel, int unfocus, bool unrel); 266 SetAlphaCmd(int focus, bool rel, int unfocus, bool unrel);
diff --git a/src/Makefile.am b/src/Makefile.am
index b53af38..448a781 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -124,6 +124,7 @@ fluxbox_SOURCES = AtomHandler.hh ArrowButton.hh ArrowButton.cc \
124 Xutil.hh Xutil.cc \ 124 Xutil.hh Xutil.cc \
125 CurrentWindowCmd.hh CurrentWindowCmd.cc \ 125 CurrentWindowCmd.hh CurrentWindowCmd.cc \
126 WorkspaceCmd.hh WorkspaceCmd.cc \ 126 WorkspaceCmd.hh WorkspaceCmd.cc \
127 TextDialog.hh TextDialog.cc \
127 CommandDialog.hh CommandDialog.cc SendToMenu.hh SendToMenu.cc \ 128 CommandDialog.hh CommandDialog.cc SendToMenu.hh SendToMenu.cc \
128 AlphaMenu.hh AlphaMenu.cc ObjectResource.hh \ 129 AlphaMenu.hh AlphaMenu.cc ObjectResource.hh \
129 CompareWindow.hh \ 130 CompareWindow.hh \
diff --git a/src/MenuCreator.cc b/src/MenuCreator.cc
index 34dce94..db9aca2 100644
--- a/src/MenuCreator.cc
+++ b/src/MenuCreator.cc
@@ -28,6 +28,7 @@
28#include "fluxbox.hh" 28#include "fluxbox.hh"
29#include "Window.hh" 29#include "Window.hh"
30#include "WindowCmd.hh" 30#include "WindowCmd.hh"
31#include "CurrentWindowCmd.hh"
31#include "WindowMenuAccessor.hh" 32#include "WindowMenuAccessor.hh"
32 33
33#include "ClientMenu.hh" 34#include "ClientMenu.hh"
@@ -492,6 +493,12 @@ bool MenuCreator::createWindowMenuItem(const string &type,
492 _FB_XTEXT(Windowmenu, Stick, 493 _FB_XTEXT(Windowmenu, Stick,
493 "Stick", "Stick the window"): 494 "Stick", "Stick the window"):
494 label, res)); 495 label, res));
496 } else if (type == "settitledialog") {
497 RefCmd setname_cmd(new SetTitleDialogCmd());
498 menu.insert(label.empty() ?
499 _FB_XTEXT(Windowmenu, SetTitle,
500 "Set Title", "Change the title of the window"):
501 label, setname_cmd);
495#ifdef HAVE_XRENDER 502#ifdef HAVE_XRENDER
496 } else if (type == "alpha") { 503 } else if (type == "alpha") {
497 if (FbTk::Transparent::haveComposite() || 504 if (FbTk::Transparent::haveComposite() ||
diff --git a/src/TextDialog.cc b/src/TextDialog.cc
new file mode 100644
index 0000000..7f95c13
--- /dev/null
+++ b/src/TextDialog.cc
@@ -0,0 +1,191 @@
1// TextDialog.cc
2// Copyright (c) 2008 Fluxbox Team (fluxgen at fluxbox dot org)
3//
4// Permission is hereby granted, free of charge, to any person obtaining a
5// copy of this software and associated documentation files (the "Software"),
6// to deal in the Software without restriction, including without limitation
7// the rights to use, copy, modify, merge, publish, distribute, sublicense,
8// and/or sell copies of the Software, and to permit persons to whom the
9// Software is furnished to do so, subject to the following conditions:
10//
11// The above copyright notice and this permission notice shall be included in
12// all copies or substantial portions of the Software.
13//
14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20// DEALINGS IN THE SOFTWARE.
21
22#include "TextDialog.hh"
23
24#include "Screen.hh"
25#include "FbWinFrameTheme.hh"
26#include "fluxbox.hh"
27
28#include "FbTk/ImageControl.hh"
29#include "FbTk/EventManager.hh"
30#include "FbTk/KeyUtil.hh"
31
32#include <X11/keysym.h>
33#include <X11/Xutil.h>
34
35#include <memory>
36#include <stdexcept>
37
38using std::string;
39
40/**
41 * This is an abstract class providing a text box dialog
42 */
43
44TextDialog::TextDialog(BScreen &screen,
45 const string &title) :
46 FbTk::FbWindow(screen.rootWindow().screenNumber(), 0, 0, 200, 1, ExposureMask),
47 m_textbox(*this, screen.focusedWinFrameTheme()->font(), ""),
48 m_label(*this, screen.focusedWinFrameTheme()->font(), title),
49 m_gc(m_textbox),
50 m_screen(screen),
51 m_move_x(0),
52 m_move_y(0),
53 m_pixmap(0){
54 init();
55}
56
57
58TextDialog::~TextDialog() {
59 FbTk::EventManager::instance()->remove(*this);
60 hide();
61 if (m_pixmap != 0)
62 m_screen.imageControl().removeImage(m_pixmap);
63}
64
65
66void TextDialog::setText(const string &text) {
67 m_textbox.setText(text);
68}
69
70void TextDialog::show() {
71 FbTk::FbWindow::show();
72 m_textbox.setInputFocus();
73 m_label.clear();
74 Fluxbox::instance()->setShowingDialog(true);
75 // resize to correct width, which should be the width of label text
76 // no need to truncate label text in this dialog
77 // but if label text size < 200 we set 200
78 if (m_label.textWidth() < 200)
79 return;
80 else {
81 resize(m_label.textWidth(), height());
82 updateSizes();
83 render();
84 }
85}
86
87void TextDialog::hide() {
88 FbTk::FbWindow::hide();
89 Fluxbox::instance()->setShowingDialog(false);
90}
91
92void TextDialog::exposeEvent(XExposeEvent &event) {
93 if (event.window == window())
94 clearArea(event.x, event.y, event.width, event.height);
95}
96
97void TextDialog::buttonPressEvent(XButtonEvent &event) {
98 m_textbox.setInputFocus();
99 m_move_x = event.x_root - x();
100 m_move_y = event.y_root - y();
101}
102
103void TextDialog::handleEvent(XEvent &event) {
104 if (event.type == ConfigureNotify && event.xconfigure.window != window()) {
105 moveResize(event.xconfigure.x, event.xconfigure.y,
106 event.xconfigure.width, event.xconfigure.height);
107 } else if (event.type == DestroyNotify)
108 delete this;
109}
110
111void TextDialog::motionNotifyEvent(XMotionEvent &event) {
112 int new_x = event.x_root - m_move_x;
113 int new_y = event.y_root - m_move_y;
114 move(new_x, new_y);
115}
116
117void TextDialog::keyPressEvent(XKeyEvent &event) {
118 unsigned int state = FbTk::KeyUtil::instance().isolateModifierMask(event.state);
119 if (state)
120 return;
121
122 KeySym ks;
123 char keychar;
124 XLookupString(&event, &keychar, 1, &ks, 0);
125
126 if (ks == XK_Return) {
127 exec(m_textbox.text());
128 delete this;
129 } else if (ks == XK_Escape)
130 delete this; // end this
131 else if (ks == XK_Tab) {
132 // try to expand a command
133 tabComplete();
134 }
135
136}
137
138void TextDialog::render() {
139 Pixmap tmp = m_pixmap;
140 if (!m_screen.focusedWinFrameTheme()->iconbarTheme().texture().usePixmap()) {
141 m_label.setBackgroundColor(m_screen.focusedWinFrameTheme()->iconbarTheme().texture().color());
142 m_pixmap = 0;
143 } else {
144 m_pixmap = m_screen.imageControl().renderImage(m_label.width(), m_label.height(),
145 m_screen.focusedWinFrameTheme()->iconbarTheme().texture());
146 m_label.setBackgroundPixmap(m_pixmap);
147 }
148
149 if (tmp)
150 m_screen.imageControl().removeImage(tmp);
151
152}
153
154void TextDialog::init() {
155
156 // setup label
157 // we listen to motion notify too
158 m_label.setEventMask(m_label.eventMask() | ButtonPressMask | ButtonMotionMask);
159 m_label.setGC(m_screen.focusedWinFrameTheme()->iconbarTheme().text().textGC());
160 m_label.show();
161
162 // setup text box
163 FbTk::Color white("white", m_textbox.screenNumber());
164 m_textbox.setBackgroundColor(white);
165 FbTk::Color black("black", m_textbox.screenNumber());
166 m_gc.setForeground(black);
167 m_textbox.setGC(m_gc.gc());
168 m_textbox.show();
169
170 // setup this window
171 setBorderWidth(1);
172 setBackgroundColor(white);
173 // move to center of the screen
174 move((m_screen.width() - width())/2, (m_screen.height() - height())/2);
175
176 updateSizes();
177 resize(width(), m_textbox.height() + m_label.height());
178
179 render();
180
181 // we need ConfigureNotify from children
182 FbTk::EventManager::instance()->addParent(*this, *this);
183}
184
185void TextDialog::updateSizes() {
186 m_label.moveResize(0, 0,
187 width(), m_textbox.font().height() + 2);
188
189 m_textbox.moveResize(2, m_label.height(),
190 width() - 4, m_textbox.font().height() + 2);
191}
diff --git a/src/TextDialog.hh b/src/TextDialog.hh
new file mode 100644
index 0000000..41579b1
--- /dev/null
+++ b/src/TextDialog.hh
@@ -0,0 +1,64 @@
1// CommandDialog.hh
2// Copyright (c) 2008 Fluxbox Team (fluxgen at fluxbox dot org)
3//
4// Permission is hereby granted, free of charge, to any person obtaining a
5// copy of this software and associated documentation files (the "Software"),
6// to deal in the Software without restriction, including without limitation
7// the rights to use, copy, modify, merge, publish, distribute, sublicense,
8// and/or sell copies of the Software, and to permit persons to whom the
9// Software is furnished to do so, subject to the following conditions:
10//
11// The above copyright notice and this permission notice shall be included in
12// all copies or substantial portions of the Software.
13//
14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20// DEALINGS IN THE SOFTWARE.
21
22#ifndef TEXTDIALOG_HH
23#define TEXTDIALOG_HH
24
25#include "FbTk/TextBox.hh"
26#include "FbTk/TextButton.hh"
27#include "FbTk/GContext.hh"
28
29class BScreen;
30
31class TextDialog: public FbTk::FbWindow, public FbTk::EventHandler {
32public:
33 TextDialog(BScreen &screen, const std::string &title);
34 virtual ~TextDialog();
35
36 /// Sets the entry text.
37 void setText(const std::string &text);
38
39 void show();
40 void hide();
41
42 void exposeEvent(XExposeEvent &event);
43 void motionNotifyEvent(XMotionEvent &event);
44 void buttonPressEvent(XButtonEvent &event);
45 void handleEvent(XEvent &event);
46 void keyPressEvent(XKeyEvent &event);
47
48protected:
49 virtual void exec(const std::string &text) = 0;
50 virtual void tabComplete() { }
51
52 void init();
53 void render();
54 void updateSizes();
55
56 FbTk::TextBox m_textbox; //< entry field
57 FbTk::TextButton m_label; //< text in the titlebar
58 FbTk::GContext m_gc;
59 BScreen &m_screen;
60 int m_move_x, m_move_y;
61 Pixmap m_pixmap;
62};
63
64#endif // TEXTDIALOG_HH