~jamespharaoh/ubuntu/oneiric/unity/fix-for-880672

« back to all changes in this revision

Viewing changes to .pc/debian-changes-4.8.2-0ubuntu4/plugins/unityshell/src/IMTextEntry.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2011-08-25 15:40:18 UTC
  • mfrom: (1.1.52 upstream)
  • Revision ID: james.westby@ubuntu.com-20110825154018-enhrknkztdco821i
Tags: 4.10.0-0ubuntu1
* New upstream release:
  - unity task switcher (alt-tab, alt-down) shows empty spaces for iconified 
    windows in window detail mode (lp: #828348)
  - compiz crashed with SIGSEGV in 
    unity::DeviceLauncherIcon::OnStopDriveReady() (lp: #824093)
  - Dash performance issues with 'Active Blur' enabled (lp: #824890)
  - compiz crashed with SIGABRT in raise() when setting background 
    to full color (lp: #829049)
  - Dragging from dash to launcher still doesn't work (lp: #824833)
  - .desktops dragged on to unity launcher will not be added to 
     com.canonical.Unity.Launcher favorites unless moved in the launcher
     (lp: #830536)
  - application's menu shown when the cursor is a little left 
    to window controls (lp: #820293)
  - Ubuntu Start launcher item should always start the dash with 
    the Home screen (lp: #825034)
  - search spinner does not stop hence nothing can be launched with 
    the Return key (lp: #824836)
* debian/control: updated nux requirement
* debian/rules: updated shlibs

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// -*- Mode: C++; indent-tabs-mode: ni; tab-width: 2 -*-
2
 
/*
3
 
 * Copyright (C) 2011 Canonical Ltd
4
 
 *
5
 
 * This program is free software: you can redistribute it and/or modify
6
 
 * it under the terms of the GNU General Pubic License version 3 as
7
 
 * published by the Free Software Foundation.
8
 
 *
9
 
 * This program is distributed in the hope that it wi be useful,
10
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 
 * GNU General Public License for more detais.
13
 
 *
14
 
 * You shoud have received a copy of the GNU General Public License
15
 
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
 
 *
17
 
 * Authored by: Neil Jagdish Patel <neil.patel@canonical.com>
18
 
 */
19
 
 
20
 
#include "config.h"
21
 
 
22
 
#include "IMTextEntry.h"
23
 
 
24
 
#include <boost/lexical_cast.hpp>
25
 
#include <NuxCore/Logger.h>
26
 
#include <UnityCore/GLibWrapper.h>
27
 
 
28
 
namespace unity
29
 
{
30
 
namespace dash
31
 
{
32
 
 
33
 
namespace
34
 
{
35
 
nux::logging::Logger logger("unity.dash.imtextentry");
36
 
}
37
 
 
38
 
NUX_IMPLEMENT_OBJECT_TYPE(IMTextEntry);
39
 
 
40
 
IMTextEntry::IMTextEntry()
41
 
  : TextEntry("", "", 80085)
42
 
  , preedit_string("")
43
 
  , im_context_(0)
44
 
  , client_window_(0)
45
 
  , im_enabled_(false)
46
 
  , im_active_(false)
47
 
{
48
 
  CheckIMEnabled();
49
 
  //FIXME: Make event forwarding work before enabling
50
 
  // im_enabled_ ? SetupMultiIM() : SetupSimpleIM();
51
 
  SetupSimpleIM();
52
 
 
53
 
  FocusChanged.connect(sigc::mem_fun(this, &IMTextEntry::OnFocusChanged));
54
 
  OnKeyNavFocusChange.connect(sigc::mem_fun(this, &IMTextEntry::OnFocusChanged));
55
 
  mouse_up.connect(sigc::mem_fun(this, &IMTextEntry::OnMouseButtonUp));
56
 
}
57
 
 
58
 
IMTextEntry::~IMTextEntry()
59
 
{
60
 
  if (im_context_)
61
 
    g_object_unref(im_context_);
62
 
  if (client_window_)
63
 
    g_object_unref(client_window_);
64
 
}
65
 
 
66
 
void IMTextEntry::CheckIMEnabled()
67
 
{
68
 
  const char* module = g_getenv("GTK_IM_MODULE");
69
 
  if (module &&
70
 
      g_strcmp0(module, "") &&
71
 
      g_strcmp0(module, "gtk-im-context-simple"))
72
 
    im_enabled_ = true;
73
 
 
74
 
  LOG_DEBUG(logger) << "Input method support is "
75
 
                    << (im_enabled_ ? "enabled" : "disabled");
76
 
}
77
 
 
78
 
void IMTextEntry::SetupSimpleIM()
79
 
{
80
 
  im_context_ = gtk_im_context_simple_new();
81
 
  
82
 
  sig_manager_.Add(new Signal<void, GtkIMContext*, char*>(im_context_, "commit", sigc::mem_fun(this, &IMTextEntry::OnCommit)));
83
 
  sig_manager_.Add(new Signal<void, GtkIMContext*>(im_context_, "preedit-changed", sigc::mem_fun(this, &IMTextEntry::OnPreeditChanged)));
84
 
  sig_manager_.Add(new Signal<void, GtkIMContext*>(im_context_, "preedit-start", sigc::mem_fun(this, &IMTextEntry::OnPreeditStart)));
85
 
  sig_manager_.Add(new Signal<void, GtkIMContext*>(im_context_, "preedit-end", sigc::mem_fun(this, &IMTextEntry::OnPreeditEnd)));
86
 
}
87
 
 
88
 
void IMTextEntry::SetupMultiIM()
89
 
{
90
 
  im_context_ = gtk_im_multicontext_new();
91
 
  
92
 
  sig_manager_.Add(new Signal<void, GtkIMContext*, char*>(im_context_, "commit", sigc::mem_fun(this, &IMTextEntry::OnCommit)));
93
 
  sig_manager_.Add(new Signal<void, GtkIMContext*>(im_context_, "preedit-changed", sigc::mem_fun(this, &IMTextEntry::OnPreeditChanged)));
94
 
  sig_manager_.Add(new Signal<void, GtkIMContext*>(im_context_, "preedit-start", sigc::mem_fun(this, &IMTextEntry::OnPreeditStart)));
95
 
  sig_manager_.Add(new Signal<void, GtkIMContext*>(im_context_, "preedit-end", sigc::mem_fun(this, &IMTextEntry::OnPreeditEnd)));
96
 
}
97
 
 
98
 
bool IMTextEntry::InspectKeyEvent(unsigned int event_type,
99
 
                                  unsigned int keysym,
100
 
                                  const char* character)
101
 
{
102
 
  bool propagate_event = !(TryHandleEvent(event_type, keysym, character));
103
 
 
104
 
    LOG_DEBUG(logger) << "Input method ("
105
 
                    << (im_enabled_ ? gtk_im_multicontext_get_context_id(GTK_IM_MULTICONTEXT(im_context_)) : "simple")
106
 
                    << ") "
107
 
                    << (propagate_event ? "did not handle " : "handled ") 
108
 
                    << "event ("
109
 
                    << (event_type == NUX_KEYDOWN ? "press" : "release")
110
 
                    << ") ";
111
 
 
112
 
  std::string preedit = preedit_string;
113
 
  if (preedit.length() < 1 && 
114
 
      (keysym == NUX_VK_ENTER ||
115
 
       keysym == NUX_KP_ENTER ||
116
 
       keysym == NUX_VK_UP ||
117
 
       keysym == NUX_VK_DOWN ||
118
 
       keysym == NUX_VK_LEFT ||
119
 
       keysym == NUX_VK_RIGHT ||
120
 
       keysym == NUX_VK_LEFT_TAB ||
121
 
       keysym == NUX_VK_TAB ||
122
 
       keysym == NUX_VK_ESCAPE ||
123
 
       keysym == NUX_VK_DELETE ||
124
 
       keysym == NUX_VK_BACKSPACE ||
125
 
       keysym == NUX_VK_HOME ||
126
 
       keysym == NUX_VK_END))
127
 
  {
128
 
    propagate_event = true;
129
 
  }
130
 
 
131
 
  return propagate_event ? TextEntry::InspectKeyEvent(event_type, keysym, character)
132
 
                         : propagate_event;
133
 
}
134
 
 
135
 
bool IMTextEntry::TryHandleEvent(unsigned int eventType,
136
 
                                 unsigned int keysym,
137
 
                                 const char* character)
138
 
{
139
 
  nux::Event event = nux::GetGraphicsThread()->GetWindow().GetCurrentEvent();
140
 
  
141
 
  CheckValidClientWindow(event.e_x11_window);
142
 
  
143
 
  GdkEventKey ev;
144
 
  KeyEventToGdkEventKey(event, ev);
145
 
 
146
 
  return gtk_im_context_filter_keypress(im_context_, &ev);
147
 
}
148
 
 
149
 
inline void IMTextEntry::CheckValidClientWindow(Window window)
150
 
{
151
 
  if (!client_window_)
152
 
  {
153
 
    client_window_ = gdk_x11_window_foreign_new_for_display(gdk_display_get_default(), window);
154
 
    gtk_im_context_set_client_window(im_context_, client_window_);
155
 
 
156
 
    if (GetFocused())
157
 
    {
158
 
      gtk_im_context_focus_in(im_context_);
159
 
    }
160
 
  }
161
 
}
162
 
 
163
 
void IMTextEntry::KeyEventToGdkEventKey(Event& event, GdkEventKey& gdk_event)
164
 
{
165
 
  gdk_event.type = event.e_event == nux::NUX_KEYDOWN ? GDK_KEY_PRESS : GDK_KEY_RELEASE;
166
 
 
167
 
  gdk_event.window = client_window_;
168
 
  gdk_event.window = 0;
169
 
  gdk_event.send_event = FALSE;
170
 
  gdk_event.time = event.e_x11_timestamp;
171
 
  gdk_event.state = event.e_x11_state;
172
 
  gdk_event.keyval = event.e_keysym;
173
 
 
174
 
  gchar* txt = const_cast<gchar*>(event.GetText());
175
 
  gdk_event.length = strlen(txt);
176
 
  gdk_event.string = txt;
177
 
 
178
 
  gdk_event.hardware_keycode = event.e_x11_keycode;
179
 
  gdk_event.group = 0;
180
 
  gdk_event.is_modifier = 0;
181
 
}
182
 
 
183
 
void IMTextEntry::OnFocusChanged(nux::Area* area)
184
 
{
185
 
 
186
 
  LOG_DEBUG(logger) << "Focus changed " << boost::lexical_cast<bool>(GetFocused());
187
 
 
188
 
  if (GetFocused())
189
 
  {
190
 
    gtk_im_context_focus_in(im_context_);
191
 
  }
192
 
  else
193
 
  {
194
 
    gtk_im_context_focus_out(im_context_);
195
 
    gtk_im_context_reset(im_context_);
196
 
  }
197
 
}
198
 
 
199
 
void IMTextEntry::OnCommit(GtkIMContext* context, char* str)
200
 
{
201
 
  LOG_DEBUG(logger) << "Commit: " << str;
202
 
  if (str)
203
 
  {
204
 
    std::string new_text = GetText() + str;
205
 
    int cursor = cursor_;
206
 
    SetText(new_text.c_str());
207
 
    SetCursor(cursor + strlen(str));
208
 
  }
209
 
}
210
 
 
211
 
void IMTextEntry::OnPreeditChanged(GtkIMContext* context)
212
 
{
213
 
  glib::String preedit;
214
 
  int cursor_pos = -1;
215
 
 
216
 
  gtk_im_context_get_preedit_string(context, &preedit, NULL, &cursor_pos);
217
 
 
218
 
  LOG_DEBUG(logger) << "Preedit changed: " << preedit;
219
 
 
220
 
  preedit_string = preedit.Str();
221
 
}
222
 
 
223
 
void IMTextEntry::OnPreeditStart(GtkIMContext* context)
224
 
{
225
 
  preedit_string = "";
226
 
  im_active_ = true;
227
 
 
228
 
  LOG_DEBUG(logger) << "Preedit start";
229
 
}
230
 
 
231
 
void IMTextEntry::OnPreeditEnd(GtkIMContext* context)
232
 
{
233
 
  preedit_string = "";
234
 
  im_active_ = false;
235
 
  gtk_im_context_reset(im_context_);
236
 
 
237
 
  LOG_DEBUG(logger) << "Preedit ended";
238
 
}
239
 
 
240
 
void IMTextEntry::OnMouseButtonUp(int x, int y, unsigned long bflags, unsigned long kflags)
241
 
{
242
 
  if (nux::GetEventButton(bflags) == 3 && im_enabled_)
243
 
  {
244
 
    GtkWidget* menu = gtk_menu_new();
245
 
    gtk_im_multicontext_append_menuitems(GTK_IM_MULTICONTEXT(im_context_),
246
 
                                          GTK_MENU_SHELL(menu));
247
 
    gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, 3, GDK_CURRENT_TIME);
248
 
  }
249
 
}
250
 
 
251
 
}
252
 
}