匿名 | ログイン | 新しいユーザーの作成 | 2024-12-05 03:57 JST |
メイン | マイビュー | 検索 | 変更履歴 | ロードマップ | Vine Linux ホーム |
課題の詳細を表示 [ コメントにジャンプ ] | [ 課題の履歴 ] [ 印刷 ] | ||||||||
ID | プロジェクト | カテゴリ | 登録日 | 最終更新 | |||||
0000564 | Vine Linux | 1 バグ | 2007-11-22 01:37 | 2007-12-13 18:41 | |||||
報告者 | anonymous | ||||||||
担当者 | packager | ||||||||
優先度 | 中 | 再現性 | 不明 | ||||||
状態 | 完了 | 解決状況 | 不明 | ||||||
バージョン | 4.1 | ||||||||
修正予定バージョン | 修正済バージョン | ||||||||
概要 | 0000564: KonsoleのPreedit入力の挙動が異常 | ||||||||
説明 | Qt & KDEのVineのデフォルトの設定はOverTheSpotですが、 (LyXを除く)ほとんどのQt & KDEのプログラムはOnTheSpotで 問題なく動きます。というより、Vine 4.1のQtではOverTheSpot では使いものにならない場合が多いのではないでしょうか。 という事で私はOnTheSpotで使用しているのですが、唯一これで 困るのはKonsoleの入力です。 現象:(skkinput or uim-skk or uim-canna + konsole (OnTheSpot)) 1) 全角Greekと全角記号の多くが1 byte文字と判定されるため、入力が 乱れる。特にskkinputやuim-skkを使用している場合、最初に必ず 変換マークが付くので、これが1byte文字と判定され 入力行が乱れて使いものにならない。 2)変換文字列の強調、反転位置がずれる。 vimなどを使うとspace keyを押して変換開始状態にすると 無関係な部分が反転したり、ひどいときには、画面全体が 反転する。 解決策: kdelibsのkonsole/konsoleに以下の添付patchを適用すると 以上の問題点は回避され、そこそこ使えるようになる。 ただし、変換行が2行にまたがる場合はオリジナルと同様で 強調位置が正しくありません(この部分を修正すると修正量が 多くなるので)。単純かつ範囲の限定されたpatchなので是非 対応して頂きたいと思います。 備考: これはこのレポートとは関係ありませんが。OnTheSpotに 動作変更する場合にはまると悪いので。。。 Qtの動作を変える時、qtconfigを使うと思いますが(例えば、 OnTheSpotにする)、一度保存すると~/.qt/qtrcが出来ます (clean installの状態ではこのファイルはありません)。 そのqtrcのlibrary path entryに実体の同じdirectoryが登録 されているはずです。 /usr/lib/qt-3.5.5 == /usr/lib/qt3. この状態を放っておくと、プログラムの起動時にwarningが出る ようになり、さらに環境によってはprogramが異常終了するように なります。ですので、qtrcのlibrary pathを確認して 重複をとりのぞき、そのあと、-r--r--r--にした方が良いと 思われます(一度qtrcが出来るとlibrary pathは勝手に追加 されるようになるので)。 たぶん、ld の部分にbugがあるのでしょうが追ってはいません。 | ||||||||
タグ | 設定されていません。 | ||||||||
arch | |||||||||
パッケージ | kdebase | ||||||||
添付ファイル | kdebase-3.5.8.diff [^] (5,395 バイト) 2007-11-22 01:37 [表示] [非表示]*** konsole/konsole/konsole_wcwidth.cpp.ORG 2007-11-21 18:28:55.000000000 +0900 --- konsole/konsole/konsole_wcwidth.cpp 2007-11-21 19:58:12.000000000 +0900 *************** *** 65,71 **** * in ISO 10646. */ ! int konsole_wcwidth(Q_UINT16 ucs) { /* sorted list of non-overlapping intervals of non-spacing characters */ static const struct interval combining[] = { --- 65,72 ---- * in ISO 10646. */ ! static int __konsole_wcwidth(Q_UINT16); ! static int __konsole_wcwidth(Q_UINT16 ucs) { /* sorted list of non-overlapping intervals of non-spacing characters */ static const struct interval combining[] = { *************** *** 131,137 **** (ucs >= 0x20000 && ucs <= 0x2ffff) */)); } ! #if 0 /* * The following function is the same as konsole_wcwidth(), except that * spacing characters in the East Asian Ambiguous (A) category as --- 132,138 ---- (ucs >= 0x20000 && ucs <= 0x2ffff) */)); } ! #if 1 /* * The following function is the same as konsole_wcwidth(), except that * spacing characters in the East Asian Ambiguous (A) category as *************** *** 140,146 **** * encodings who want to migrate to UCS. It is not otherwise * recommended for general use. */ ! int konsole_wcwidth_cjk(Q_UINT16 ucs) { /* sorted list of non-overlapping intervals of East Asian Ambiguous * characters */ --- 141,147 ---- * encodings who want to migrate to UCS. It is not otherwise * recommended for general use. */ ! int konsole_wcwidth(Q_UINT16 ucs) { /* sorted list of non-overlapping intervals of East Asian Ambiguous * characters */ *************** *** 202,208 **** sizeof(ambiguous) / sizeof(struct interval) - 1)) return 2; ! return konsole_wcwidth(ucs); } #endif --- 203,209 ---- sizeof(ambiguous) / sizeof(struct interval) - 1)) return 2; ! return __konsole_wcwidth(ucs); } #endif *** konsole/konsole/TEWidget.cpp.ORG 2007-11-21 18:28:36.000000000 +0900 --- konsole/konsole/TEWidget.cpp 2007-11-21 23:40:50.097000000 +0900 *************** *** 647,656 **** QString tmpStr = str.simplifyWhiteSpace(); if ( m_isIMEdit && !tmpStr.isEmpty() ) { // imput method edit area background color QRect tmpRect = rect; ! if ( str != m_imPreeditText ) { // ugly hack ! tmpRect.setLeft( tmpRect.left() + font_w ); ! tmpRect.setWidth( tmpRect.width() + font_w ); ! } paint.fillRect( tmpRect, Qt::darkCyan ); // currently use hard code color } --- 647,656 ---- QString tmpStr = str.simplifyWhiteSpace(); if ( m_isIMEdit && !tmpStr.isEmpty() ) { // imput method edit area background color QRect tmpRect = rect; ! // if ( str != m_imPreeditText ) { // ugly hack ! // tmpRect.setLeft( tmpRect.left() + font_w ); ! // tmpRect.setWidth( tmpRect.width() + font_w ); ! // } paint.fillRect( tmpRect, Qt::darkCyan ); // currently use hard code color } *************** *** 662,671 **** int h = font_h; QRect tmpRect = QRect( x, y, w, h ); ! if ( str != m_imPreeditText ) { // ugly hack ! tmpRect.setLeft( tmpRect.left() + font_w ); ! tmpRect.setWidth( tmpRect.width() + font_w ); ! } paint.fillRect( tmpRect, Qt::darkGray ); // currently use hard code color } --- 662,671 ---- int h = font_h; QRect tmpRect = QRect( x, y, w, h ); ! // if ( str != m_imPreeditText ) { // ugly hack ! // tmpRect.setLeft( tmpRect.left() + font_w ); ! // tmpRect.setWidth( tmpRect.width() + font_w ); ! // } paint.fillRect( tmpRect, Qt::darkGray ); // currently use hard code color } *************** *** 876,882 **** if (ext[x+len].f != cf || ext[x+len].b != cb || ext[x+len].r != cr || !dirtyMask[x+len] || isLineChar(c) != lineDraw || (ext[x+len+1].c == 0) != doubleWidth) break; ! disstrU[p++] = c; //fontMap(c); } --- 876,884 ---- if (ext[x+len].f != cf || ext[x+len].b != cb || ext[x+len].r != cr || !dirtyMask[x+len] || isLineChar(c) != lineDraw || (ext[x+len+1].c == 0) != doubleWidth) break; ! // Moreover, we never cross the boundary of the preedit area ! if (m_imStart < m_imEnd && (x + 1) == m_imStart) ! break; disstrU[p++] = c; //fontMap(c); } *************** *** 884,889 **** --- 886,892 ---- // for XIM on the spot input style m_isIMEdit = m_isIMSel = false; + #if 0 if ( m_imStartLine == y ) { if ( ( m_imStart < m_imEnd ) && ( x >= m_imStart-1 ) && ( x + int( unistr.length() ) <= m_imEnd ) ) m_isIMEdit = true; *************** *** 898,903 **** --- 901,920 ---- if ( ( m_imSelStart < m_imSelEnd ) ) m_isIMSel = true; } + #else + if (m_imStart < m_imEnd && y >= m_imStartLine) + { + int realsx, realex; + realsx = x + (y - m_imStartLine) * cols; + realex = realsx + int(unistr.length()); + if (!(realex <= m_imStart || realsx >= m_imEnd)) + { + m_isIMEdit = true; + if (m_imSelStart < m_imSelEnd) + m_isIMSel = true; + } + } + #endif bool save_fixed_font = fixed_font; if (lineDraw) konsole-3.5.8-1122.diff [^] (10,335 バイト) 2007-11-22 09:43 [表示] [非表示] *** konsole/konsole/konsole_wcwidth.cpp.ORG 2007-11-22 09:18:07.000000000 +0900 --- konsole/konsole/konsole_wcwidth.cpp 2007-11-22 05:19:17.000000000 +0900 *************** *** 65,71 **** * in ISO 10646. */ ! int konsole_wcwidth(Q_UINT16 ucs) { /* sorted list of non-overlapping intervals of non-spacing characters */ static const struct interval combining[] = { --- 65,72 ---- * in ISO 10646. */ ! static int __konsole_wcwidth(Q_UINT16); ! static int __konsole_wcwidth(Q_UINT16 ucs) { /* sorted list of non-overlapping intervals of non-spacing characters */ static const struct interval combining[] = { *************** *** 131,137 **** (ucs >= 0x20000 && ucs <= 0x2ffff) */)); } ! #if 0 /* * The following function is the same as konsole_wcwidth(), except that * spacing characters in the East Asian Ambiguous (A) category as --- 132,138 ---- (ucs >= 0x20000 && ucs <= 0x2ffff) */)); } ! #if 1 /* * The following function is the same as konsole_wcwidth(), except that * spacing characters in the East Asian Ambiguous (A) category as *************** *** 140,146 **** * encodings who want to migrate to UCS. It is not otherwise * recommended for general use. */ ! int konsole_wcwidth_cjk(Q_UINT16 ucs) { /* sorted list of non-overlapping intervals of East Asian Ambiguous * characters */ --- 141,147 ---- * encodings who want to migrate to UCS. It is not otherwise * recommended for general use. */ ! int konsole_wcwidth(Q_UINT16 ucs) { /* sorted list of non-overlapping intervals of East Asian Ambiguous * characters */ *************** *** 202,208 **** sizeof(ambiguous) / sizeof(struct interval) - 1)) return 2; ! return konsole_wcwidth(ucs); } #endif --- 203,209 ---- sizeof(ambiguous) / sizeof(struct interval) - 1)) return 2; ! return __konsole_wcwidth(ucs); } #endif *** konsole/konsole/TEWidget.cpp.ORG 2007-11-22 09:18:21.000000000 +0900 --- konsole/konsole/TEWidget.cpp 2007-11-22 09:28:19.000000000 +0900 *************** *** 647,656 **** QString tmpStr = str.simplifyWhiteSpace(); if ( m_isIMEdit && !tmpStr.isEmpty() ) { // imput method edit area background color QRect tmpRect = rect; ! if ( str != m_imPreeditText ) { // ugly hack ! tmpRect.setLeft( tmpRect.left() + font_w ); ! tmpRect.setWidth( tmpRect.width() + font_w ); ! } paint.fillRect( tmpRect, Qt::darkCyan ); // currently use hard code color } --- 647,656 ---- QString tmpStr = str.simplifyWhiteSpace(); if ( m_isIMEdit && !tmpStr.isEmpty() ) { // imput method edit area background color QRect tmpRect = rect; ! // if ( str != m_imPreeditText ) { // ugly hack ! // tmpRect.setLeft( tmpRect.left() + font_w ); ! // tmpRect.setWidth( tmpRect.width() + font_w ); ! // } paint.fillRect( tmpRect, Qt::darkCyan ); // currently use hard code color } *************** *** 660,673 **** int y = rect.top(); int w = font_w * (m_imSelEnd - m_imSelStart); int h = font_h; ! QRect tmpRect = QRect( x, y, w, h ); ! if ( str != m_imPreeditText ) { // ugly hack ! tmpRect.setLeft( tmpRect.left() + font_w ); ! tmpRect.setWidth( tmpRect.width() + font_w ); } - - paint.fillRect( tmpRect, Qt::darkGray ); // currently use hard code color } } --- 660,675 ---- int y = rect.top(); int w = font_w * (m_imSelEnd - m_imSelStart); int h = font_h; + if (x + w <= rect.left() + rect.width()) + { + QRect tmpRect = QRect( x, y, w, h ); + // if ( str != m_imPreeditText ) { // ugly hack + // tmpRect.setLeft( tmpRect.left() + font_w ); + // tmpRect.setWidth( tmpRect.width() + font_w ); + // } ! paint.fillRect( tmpRect, Qt::darkGray ); // currently use hard code color } } } *************** *** 791,796 **** --- 793,806 ---- // fprintf(stderr, "x/y = %d/%d\txpos/ypos = %d/%d\n", curx, cury, xpos, ypos); m_cursorLine = cury; m_cursorCol = curx; + if (m_imStart == m_imEnd) + { + // + // Ok, now event queue being flushed + // + m_imEnd = m_imStart = 0; + m_imStartLine = 0; + } } /*! *************** *** 837,849 **** // Two extra so that we don't have to have to care about start and end conditions for (x = 0; x < cols; x++) { ! if ( ( (m_imPreeditLength > 0) && ( ( m_imStartLine == y ) ! && ( ( m_imStart < m_imEnd ) && ( ( x > m_imStart ) ) && ( x < m_imEnd ) ) ! || ( ( m_imSelStart < m_imSelEnd ) && ( ( x > m_imSelStart ) ) ) ) ) ! || ext[x] != lcl[x]) ! { ! dirtyMask[x] = dirtyMask[x+1] = dirtyMask[x+2] = 1; ! } } dirtyMask++; // Position correctly --- 847,863 ---- // Two extra so that we don't have to have to care about start and end conditions for (x = 0; x < cols; x++) { ! if (ext[x] != lcl[x]) ! { ! dirtyMask[x] = dirtyMask[x+1] = dirtyMask[x+2] = 1; ! } ! else if (m_imStart < m_imEnd && y >= m_imStartLine) ! { ! int pos; ! pos = (y - m_imStartLine) * cols + x; ! if (m_imStart < pos && pos < m_imEnd) ! dirtyMask[x] = dirtyMask[x+1] = dirtyMask[x+2] = 1; ! } } dirtyMask++; // Position correctly *************** *** 869,874 **** --- 883,893 ---- int lln = cols - x; for (len = 1; len < lln; len++) { + // We never cross the boundary of the preedit area + if (m_imStart < m_imEnd && + (((x + len) == m_imStart) || (x + len) == m_imEnd)) + break; + c = ext[x+len].c; if (!c) continue; // Skip trailing part of multi-col chars. *************** *** 884,889 **** --- 903,909 ---- // for XIM on the spot input style m_isIMEdit = m_isIMSel = false; + #if 0 if ( m_imStartLine == y ) { if ( ( m_imStart < m_imEnd ) && ( x >= m_imStart-1 ) && ( x + int( unistr.length() ) <= m_imEnd ) ) m_isIMEdit = true; *************** *** 898,903 **** --- 918,939 ---- if ( ( m_imSelStart < m_imSelEnd ) ) m_isIMSel = true; } + #else + if (m_imStart < m_imEnd && y >= m_imStartLine) + { + int realsx, realex; + realsx = x + (y - m_imStartLine) * cols; + realex = realsx + string_width(unistr); + //realex = realsx + int(unistr.length()); + if (!(realex <= m_imStart || realsx >= m_imEnd)) + { + m_isIMEdit = true; + if (m_imSelStart < m_imSelEnd && + (!(realex <= m_imSelStart || realsx >= m_imSelEnd))) + m_isIMSel = true; + } + } + #endif bool save_fixed_font = fixed_font; if (lineDraw) *************** *** 1921,1931 **** void TEWidget::imStartEvent( QIMEvent */*e*/ ) { ! m_imStart = m_cursorCol; ! m_imStartLine = m_cursorLine; m_imPreeditLength = 0; ! m_imEnd = m_imSelStart = m_imSelEnd = 0; m_isIMEdit = m_isIMSel = false; } --- 1957,1975 ---- void TEWidget::imStartEvent( QIMEvent */*e*/ ) { ! // ! // m_imStart == 0 && m_imStartLine == 0 mean that the event queue ! // is empty, thus we can trust the cursor position. ! // ! if (m_imStart == 0 && m_imStartLine == 0) ! { ! m_imStart = m_cursorCol; ! m_imStartLine = m_cursorLine; ! } m_imPreeditLength = 0; ! m_imEnd = m_imStart; ! m_imSelStart = m_imSelEnd = 0; m_isIMEdit = m_isIMSel = false; } *************** *** 1944,1949 **** --- 1988,1995 ---- tmpStr = e->text().mid( e->cursorPos(), e->selectionLength() ); m_imSelEnd = m_imSelStart + string_width( tmpStr ); m_imPreeditLength = e->text().length(); + if (e->cursorPos() < m_imPreeditLength && m_imSelStart == m_imSelEnd) + m_imSelEnd = m_imSelStart + 1; m_imPreeditText = e->text(); text += e->text(); *************** *** 1956,1983 **** void TEWidget::imEndEvent( QIMEvent *e ) { QString text = QString::null; if ( m_imPreeditLength > 0 ) { text.fill( '\010', m_imPreeditLength ); } ! m_imEnd = m_imSelStart = m_imSelEnd = 0; text += e->text(); if ( text.length() > 0 ) { QKeyEvent ke( QEvent::KeyPress, 0, -1, 0, text ); emit keyPressedSignal( &ke ); } QPoint tL = contentsRect().topLeft(); int tLx = tL.x(); int tLy = tL.y(); ! ! QRect repaintRect = QRect( bX+tLx, bY+tLy+font_h*m_imStartLine, contentsRect().width(), contentsRect().height() ); ! m_imStart = 0; ! m_imPreeditLength = 0; ! ! m_isIMEdit = m_isIMSel = false; ! repaint( repaintRect, true ); } // Override any Ctrl+<key> accelerator when pressed with the keyboard --- 2002,2049 ---- void TEWidget::imEndEvent( QIMEvent *e ) { QString text = QString::null; + int prevstart, prevlen; if ( m_imPreeditLength > 0 ) { text.fill( '\010', m_imPreeditLength ); } ! // ! // Calculte the true cursor position for the next im_imStart ! // in case of the non empty event queue. ! // ! prevstart = m_imStart; ! prevlen = m_imEnd - m_imStart + 2; ! if (prevlen < 2) ! prevlen = 2; ! m_imStart += string_width(e->text()); ! m_imEnd = m_imStart; ! m_imSelStart = m_imSelEnd = 0; ! text += e->text(); if ( text.length() > 0 ) { QKeyEvent ke( QEvent::KeyPress, 0, -1, 0, text ); emit keyPressedSignal( &ke ); } + m_imPreeditLength = 0; + m_isIMEdit = m_isIMSel = false; + QPoint tL = contentsRect().topLeft(); int tLx = tL.x(); int tLy = tL.y(); ! if (prevlen + prevstart <= this->columns) // This is wrong! ! { ! QRect repaintRect = QRect( bX+tLx + font_w * prevstart, ! bY+tLy+font_h*m_imStartLine, ! font_w * prevlen, font_h); ! repaint( repaintRect, true ); ! } ! else ! { ! QRect repaintRect = QRect( bX+tLx, bY+tLy+font_h*m_imStartLine, contentsRect().width(), contentsRect().height() ); ! repaint( repaintRect, true ); ! } } // Override any Ctrl+<key> accelerator when pressed with the keyboard konsole-3.5.8-1123.diff [^] (14,504 バイト) 2007-11-23 04:13 [表示] [非表示] *** konsole/konsole/TEWidget.cpp.ORG 2007-11-21 18:28:36.000000000 +0900 --- konsole/konsole/TEWidget.cpp 2007-11-23 03:50:03.667000000 +0900 *************** *** 373,381 **** ,rimY(1) ,m_imPreeditText(QString::null) ,m_imPreeditLength(0) ! ,m_imStart(0) ,m_imStartLine(0) ! ,m_imEnd(0) ,m_imSelStart(0) ,m_imSelEnd(0) ,m_cursorLine(0) --- 373,381 ---- ,rimY(1) ,m_imPreeditText(QString::null) ,m_imPreeditLength(0) ! ,m_imStart(-1) ,m_imStartLine(0) ! ,m_imEnd(-1) ,m_imSelStart(0) ,m_imSelEnd(0) ,m_cursorLine(0) *************** *** 644,673 **** paint.fillRect(rect, bColor); } ! QString tmpStr = str.simplifyWhiteSpace(); ! if ( m_isIMEdit && !tmpStr.isEmpty() ) { // imput method edit area background color ! QRect tmpRect = rect; ! if ( str != m_imPreeditText ) { // ugly hack ! tmpRect.setLeft( tmpRect.left() + font_w ); ! tmpRect.setWidth( tmpRect.width() + font_w ); ! } ! ! paint.fillRect( tmpRect, Qt::darkCyan ); // currently use hard code color ! } ! if ( m_isIMSel && !tmpStr.isEmpty() ) { // imput method selection background color ! int x = rect.left() + ( font_w * (m_imSelStart - m_imStart) ); ! int y = rect.top(); ! int w = font_w * (m_imSelEnd - m_imSelStart); ! int h = font_h; ! ! QRect tmpRect = QRect( x, y, w, h ); ! if ( str != m_imPreeditText ) { // ugly hack ! tmpRect.setLeft( tmpRect.left() + font_w ); ! tmpRect.setWidth( tmpRect.width() + font_w ); } - - paint.fillRect( tmpRect, Qt::darkGray ); // currently use hard code color } } --- 644,663 ---- paint.fillRect(rect, bColor); } ! if (m_isIMEdit && str.length() > 0) ! paint.fillRect(rect, Qt::darkCyan ); // currently use hard code color ! if ( m_isIMSel && str.length() > 0) ! { // imput method selection background color ! if (m_imSelEnd - m_imSelStart == 1) // The fake cursor case ! { ! QRect tmpRect = QRect(rect.left(), rect.top(), font_w, font_h); ! paint.fillRect( tmpRect, Qt::darkGray ); ! } ! else ! { ! paint.fillRect(rect, Qt::darkGray ); // currently use hard code color } } } *************** *** 791,796 **** --- 781,792 ---- // fprintf(stderr, "x/y = %d/%d\txpos/ypos = %d/%d\n", curx, cury, xpos, ypos); m_cursorLine = cury; m_cursorCol = curx; + // OK, now the event queue is going to be flushed. + if (m_imStart == m_imEnd) + { + m_imEnd = m_imStart = -1; + m_imStartLine = 0; + } } /*! *************** *** 825,830 **** --- 821,842 ---- char *dirtyMask = (char *) malloc(cols+2); //{ static int cnt = 0; printf("setImage %d\n",cnt++); } + int imstart = -1, imend = 0; + int imselstart = -1, imselend = 0; + int abspos = 0; + if (m_imStart < m_imEnd) + { + int xpos = cols * m_imStartLine; + imstart = xpos + m_imStart; + imend = xpos + m_imEnd; + if (m_imSelStart < m_imSelEnd) + { + imselstart = xpos + m_imSelStart; + imselend = xpos + m_imSelEnd; + } + } + + for (y = 0; y < lins; y++) { const ca* lcl = &image[y*this->columns]; *************** *** 834,854 **** // mark surrounding neighbours dirty, in case the character exceeds // its cell boundaries memset(dirtyMask, 0, cols+2); // Two extra so that we don't have to have to care about start and end conditions ! for (x = 0; x < cols; x++) { ! if ( ( (m_imPreeditLength > 0) && ( ( m_imStartLine == y ) ! && ( ( m_imStart < m_imEnd ) && ( ( x > m_imStart ) ) && ( x < m_imEnd ) ) ! || ( ( m_imSelStart < m_imSelEnd ) && ( ( x > m_imSelStart ) ) ) ) ) ! || ext[x] != lcl[x]) ! { ! dirtyMask[x] = dirtyMask[x+1] = dirtyMask[x+2] = 1; ! } } dirtyMask++; // Position correctly if (!resizing) // not while resizing, we're expecting a paintEvent ! for (x = 0; x < cols; x++) { hasBlinker |= (ext[x].r & RE_BLINK); // Start drawing if this character or the next one differs. --- 846,886 ---- // mark surrounding neighbours dirty, in case the character exceeds // its cell boundaries memset(dirtyMask, 0, cols+2); + + // Ajust the end positions of the input area for wrapping cases. + abspos = y * cols; + int xpos = abspos + cols - 1; + if (imstart >= 0 && ext[cols - 1].c == '>' && + imstart <= xpos && xpos < imend) + { + imend ++; + if (imselstart >= 0) + { + if (xpos <= imselstart) + imselstart ++; + if (xpos < imselend) + imselend ++; + } + } + // Two extra so that we don't have to have to care about start and end conditions ! for (x = 0; x < cols; x++, abspos ++) { ! if (ext[x] != lcl[x]) ! { ! dirtyMask[x] = dirtyMask[x+1] = dirtyMask[x+2] = 1; ! } ! else if (imstart >= 0) ! { ! if (imstart < abspos && abspos < imend) ! dirtyMask[x] = dirtyMask[x+1] = dirtyMask[x+2] = 1; ! } } dirtyMask++; // Position correctly + abspos = y * cols; if (!resizing) // not while resizing, we're expecting a paintEvent ! for (x = 0; x < cols; x++, abspos ++) { hasBlinker |= (ext[x].r & RE_BLINK); // Start drawing if this character or the next one differs. *************** *** 873,878 **** --- 905,922 ---- if (!c) continue; // Skip trailing part of multi-col chars. + // We never cross the boundary of the preedit area + if (imstart >= 0) + { + if (abspos + len == imstart || abspos + len == imend) + break; + // We also never cross the boundary of the selection area, + // however, we should remark the case of a fake cursor. + if (imselstart >= 0 && + (abspos + len == imselstart || abspos + len == imselend)) + break; + } + if (ext[x+len].f != cf || ext[x+len].b != cb || ext[x+len].r != cr || !dirtyMask[x+len] || isLineChar(c) != lineDraw || (ext[x+len+1].c == 0) != doubleWidth) break; *************** *** 884,889 **** --- 928,934 ---- // for XIM on the spot input style m_isIMEdit = m_isIMSel = false; + #if 0 if ( m_imStartLine == y ) { if ( ( m_imStart < m_imEnd ) && ( x >= m_imStart-1 ) && ( x + int( unistr.length() ) <= m_imEnd ) ) m_isIMEdit = true; *************** *** 898,903 **** --- 943,961 ---- if ( ( m_imSelStart < m_imSelEnd ) ) m_isIMSel = true; } + #else + // Check the segment cotaining a part of the input area. + if (imstart >= 0) + { + if (imstart <= abspos && abspos < imend) + { + m_isIMEdit = true; + if (imselstart >= 0 && + imselstart <= abspos && abspos < imselend) + m_isIMSel = true; + } + } + #endif bool save_fixed_font = fixed_font; if (lineDraw) *************** *** 909,914 **** --- 967,973 ---- unistr, &ext[x], pm != NULL, true); fixed_font = save_fixed_font; x += len - 1; + abspos += len - 1; } } *************** *** 1921,1931 **** void TEWidget::imStartEvent( QIMEvent */*e*/ ) { ! m_imStart = m_cursorCol; ! m_imStartLine = m_cursorLine; m_imPreeditLength = 0; ! m_imEnd = m_imSelStart = m_imSelEnd = 0; m_isIMEdit = m_isIMSel = false; } --- 1980,1998 ---- void TEWidget::imStartEvent( QIMEvent */*e*/ ) { ! // ! // m_imStart == -1 && m_imStartLine == 0 mean that the event queue ! // is empty, thus we can trust the cursor position. ! // ! if (m_imStart == -1 && m_imStartLine == 0) ! { ! m_imStart = m_cursorCol; ! m_imStartLine = m_cursorLine; ! } m_imPreeditLength = 0; ! m_imEnd = m_imStart; ! m_imSelStart = m_imSelEnd = 0; m_isIMEdit = m_isIMSel = false; } *************** *** 1944,1949 **** --- 2011,2018 ---- tmpStr = e->text().mid( e->cursorPos(), e->selectionLength() ); m_imSelEnd = m_imSelStart + string_width( tmpStr ); m_imPreeditLength = e->text().length(); + if (e->cursorPos() < m_imPreeditLength && m_imSelStart == m_imSelEnd) + m_imSelEnd = m_imSelStart + 1; m_imPreeditText = e->text(); text += e->text(); *************** *** 1951,1983 **** QKeyEvent ke( QEvent::KeyPress, 0, -1, 0, text ); emit keyPressedSignal( &ke ); } } void TEWidget::imEndEvent( QIMEvent *e ) { QString text = QString::null; if ( m_imPreeditLength > 0 ) { text.fill( '\010', m_imPreeditLength ); } ! m_imEnd = m_imSelStart = m_imSelEnd = 0; text += e->text(); if ( text.length() > 0 ) { QKeyEvent ke( QEvent::KeyPress, 0, -1, 0, text ); emit keyPressedSignal( &ke ); } QPoint tL = contentsRect().topLeft(); int tLx = tL.x(); int tLy = tL.y(); ! ! QRect repaintRect = QRect( bX+tLx, bY+tLy+font_h*m_imStartLine, contentsRect().width(), contentsRect().height() ); ! m_imStart = 0; ! m_imPreeditLength = 0; ! ! m_isIMEdit = m_isIMSel = false; ! repaint( repaintRect, true ); } // Override any Ctrl+<key> accelerator when pressed with the keyboard --- 2020,2094 ---- QKeyEvent ke( QEvent::KeyPress, 0, -1, 0, text ); emit keyPressedSignal( &ke ); } + + #if 0 + printf("%d %d %d %d %d: %d %d \n", + m_imStart, m_imEnd, m_imPreeditLength, m_imSelStart, m_imSelEnd, + e->cursorPos(), e->selectionLength()); + #endif } void TEWidget::imEndEvent( QIMEvent *e ) { QString text = QString::null; + int prevstart, prevlen; if ( m_imPreeditLength > 0 ) { text.fill( '\010', m_imPreeditLength ); } ! // ! // Calculte the true cursor position for the next im_start ! // in case of the non empty event queue ! // ! prevstart = m_imStart; ! prevlen = m_imEnd - m_imStart + 2; ! if (prevlen < 2) ! prevlen = 2; ! ! uint i, cols = this->columns; /* XXX: A bad assumption!! */ ! int xres, xlen, xpos = m_imStart; ! #if 1 ! for (i = 0; i < e->text().length(); i ++) ! { ! xlen = konsole_wcwidth(e->text()[i].unicode()); ! xres = cols - (xpos % cols); ! if (xres < xlen) ! xpos += xres; ! xpos += xlen; ! } ! #else ! xpos += string_width(e->text()); ! #endif ! m_imStart = (xpos % cols); ! m_imEnd = m_imStart; ! m_imStartLine += (xpos / cols); ! m_imSelStart = m_imSelEnd = 0; ! text += e->text(); if ( text.length() > 0 ) { QKeyEvent ke( QEvent::KeyPress, 0, -1, 0, text ); emit keyPressedSignal( &ke ); } + m_imPreeditLength = 0; + m_isIMEdit = m_isIMSel = false; + QPoint tL = contentsRect().topLeft(); int tLx = tL.x(); int tLy = tL.y(); ! if (prevlen + prevstart <= cols) // This is wrong! ! { ! QRect repaintRect = QRect( bX+tLx + font_w * prevstart, ! bY+tLy+font_h*m_imStartLine, ! font_w * prevlen, font_h); ! repaint( repaintRect, true ); ! } ! else ! { ! QRect repaintRect = QRect( bX+tLx, bY+tLy+font_h*m_imStartLine, contentsRect().width(), contentsRect().height() ); ! repaint( repaintRect, true ); ! } } // Override any Ctrl+<key> accelerator when pressed with the keyboard *** konsole/konsole/konsole_wcwidth.cpp.ORG 2007-11-21 18:28:55.000000000 +0900 --- konsole/konsole/konsole_wcwidth.cpp 2007-11-23 02:53:39.507000000 +0900 *************** *** 65,71 **** * in ISO 10646. */ ! int konsole_wcwidth(Q_UINT16 ucs) { /* sorted list of non-overlapping intervals of non-spacing characters */ static const struct interval combining[] = { --- 65,72 ---- * in ISO 10646. */ ! static int __konsole_wcwidth(Q_UINT16); ! static int __konsole_wcwidth(Q_UINT16 ucs) { /* sorted list of non-overlapping intervals of non-spacing characters */ static const struct interval combining[] = { *************** *** 131,137 **** (ucs >= 0x20000 && ucs <= 0x2ffff) */)); } ! #if 0 /* * The following function is the same as konsole_wcwidth(), except that * spacing characters in the East Asian Ambiguous (A) category as --- 132,138 ---- (ucs >= 0x20000 && ucs <= 0x2ffff) */)); } ! #if 1 /* * The following function is the same as konsole_wcwidth(), except that * spacing characters in the East Asian Ambiguous (A) category as *************** *** 140,146 **** * encodings who want to migrate to UCS. It is not otherwise * recommended for general use. */ ! int konsole_wcwidth_cjk(Q_UINT16 ucs) { /* sorted list of non-overlapping intervals of East Asian Ambiguous * characters */ --- 141,147 ---- * encodings who want to migrate to UCS. It is not otherwise * recommended for general use. */ ! int konsole_wcwidth(Q_UINT16 ucs) { /* sorted list of non-overlapping intervals of East Asian Ambiguous * characters */ *************** *** 184,190 **** { 0x226E, 0x226F }, { 0x2282, 0x2283 }, { 0x2286, 0x2287 }, { 0x2295, 0x2295 }, { 0x2299, 0x2299 }, { 0x22A5, 0x22A5 }, { 0x22BF, 0x22BF }, { 0x2312, 0x2312 }, { 0x2460, 0x24BF }, ! { 0x24D0, 0x24E9 }, { 0x2500, 0x254B }, { 0x2550, 0x2574 }, { 0x2580, 0x258F }, { 0x2592, 0x2595 }, { 0x25A0, 0x25A1 }, { 0x25A3, 0x25A9 }, { 0x25B2, 0x25B3 }, { 0x25B6, 0x25B7 }, { 0x25BC, 0x25BD }, { 0x25C0, 0x25C1 }, { 0x25C6, 0x25C8 }, --- 185,195 ---- { 0x226E, 0x226F }, { 0x2282, 0x2283 }, { 0x2286, 0x2287 }, { 0x2295, 0x2295 }, { 0x2299, 0x2299 }, { 0x22A5, 0x22A5 }, { 0x22BF, 0x22BF }, { 0x2312, 0x2312 }, { 0x2460, 0x24BF }, ! { 0x24D0, 0x24E9 }, ! #if 0 // Graphic line chars ! { 0x2500, 0x254B }, ! #endif ! { 0x2550, 0x2574 }, { 0x2580, 0x258F }, { 0x2592, 0x2595 }, { 0x25A0, 0x25A1 }, { 0x25A3, 0x25A9 }, { 0x25B2, 0x25B3 }, { 0x25B6, 0x25B7 }, { 0x25BC, 0x25BD }, { 0x25C0, 0x25C1 }, { 0x25C6, 0x25C8 }, *************** *** 202,208 **** sizeof(ambiguous) / sizeof(struct interval) - 1)) return 2; ! return konsole_wcwidth(ucs); } #endif --- 207,213 ---- sizeof(ambiguous) / sizeof(struct interval) - 1)) return 2; ! return __konsole_wcwidth(ucs); } #endif konsole-3.5.8-1127.diff [^] (19,229 バイト) 2007-11-28 02:08 [表示] [非表示] *** konsole/konsole/TEWidget.cpp.ORG 2007-11-21 18:28:36.000000000 +0900 --- konsole/konsole/TEWidget.cpp 2007-11-28 01:30:19.677000000 +0900 *************** *** 373,383 **** ,rimY(1) ,m_imPreeditText(QString::null) ,m_imPreeditLength(0) ! ,m_imStart(0) ,m_imStartLine(0) ! ,m_imEnd(0) ! ,m_imSelStart(0) ! ,m_imSelEnd(0) ,m_cursorLine(0) ,m_cursorCol(0) ,m_isIMEdit(false) --- 373,383 ---- ,rimY(1) ,m_imPreeditText(QString::null) ,m_imPreeditLength(0) ! ,m_imStart(-1) ,m_imStartLine(0) ! ,m_imEnd(-1) ! ,m_imSelStart(-1) ! ,m_imSelEnd(-1) ,m_cursorLine(0) ,m_cursorCol(0) ,m_isIMEdit(false) *************** *** 643,674 **** } else paint.fillRect(rect, bColor); } - - QString tmpStr = str.simplifyWhiteSpace(); - if ( m_isIMEdit && !tmpStr.isEmpty() ) { // imput method edit area background color - QRect tmpRect = rect; - if ( str != m_imPreeditText ) { // ugly hack - tmpRect.setLeft( tmpRect.left() + font_w ); - tmpRect.setWidth( tmpRect.width() + font_w ); - } - - paint.fillRect( tmpRect, Qt::darkCyan ); // currently use hard code color - } - - if ( m_isIMSel && !tmpStr.isEmpty() ) { // imput method selection background color - int x = rect.left() + ( font_w * (m_imSelStart - m_imStart) ); - int y = rect.top(); - int w = font_w * (m_imSelEnd - m_imSelStart); - int h = font_h; - - QRect tmpRect = QRect( x, y, w, h ); - if ( str != m_imPreeditText ) { // ugly hack - tmpRect.setLeft( tmpRect.left() + font_w ); - tmpRect.setWidth( tmpRect.width() + font_w ); - } - - paint.fillRect( tmpRect, Qt::darkGray ); // currently use hard code color - } } // Paint cursor --- 643,648 ---- *************** *** 791,796 **** --- 765,774 ---- // fprintf(stderr, "x/y = %d/%d\txpos/ypos = %d/%d\n", curx, cury, xpos, ypos); m_cursorLine = cury; m_cursorCol = curx; + + // OK, now the event queue is going to be flushed. + if (m_imStart == m_imEnd && m_imSelStart < 0) + m_imEnd = m_imStart = -1; } /*! *************** *** 798,804 **** The size of the new image may or may not match the size of the widget. */ ! void TEWidget::setImage(const ca* const newimg, int lines, int columns) { if (!image) --- 776,803 ---- The size of the new image may or may not match the size of the widget. */ ! static bool __check_preedit(const int& cols, const int& lins, ! const int& imstartline, const int& imstart, const int& imend, ! const int& cx, const int& cy) ! { ! ! if (imstartline >= lins) ! return false; ! if (imend <= (lins - imstartline) * cols || cy <= lins - 2) ! { ! int abspos = (cy - imstartline) * cols + cx; ! return (imstart <= abspos && abspos < imend); ! } ! if (imend >= ((lins - imstartline) + 1) * cols) ! return true; ! // ! // Here the current conditions are cy == lins - 1 and ! // (lins - imstartline) * cols < imend < (lins - imstartline + 1) * cols ! // ! int selp = (imstartline == lins - 1) ? (imstart % cols) : 0; ! return (cx >= selp || cx < (imend % cols)); ! } ! void TEWidget::setImage(const ca* const newimg, int lines, int columns) { if (!image) *************** *** 834,849 **** // mark surrounding neighbours dirty, in case the character exceeds // its cell boundaries memset(dirtyMask, 0, cols+2); // Two extra so that we don't have to have to care about start and end conditions ! for (x = 0; x < cols; x++) ! { ! if ( ( (m_imPreeditLength > 0) && ( ( m_imStartLine == y ) ! && ( ( m_imStart < m_imEnd ) && ( ( x > m_imStart ) ) && ( x < m_imEnd ) ) ! || ( ( m_imSelStart < m_imSelEnd ) && ( ( x > m_imSelStart ) ) ) ) ) ! || ext[x] != lcl[x]) ! { ! dirtyMask[x] = dirtyMask[x+1] = dirtyMask[x+2] = 1; ! } } dirtyMask++; // Position correctly --- 833,843 ---- // mark surrounding neighbours dirty, in case the character exceeds // its cell boundaries memset(dirtyMask, 0, cols+2); + // Two extra so that we don't have to have to care about start and end conditions ! for (x = 0; x < cols; x++) { ! if (ext[x] != lcl[x]) ! dirtyMask[x] = dirtyMask[x+1] = dirtyMask[x+2] = 1; } dirtyMask++; // Position correctly *************** *** 857,862 **** --- 851,859 ---- if (dirtyMask[x]) { Q_UINT16 c = ext[x+0].c; + if (m_imEnd > m_imStart && __check_preedit(cols, lins, + m_imStartLine, m_imStart, m_imEnd, x, y) == true) + continue; if ( !c ) continue; int p = 0; *************** *** 873,878 **** --- 870,879 ---- if (!c) continue; // Skip trailing part of multi-col chars. + if (m_imEnd > m_imStart && __check_preedit(cols, lins, + m_imStartLine, m_imStart, m_imEnd, x + len, y) == true) + break; + if (ext[x+len].f != cf || ext[x+len].b != cb || ext[x+len].r != cr || !dirtyMask[x+len] || isLineChar(c) != lineDraw || (ext[x+len+1].c == 0) != doubleWidth) break; *************** *** 882,904 **** QString unistr(disstrU, p); - // for XIM on the spot input style - m_isIMEdit = m_isIMSel = false; - if ( m_imStartLine == y ) { - if ( ( m_imStart < m_imEnd ) && ( x >= m_imStart-1 ) && ( x + int( unistr.length() ) <= m_imEnd ) ) - m_isIMEdit = true; - - if ( ( m_imSelStart < m_imSelEnd ) && ( x >= m_imStart-1 ) && ( x + int( unistr.length() ) <= m_imEnd ) ) - m_isIMSel = true; - } - else if ( m_imStartLine < y ) { // for word worp - if ( ( m_imStart < m_imEnd ) ) - m_isIMEdit = true; - - if ( ( m_imSelStart < m_imSelEnd ) ) - m_isIMSel = true; - } - bool save_fixed_font = fixed_font; if (lineDraw) fixed_font = false; --- 883,888 ---- *************** *** 1921,1983 **** void TEWidget::imStartEvent( QIMEvent */*e*/ ) { ! m_imStart = m_cursorCol; ! m_imStartLine = m_cursorLine; m_imPreeditLength = 0; ! m_imEnd = m_imSelStart = m_imSelEnd = 0; m_isIMEdit = m_isIMSel = false; } void TEWidget::imComposeEvent( QIMEvent *e ) { ! QString text = QString::null; ! if ( m_imPreeditLength > 0 ) { ! text.fill( '\010', m_imPreeditLength ); } ! m_imEnd = m_imStart + string_width( e->text() ); ! QString tmpStr = e->text().left( e->cursorPos() ); ! m_imSelStart = m_imStart + string_width( tmpStr ); - tmpStr = e->text().mid( e->cursorPos(), e->selectionLength() ); - m_imSelEnd = m_imSelStart + string_width( tmpStr ); - m_imPreeditLength = e->text().length(); m_imPreeditText = e->text(); ! text += e->text(); ! if ( text.length() > 0 ) { ! QKeyEvent ke( QEvent::KeyPress, 0, -1, 0, text ); ! emit keyPressedSignal( &ke ); ! } } void TEWidget::imEndEvent( QIMEvent *e ) { - QString text = QString::null; - if ( m_imPreeditLength > 0 ) { - text.fill( '\010', m_imPreeditLength ); - } ! m_imEnd = m_imSelStart = m_imSelEnd = 0; ! text += e->text(); ! if ( text.length() > 0 ) { ! QKeyEvent ke( QEvent::KeyPress, 0, -1, 0, text ); ! emit keyPressedSignal( &ke ); } ! QPoint tL = contentsRect().topLeft(); int tLx = tL.x(); int tLy = tL.y(); ! QRect repaintRect = QRect( bX+tLx, bY+tLy+font_h*m_imStartLine, ! contentsRect().width(), contentsRect().height() ); ! m_imStart = 0; ! m_imPreeditLength = 0; m_isIMEdit = m_isIMSel = false; ! repaint( repaintRect, true ); } // Override any Ctrl+<key> accelerator when pressed with the keyboard --- 1905,2207 ---- void TEWidget::imStartEvent( QIMEvent */*e*/ ) { ! //#define IM_EVENT_DEBUG 0 ! #ifdef IM_EVENT_DEBUG ! printf("Start: %d %d %d %d %d \n", ! m_imStart, m_imEnd, m_imPreeditLength, m_imSelStart, m_imSelEnd); ! #endif ! ! // ! // The m_imStart < 0 means that the event queue ! // is empty, thus we can trust the cursor position. ! // Moreover m_imStart == m_imEnd implies that ! // we have any preedit string currently or commited that already. ! // m_imPreeditLength = 0; + m_imEnd = m_imStart; ! // ! // The m_imSelStart >= 0 means the IM state is now proceeding ! // from "changed callbacks" to "end callback" ! // ! m_imSelStart = m_imSelEnd = -1; m_isIMEdit = m_isIMSel = false; } void TEWidget::imComposeEvent( QIMEvent *e ) { ! ! if (m_imStart < 0) ! { ! m_imEnd = m_imStart = (m_cursorCol % columns); ! m_imStartLine = m_cursorLine; ! m_imSelStart = m_imSelEnd = 0; ! #ifdef IM_EVENT_DEBUG ! printf("DelayStart(C): %d %d %d %d %d \n", ! m_imStart, m_imEnd, m_imPreeditLength, m_imSelStart, m_imSelEnd); ! #endif ! } ! ! // Sanity check ! if (m_imStart >= columns || m_imStartLine >= lines) ! { ! printf("Changed: Strange m_imStart %d(%d) m_imStartLine %d(%d)\n", ! m_imStart, columns, m_imStartLine, lines); ! return; ! } ! // Setup the preedit region. ! int oimEnd = m_imEnd; ! m_imEnd = m_imStart; ! m_imSelEnd = m_imSelStart; ! ! QPainter paint; ! setUpdatesEnabled(false); ! paint.begin( this ); ! QPoint tL = contentsRect().topLeft(); ! int tLx = tL.x(); ! int tLy = tL.y(); ! QRect tmpRect; ! ! ca data[(columns + 2) * sizeof(ca)]; ! ca dft(' ',cacol(CO_DFT,DEFAULT_FORE_COLOR), ! cacol(CO_DFT,DEFAULT_BACK_COLOR),DEFAULT_RENDITION); ! ! int wcwidth = 1, i, x, xpos; ! for (i = 0, x = m_imStart, xpos = 0; i < e->text().length(); ) ! { ! int p = 0; ! int redraw_p = -1, redraw_x = -1; ! QChar disstrU[columns + 2]; ! ! wcwidth = konsole_wcwidth(e->text()[i].unicode()); ! for ( ; x < columns && i < e->text().length(); i++) ! { ! Q_UINT16 c, tmpwcwidth; ! ! c = e->text()[i].unicode(); ! tmpwcwidth = konsole_wcwidth(c); ! if (wcwidth != tmpwcwidth) ! break; ! ! // Check a selection start point. ! if (i == e->cursorPos()) ! { ! m_imSelStart = xpos + x; ! m_imSelEnd = m_imSelStart + lines * columns; /* XXX */ ! } ! #define FAST_REDRAW "yes" ! #ifdef FAST_REDRAW ! if (redraw_x == -1) ! { ! if ((e->cursorPos() < e->text().length() ! /* && i >= e->cursorPos()*/) || ! (i >= m_imPreeditLength || m_imPreeditText[i].unicode() != c)) ! { ! redraw_p = p; redraw_x = x; ! } ! } ! #else /* !FAST_REDRAW */ ! if (redraw_x == -1) ! { ! redraw_p = p; redraw_x = x; ! } ! #endif /* !FAST_REDRAW */ ! ! data[x] = dft; ! data[x++].c = c; ! m_imEnd ++; ! if (tmpwcwidth == 2) ! { ! // Check the wrapping. ! if (x >= columns) ! { ! disstrU[p ++] = data[x-1].c = ' '; ! break; ! } ! data[x] = dft; ! data[x++].c = 0; ! m_imEnd ++; ! } ! ! disstrU[p ++] = c; ! ! // Check a selection end point. ! if ((i + 1) == e->cursorPos() + QMAX(1, e->selectionLength())) ! m_imSelEnd = xpos + x; ! } ! ! int xlen; ! int y = QMIN(lines - 1, (m_imStartLine + (xpos/columns))); ! ! #define FONT_GAPS 0 ! if (redraw_x >= 0 && x - redraw_x > 0) ! { ! tmpRect = QRect(bX + tLx + font_w * redraw_x, ! bY + tLy + font_h * y, ! font_w * (x - redraw_x)+ FONT_GAPS, font_h); ! erase(tmpRect); ! } ! ! if (redraw_p >= 0 && p - redraw_p > 0) ! { ! xlen = QMIN(x - redraw_x, m_imEnd - redraw_x - xpos); ! tmpRect = QRect(bX + tLx + font_w * redraw_x, ! bY + tLy + font_h * y, font_w * xlen, font_h); ! paint.fillRect(tmpRect, Qt::darkCyan); ! ! if (m_imSelStart < m_imSelEnd && ! !(xpos + redraw_x > m_imSelEnd || ! xpos + x <= m_imSelStart)) ! { ! int sels = redraw_x; ! if (xpos + redraw_x <= m_imSelStart && ! m_imSelStart < xpos + x) ! sels = (m_imSelStart % columns); ! xlen = QMIN(x - sels, ! m_imSelEnd - xpos - sels); ! tmpRect = QRect(bX + tLx + font_w * sels, ! bY + tLy + font_h * y, ! font_w * xlen, font_h); ! paint.fillRect(tmpRect, Qt::darkGray); ! } ! ! QString unistr(&disstrU[redraw_p], p - redraw_p); ! if (wcwidth == 2) ! { ! drawTextFixed(paint, bX + tLx + font_w * redraw_x, ! bY + tLy + font_h * y, unistr, &data[redraw_x]); ! } ! else ! { ! int a = font_a + m_lineSpacing / 2; ! paint.drawText(bX + tLx + font_w * redraw_x, ! bY + tLy + font_h * y + a, ! unistr, -1, ! bidiEnabled ? QPainter::Auto : QPainter::LTR ); ! } ! } ! ! if (x == columns) ! { ! x = 0; ! xpos += columns; ! } } ! for ( ; xpos + x < oimEnd; x = 0, xpos += columns) ! { ! int xlen = QMIN(columns - x, oimEnd - x - xpos); ! int y = QMIN(lines - 1, (m_imStartLine + (xpos/columns))); ! tmpRect = QRect(bX + tLx + font_w * x, ! bY + tLy + font_h * y, font_w * xlen, font_h); ! paintContents(paint, tmpRect, backgroundPixmap() != 0); ! } ! ! drawFrame(&paint); ! paint.end(); ! setUpdatesEnabled(true); m_imPreeditText = e->text(); ! m_imPreeditLength = m_imPreeditText.length(); ! #ifdef IM_EVENT_DEBUG ! printf("Compose: %d %d %d %d %d: %d %d %d \n", ! m_imStart, m_imEnd, m_imPreeditLength, m_imSelStart, m_imSelEnd, ! e->text().length(), e->cursorPos(), e->selectionLength()); ! #endif } void TEWidget::imEndEvent( QIMEvent *e ) { ! if (m_imStart < 0) ! { ! m_imEnd = m_imStart = (m_cursorCol % columns); ! m_imStartLine = m_cursorLine; ! m_imSelStart = m_imSelEnd = 0; ! #ifdef IM_EVENT_DEBUG ! printf("DelayStart(E): %d %d %d %d %d \n", ! m_imStart, m_imEnd, m_imPreeditLength, m_imSelStart, m_imSelEnd); ! #endif ! } ! ! // Sanity check ! if (m_imStart >= columns || m_imStartLine >= lines) ! { ! printf("Commit: Strange m_imStart %d(%d) m_imStartLine %d(%d)\n", ! m_imStart, columns, m_imStartLine, lines); ! return; } ! ! // Clear all preedit strings. ! QPainter paint; ! setUpdatesEnabled(false); ! paint.begin( this ); QPoint tL = contentsRect().topLeft(); int tLx = tL.x(); int tLy = tL.y(); + int cpos, cline, xlen; ! for (cpos = m_imStart, cline = m_imStartLine; ! cpos < m_imEnd; cline += 1, cpos += xlen) ! { ! int spos, y; ! ! y = QMIN(lines - 1, cline); ! if (cpos == m_imStart) ! { ! xlen = QMIN(columns - cpos, m_imEnd - cpos); ! spos = m_imStart; ! } ! else ! { ! xlen = QMIN(columns, m_imEnd - cpos); ! spos = 0; ! } ! ! QRect tmpRect = QRect(bX + tLx + font_w * spos, ! bY + tLy + font_h * y, font_w * xlen, font_h); ! paintContents(paint, tmpRect, backgroundPixmap() != 0); ! } ! drawFrame(&paint); ! paint.end(); ! setUpdatesEnabled(true); ! ! // Calculte the true cursor position for the next im_start ! // in case of the non empty event queue ! int i, xpos; ! ! for (i = 0, xpos = m_imStart; i < (int) e->text().length(); i ++) ! { ! int xres = columns - (xpos % columns); ! xlen = konsole_wcwidth(e->text()[i].unicode()); ! if (xres < xlen) ! xpos += xres; ! xpos += xlen; ! } ! ! // All informations are cleared here. ! m_imStart = (xpos % columns); ! m_imEnd = m_imStart; ! m_imSelStart = m_imSelEnd = -1; m_isIMEdit = m_isIMSel = false; ! m_imStartLine += (xpos / columns); ! m_imPreeditLength = 0; ! m_imPreeditText = QString::null; ! ! // Emit key events. ! if (e->text().length() > 0 ) { ! QKeyEvent ke( QEvent::KeyPress, 0, -1, 0, e->text()); ! emit keyPressedSignal( &ke ); ! } ! ! #ifdef IM_EVENT_DEBUG ! printf("End: %d %d %d %d %d: %d %d %d \n", ! m_imStart, m_imEnd, m_imPreeditLength, m_imSelStart, m_imSelEnd, ! e->text().length(), e->cursorPos(), e->selectionLength()); ! #endif } // Override any Ctrl+<key> accelerator when pressed with the keyboard *** konsole/konsole/konsole_wcwidth.cpp.ORG 2007-11-21 18:28:55.000000000 +0900 --- konsole/konsole/konsole_wcwidth.cpp 2007-11-23 02:53:39.507000000 +0900 *************** *** 65,71 **** * in ISO 10646. */ ! int konsole_wcwidth(Q_UINT16 ucs) { /* sorted list of non-overlapping intervals of non-spacing characters */ static const struct interval combining[] = { --- 65,72 ---- * in ISO 10646. */ ! static int __konsole_wcwidth(Q_UINT16); ! static int __konsole_wcwidth(Q_UINT16 ucs) { /* sorted list of non-overlapping intervals of non-spacing characters */ static const struct interval combining[] = { *************** *** 131,137 **** (ucs >= 0x20000 && ucs <= 0x2ffff) */)); } ! #if 0 /* * The following function is the same as konsole_wcwidth(), except that * spacing characters in the East Asian Ambiguous (A) category as --- 132,138 ---- (ucs >= 0x20000 && ucs <= 0x2ffff) */)); } ! #if 1 /* * The following function is the same as konsole_wcwidth(), except that * spacing characters in the East Asian Ambiguous (A) category as *************** *** 140,146 **** * encodings who want to migrate to UCS. It is not otherwise * recommended for general use. */ ! int konsole_wcwidth_cjk(Q_UINT16 ucs) { /* sorted list of non-overlapping intervals of East Asian Ambiguous * characters */ --- 141,147 ---- * encodings who want to migrate to UCS. It is not otherwise * recommended for general use. */ ! int konsole_wcwidth(Q_UINT16 ucs) { /* sorted list of non-overlapping intervals of East Asian Ambiguous * characters */ *************** *** 184,190 **** { 0x226E, 0x226F }, { 0x2282, 0x2283 }, { 0x2286, 0x2287 }, { 0x2295, 0x2295 }, { 0x2299, 0x2299 }, { 0x22A5, 0x22A5 }, { 0x22BF, 0x22BF }, { 0x2312, 0x2312 }, { 0x2460, 0x24BF }, ! { 0x24D0, 0x24E9 }, { 0x2500, 0x254B }, { 0x2550, 0x2574 }, { 0x2580, 0x258F }, { 0x2592, 0x2595 }, { 0x25A0, 0x25A1 }, { 0x25A3, 0x25A9 }, { 0x25B2, 0x25B3 }, { 0x25B6, 0x25B7 }, { 0x25BC, 0x25BD }, { 0x25C0, 0x25C1 }, { 0x25C6, 0x25C8 }, --- 185,195 ---- { 0x226E, 0x226F }, { 0x2282, 0x2283 }, { 0x2286, 0x2287 }, { 0x2295, 0x2295 }, { 0x2299, 0x2299 }, { 0x22A5, 0x22A5 }, { 0x22BF, 0x22BF }, { 0x2312, 0x2312 }, { 0x2460, 0x24BF }, ! { 0x24D0, 0x24E9 }, ! #if 0 // Graphic line chars ! { 0x2500, 0x254B }, ! #endif ! { 0x2550, 0x2574 }, { 0x2580, 0x258F }, { 0x2592, 0x2595 }, { 0x25A0, 0x25A1 }, { 0x25A3, 0x25A9 }, { 0x25B2, 0x25B3 }, { 0x25B6, 0x25B7 }, { 0x25BC, 0x25BD }, { 0x25C0, 0x25C1 }, { 0x25C6, 0x25C8 }, *************** *** 202,208 **** sizeof(ambiguous) / sizeof(struct interval) - 1)) return 2; ! return konsole_wcwidth(ucs); } #endif --- 207,213 ---- sizeof(ambiguous) / sizeof(struct interval) - 1)) return 2; ! return __konsole_wcwidth(ucs); } #endif konsole-3.5.8-1130.diff [^] (26,339 バイト) 2007-11-30 17:20 [表示] [非表示] *** konsole/konsole/TEWidget.cpp.ORG 2007-11-22 09:46:40.000000000 +0900 --- konsole/konsole/TEWidget.cpp 2007-11-30 16:42:17.000000000 +0900 *************** *** 329,334 **** --- 329,337 ---- /* Constructor / Destructor */ /* */ /* ------------------------------------------------------------------------- */ + #define m_isIMForceRedraw m_isIMSel + #define m_imCursorPos m_imPreeditLength + #define m_imSelLen m_imStartLine TEWidget::TEWidget(QWidget *parent, const char *name) :QFrame(parent,name,WNoAutoErase) *************** *** 372,387 **** ,rimX(1) ,rimY(1) ,m_imPreeditText(QString::null) ! ,m_imPreeditLength(0) ! ,m_imStart(0) ! ,m_imStartLine(0) ! ,m_imEnd(0) ,m_imSelStart(0) ,m_imSelEnd(0) ,m_cursorLine(0) ,m_cursorCol(0) ,m_isIMEdit(false) ! ,m_isIMSel(false) ,blend_color(qRgba(0,0,0,0xff)) { // The offsets are not yet calculated. --- 375,390 ---- ,rimX(1) ,rimY(1) ,m_imPreeditText(QString::null) ! ,m_imPreeditLength(0) // NOT USED! rename => m_imCursorPos ! ,m_imStart(-1) ! ,m_imStartLine(0) // NOT USED! rename => m_imSelLen ! ,m_imEnd(-1) ,m_imSelStart(0) ,m_imSelEnd(0) ,m_cursorLine(0) ,m_cursorCol(0) ,m_isIMEdit(false) ! ,m_isIMSel(false) // NOT USED! rename => m_isIMForceRedraw ,blend_color(qRgba(0,0,0,0xff)) { // The offsets are not yet calculated. *************** *** 643,674 **** } else paint.fillRect(rect, bColor); } - - QString tmpStr = str.simplifyWhiteSpace(); - if ( m_isIMEdit && !tmpStr.isEmpty() ) { // imput method edit area background color - QRect tmpRect = rect; - if ( str != m_imPreeditText ) { // ugly hack - tmpRect.setLeft( tmpRect.left() + font_w ); - tmpRect.setWidth( tmpRect.width() + font_w ); - } - - paint.fillRect( tmpRect, Qt::darkCyan ); // currently use hard code color - } - - if ( m_isIMSel && !tmpStr.isEmpty() ) { // imput method selection background color - int x = rect.left() + ( font_w * (m_imSelStart - m_imStart) ); - int y = rect.top(); - int w = font_w * (m_imSelEnd - m_imSelStart); - int h = font_h; - - QRect tmpRect = QRect( x, y, w, h ); - if ( str != m_imPreeditText ) { // ugly hack - tmpRect.setLeft( tmpRect.left() + font_w ); - tmpRect.setWidth( tmpRect.width() + font_w ); - } - - paint.fillRect( tmpRect, Qt::darkGray ); // currently use hard code color - } } // Paint cursor --- 646,651 ---- *************** *** 791,796 **** --- 768,780 ---- // fprintf(stderr, "x/y = %d/%d\txpos/ypos = %d/%d\n", curx, cury, xpos, ypos); m_cursorLine = cury; m_cursorCol = curx; + + // OK, now the event queue is going to be flushed. + if (m_imStart == m_imEnd) + m_imEnd = m_imStart = -1; + else if (m_isIMEdit == true && + m_imStart != m_cursorLine * columns + m_cursorCol) + imComposeEvent(NULL); } /*! *************** *** 798,804 **** The size of the new image may or may not match the size of the widget. */ ! void TEWidget::setImage(const ca* const newimg, int lines, int columns) { if (!image) --- 782,808 ---- The size of the new image may or may not match the size of the widget. */ ! static bool __check_preedit(const int& cols, const int& lins, ! const int& imstart, const int& imend, const int& cx, const int& cy) ! { ! ! if (imstart/cols >= lins) ! return false; ! if (imend <= lins * cols || cy <= lins - 2) ! { ! int abspos = cy * cols + cx; ! return (imstart <= abspos && abspos < imend); ! } ! if (imend >= (lins + 1) * cols) ! return true; ! // ! // Here the current conditions are cy == lins - 1 and ! // lins * cols < imend < (lins + 1) * cols ! // ! int selp = (imstart/cols == lins - 1) ? (imstart % cols) : 0; ! return (cx >= selp || cx < (imend % cols)); ! } ! void TEWidget::setImage(const ca* const newimg, int lines, int columns) { if (!image) *************** *** 834,849 **** // mark surrounding neighbours dirty, in case the character exceeds // its cell boundaries memset(dirtyMask, 0, cols+2); // Two extra so that we don't have to have to care about start and end conditions ! for (x = 0; x < cols; x++) ! { ! if ( ( (m_imPreeditLength > 0) && ( ( m_imStartLine == y ) ! && ( ( m_imStart < m_imEnd ) && ( ( x > m_imStart ) ) && ( x < m_imEnd ) ) ! || ( ( m_imSelStart < m_imSelEnd ) && ( ( x > m_imSelStart ) ) ) ) ) ! || ext[x] != lcl[x]) ! { ! dirtyMask[x] = dirtyMask[x+1] = dirtyMask[x+2] = 1; ! } } dirtyMask++; // Position correctly --- 838,848 ---- // mark surrounding neighbours dirty, in case the character exceeds // its cell boundaries memset(dirtyMask, 0, cols+2); + // Two extra so that we don't have to have to care about start and end conditions ! for (x = 0; x < cols; x++) { ! if (ext[x] != lcl[x]) ! dirtyMask[x] = dirtyMask[x+1] = dirtyMask[x+2] = 1; } dirtyMask++; // Position correctly *************** *** 857,862 **** --- 856,865 ---- if (dirtyMask[x]) { Q_UINT16 c = ext[x+0].c; + if (m_isIMEdit == true && + m_imEnd > m_imStart && __check_preedit(cols, lins, + m_imStart, m_imEnd, x, y) == true) + continue; if ( !c ) continue; int p = 0; *************** *** 873,878 **** --- 876,886 ---- if (!c) continue; // Skip trailing part of multi-col chars. + if (m_isIMEdit == true && + m_imEnd > m_imStart && __check_preedit(cols, lins, + m_imStart, m_imEnd, x + len, y) == true) + break; + if (ext[x+len].f != cf || ext[x+len].b != cb || ext[x+len].r != cr || !dirtyMask[x+len] || isLineChar(c) != lineDraw || (ext[x+len+1].c == 0) != doubleWidth) break; *************** *** 882,904 **** QString unistr(disstrU, p); - // for XIM on the spot input style - m_isIMEdit = m_isIMSel = false; - if ( m_imStartLine == y ) { - if ( ( m_imStart < m_imEnd ) && ( x >= m_imStart-1 ) && ( x + int( unistr.length() ) <= m_imEnd ) ) - m_isIMEdit = true; - - if ( ( m_imSelStart < m_imSelEnd ) && ( x >= m_imStart-1 ) && ( x + int( unistr.length() ) <= m_imEnd ) ) - m_isIMSel = true; - } - else if ( m_imStartLine < y ) { // for word worp - if ( ( m_imStart < m_imEnd ) ) - m_isIMEdit = true; - - if ( ( m_imSelStart < m_imSelEnd ) ) - m_isIMSel = true; - } - bool save_fixed_font = fixed_font; if (lineDraw) fixed_font = false; --- 890,895 ---- *************** *** 981,987 **** between the old and the new image. Instead, the internal image is used and the painting bound by the PaintEvent box. */ - void TEWidget::paintEvent( QPaintEvent* pe ) { const QPixmap* pm = backgroundPixmap(); --- 972,977 ---- *************** *** 1045,1050 **** --- 1035,1046 ---- paint.end(); setUpdatesEnabled(true); + + if (m_isIMEdit == true && /* m_isIMForceRedraw == true &&*/ m_imStart < m_imEnd) + { + m_isIMForceRedraw = true; + imComposeEvent(NULL); + } } void TEWidget::print(QPainter &paint, bool friendly, bool exact) *************** *** 1105,1110 **** --- 1101,1110 ---- { int len = 1; int p = 0; + if (m_isIMEdit == true && + m_imEnd > m_imStart && __check_preedit(columns, lines, + m_imStart, m_imEnd, x, y) == true) + continue; c = image[loc(x,y)].c; if (c) disstrU[p++] = c; //fontMap(c); *************** *** 1120,1125 **** --- 1120,1129 ---- (image[loc(x+len,y)+1].c == 0) == doubleWidth && isLineChar( c = image[loc(x+len,y)].c) == lineDraw) // Assignment! { + if (m_isIMEdit == true && + m_imEnd > m_imStart && __check_preedit(columns, lines, + m_imStart, m_imEnd, x + len, y) == true) + break; if (c) disstrU[p++] = c; //fontMap(c); if (doubleWidth) // assert((image[loc(x+len,y)+1].c == 0)), see above if condition *************** *** 1159,1165 **** void TEWidget::blinkCursorEvent() { cursorBlinking = !cursorBlinking; ! repaint(cursorRect, true); } /* ------------------------------------------------------------------------- */ --- 1163,1170 ---- void TEWidget::blinkCursorEvent() { cursorBlinking = !cursorBlinking; ! if (m_isIMEdit == false) ! repaint(cursorRect, true); } /* ------------------------------------------------------------------------- */ *************** *** 1735,1748 **** void TEWidget::focusInEvent( QFocusEvent * ) { ! repaint(cursorRect, true); // *do* erase area, to get rid of the // hollow cursor rectangle. } void TEWidget::focusOutEvent( QFocusEvent * ) { ! repaint(cursorRect, true); // don't erase area } bool TEWidget::focusNextPrevChild( bool next ) --- 1740,1766 ---- void TEWidget::focusInEvent( QFocusEvent * ) { ! ! m_isIMForceRedraw = true; ! if (m_isIMEdit == false) ! { ! repaint(cursorRect, true); // *do* erase area, to get rid of the // hollow cursor rectangle. + } + else + { + if (m_imStart < m_imEnd) + imComposeEvent(NULL); + } } void TEWidget::focusOutEvent( QFocusEvent * ) { ! ! m_isIMForceRedraw = true; ! if (m_isIMEdit == false) ! repaint(cursorRect, true); // don't erase area } bool TEWidget::focusNextPrevChild( bool next ) *************** *** 1921,1983 **** void TEWidget::imStartEvent( QIMEvent */*e*/ ) { ! m_imStart = m_cursorCol; ! m_imStartLine = m_cursorLine; ! m_imPreeditLength = 0; ! ! m_imEnd = m_imSelStart = m_imSelEnd = 0; ! m_isIMEdit = m_isIMSel = false; } void TEWidget::imComposeEvent( QIMEvent *e ) { - QString text = QString::null; - if ( m_imPreeditLength > 0 ) { - text.fill( '\010', m_imPreeditLength ); - } ! m_imEnd = m_imStart + string_width( e->text() ); ! QString tmpStr = e->text().left( e->cursorPos() ); ! m_imSelStart = m_imStart + string_width( tmpStr ); ! tmpStr = e->text().mid( e->cursorPos(), e->selectionLength() ); ! m_imSelEnd = m_imSelStart + string_width( tmpStr ); ! m_imPreeditLength = e->text().length(); ! m_imPreeditText = e->text(); ! text += e->text(); ! if ( text.length() > 0 ) { ! QKeyEvent ke( QEvent::KeyPress, 0, -1, 0, text ); ! emit keyPressedSignal( &ke ); } - } ! void TEWidget::imEndEvent( QIMEvent *e ) ! { ! QString text = QString::null; ! if ( m_imPreeditLength > 0 ) { ! text.fill( '\010', m_imPreeditLength ); ! } ! m_imEnd = m_imSelStart = m_imSelEnd = 0; ! text += e->text(); ! if ( text.length() > 0 ) { ! QKeyEvent ke( QEvent::KeyPress, 0, -1, 0, text ); ! emit keyPressedSignal( &ke ); } ! QPoint tL = contentsRect().topLeft(); ! int tLx = tL.x(); ! int tLy = tL.y(); ! QRect repaintRect = QRect( bX+tLx, bY+tLy+font_h*m_imStartLine, ! contentsRect().width(), contentsRect().height() ); ! m_imStart = 0; ! m_imPreeditLength = 0; ! m_isIMEdit = m_isIMSel = false; ! repaint( repaintRect, true ); } // Override any Ctrl+<key> accelerator when pressed with the keyboard --- 1939,2348 ---- void TEWidget::imStartEvent( QIMEvent */*e*/ ) { ! //#define IM_EVENT_DEBUG 0 ! #ifdef IM_EVENT_DEBUG ! printf("Start: %d %d %d %d \n", ! m_imStart, m_imEnd, m_imSelStart, m_imSelEnd); ! #endif ! ! // Sometimes SCIM skips to send the XIM_END, buggy enough! ! if (m_imStart < m_imEnd) ! imEndEvent(NULL); ! ! // The m_imStart < 0 means that the event queue ! // is empty, thus we can trust the cursor position. ! // Moreover m_imStart == m_imEnd implies that ! // we have no preedit string currently or commited that already. ! // ! m_imEnd = m_imStart; ! m_imSelStart = m_imSelEnd = 0; ! m_isIMEdit = m_isIMForceRedraw = false; ! m_imCursorPos = 0; ! m_imSelLen = 0; } void TEWidget::imComposeEvent( QIMEvent *e ) { ! if (m_imStart < 0) ! { ! m_imEnd = m_imStart = m_cursorCol + m_cursorLine * columns; ! m_imSelStart = m_imSelEnd = 0; ! #ifdef IM_EVENT_DEBUG ! printf("DelayStart(C): %d %d %d %d \n", ! m_imStart, m_imEnd, m_imSelStart, m_imSelEnd); ! #endif ! } ! ! // Sanity check ! if (image == NULL) ! return; ! ! // In the case of refresh. ! QString NText; ! int CursorPos, SelLen; ! if (e == NULL) ! { ! NText = m_imPreeditText; ! CursorPos = m_imCursorPos; ! SelLen = m_imSelLen; ! } ! else ! { ! // Do not believe the behavior of IM! ! NText = e->text(); ! CursorPos = QMAX(0, QMIN(e->cursorPos(), (int) NText.length())); ! SelLen = QMAX(e->selectionLength(), 0); ! } ! ! // Setup the painter. ! QPainter paint; ! setUpdatesEnabled(false); ! paint.begin( this ); ! QPoint tL = contentsRect().topLeft(); ! int tLx = tL.x(); ! int tLy = tL.y(); ! QRect tmpRect; ! // If the cursor position has been changed, then try to ! // relocate the preedit area. ! if (e == NULL && m_imEnd > m_imStart && ! m_imStart != m_cursorCol + m_cursorLine * columns) ! { ! int cpos, xpos, xlen; ! ! m_isIMEdit = false; // Should be turned off!! ! cpos = m_imStart; ! xpos = (m_imStart%columns); ! xlen = QMIN(columns - xpos, m_imEnd - cpos); ! while (cpos < m_imEnd) ! { ! int y = QMIN(lines - 1, cpos/columns); ! tmpRect = QRect(bX + tLx + font_w * xpos, ! bY + tLy + font_h * y, font_w * xlen, font_h); ! paintContents(paint, tmpRect, backgroundPixmap() != 0); ! cpos += xlen; ! xlen = QMIN(columns, m_imEnd - cpos); ! xpos = 0; ! } ! ! m_isIMEdit = true; ! m_isIMForceRedraw = true; ! m_imStart = m_imEnd = m_cursorCol + m_cursorLine * columns; ! } ! ! // Let us begin to draw the preedit area! ! int oimEnd = m_imEnd; ! m_imEnd = m_imStart; ! m_imSelEnd = m_imSelStart; ! ! ca data[(columns + 2) * sizeof(ca)]; ! ca dft(' ',cacol(CO_DFT,DEFAULT_FORE_COLOR), ! cacol(CO_DFT,DEFAULT_BACK_COLOR),DEFAULT_RENDITION); ! ! int wcwidth = 1, i, x, xpos; ! #define FAST_REDRAW "yes" ! #ifdef FAST_REDRAW ! int minselstart = (CursorPos < (int) NText.length()) ? CursorPos : NText.length(); ! if (m_imCursorPos < (int) m_imPreeditText.length() && minselstart > m_imCursorPos) ! minselstart = m_imCursorPos; ! #endif /* FAST_REDRAW */ ! ! for (i = 0, x = (m_imStart % columns), ! xpos = m_imStart - (m_imStart % columns); ! i < (int) NText.length(); ) ! { ! int p = 0; ! int redraw_p = -1, redraw_x = -1; ! QChar disstrU[columns + 2]; ! ! wcwidth = konsole_wcwidth(NText[i].unicode()); ! for ( ; x < columns && i < (int) NText.length(); i++) ! { ! Q_UINT16 c; ! int tmpwcwidth; ! ! c = NText[i].unicode(); ! tmpwcwidth = konsole_wcwidth(c); ! if (wcwidth != tmpwcwidth) ! break; ! ! // Check a selection start point. ! if (i == CursorPos) ! { ! m_imSelStart = xpos + x; ! m_imSelEnd = m_imSelStart + lines * columns; /* XXX */ ! } ! #ifdef FAST_REDRAW ! if (redraw_x == -1 && ! (m_isIMForceRedraw == true || i >= minselstart || ! (i >= (int) m_imPreeditText.length() || ! m_imPreeditText[i].unicode() != c))) ! { ! redraw_p = p; redraw_x = x; ! } ! #else /* !FAST_REDRAW */ ! if (redraw_x == -1) ! { ! redraw_p = p; redraw_x = x; ! } ! #endif /* !FAST_REDRAW */ ! ! data[x] = dft; ! data[x++].c = c; ! m_imEnd ++; ! if (tmpwcwidth == 2) ! { ! // Check the wrapping. ! if (x >= columns) ! { ! disstrU[p ++] = data[x-1].c = ' '; ! break; ! } ! data[x] = dft; ! data[x++].c = 0; ! m_imEnd ++; ! } ! ! disstrU[p ++] = c; ! ! // Check a selection end point. ! if ((i + 1) == CursorPos + QMAX(1, SelLen)) ! m_imSelEnd = xpos + x; ! } ! ! int y = QMIN(lines - 1, (xpos/columns)); ! ! // Check if the boundary of the preedit area is located at ! // the middle of a wide character in the underlying screen. ! if (i == (int) NText.length() && i > 0) // The last segment. ! { ! const ca* img = &image[y*columns]; ! if (img[x].c == 0 && img[x-1].c != 0 && x < columns && x > 0) ! { ! if (redraw_x < 0) ! { ! redraw_x = x; redraw_p = p; ! } ! data[x] = dft; ! disstrU[p ++] = data[x ++].c = ' '; ! m_imEnd ++; ! } ! } ! // Render the screen. ! if (redraw_x >= 0 && x - redraw_x > 0) ! { ! // The fake cursor ! int fcursorlen = 0; ! if (xpos + redraw_x == m_imStart && p > 0) // The first segment. ! if (konsole_wcwidth(disstrU[0]) == 1) ! fcursorlen = 1; ! ! const ca *attr = &image[y*columns + redraw_x]; ! QColor fColor = attr->f.color(color_table); ! QColor bColor = attr->b.color(color_table); ! ! m_isIMEdit = true; ! ! tmpRect = QRect(bX + tLx + font_w * redraw_x, ! bY + tLy + font_h * y, ! font_w * (x - redraw_x), font_h); ! #define IM_UNDERLINE ! #ifdef IM_UNDERLINE ! if (attr->isTransparent(color_table)) ! erase(tmpRect); ! else ! { ! #endif /* IM_UNERLINE */ ! ! paint.fillRect(tmpRect, Qt::darkCyan); ! ! #ifdef IM_UNDERLINE ! paint.fillRect(tmpRect, bColor); ! } ! #endif /* IM_UNERLINE */ ! ! if (redraw_p >= 0 && p - redraw_p > 0) ! { ! if (m_imSelStart < m_imSelEnd && ! !(xpos + redraw_x > m_imSelEnd || ! xpos + x <= m_imSelStart)) ! { ! int xlen, sels = redraw_x; ! if (xpos + redraw_x <= m_imSelStart && ! m_imSelStart < xpos + x) ! sels = (m_imSelStart % columns); ! xlen = QMIN(x - sels, ! m_imSelEnd - xpos - sels); ! tmpRect = QRect(bX + tLx + font_w * sels, ! bY + tLy + font_h * y, ! font_w * xlen, font_h); ! paint.fillRect(tmpRect, Qt::darkGray); ! } ! ! paint.setPen(fColor); ! QString unistr(&disstrU[redraw_p], p - redraw_p); ! int a = font_a + m_lineSpacing / 2; ! if (wcwidth == 2) ! { ! drawTextFixed(paint, bX + tLx + font_w * redraw_x, ! bY + tLy + font_h * y, unistr, &data[redraw_x]); ! } ! else ! { ! paint.drawText(bX + tLx + font_w * redraw_x, ! bY + tLy + font_h * y + a, ! unistr, -1, ! bidiEnabled ? QPainter::Auto : QPainter::LTR ); ! } ! ! #ifdef IM_UNDERLINE ! if (x - fcursorlen - redraw_x > 0) ! { ! // Draw an underline. ! paint.drawLine(bX + tLx + font_w * (redraw_x + fcursorlen), ! bY + tLy + font_h * y + a + 1, ! bX + tLx + font_w * (x - fcursorlen) - 1, ! bY + tLy + font_h * y + a + 1); ! } ! #endif /* IM_UNDERLINE */ ! ! if (fcursorlen > 0) ! { ! tmpRect = QRect(bX + tLx + font_w * redraw_x, ! bY + tLy + font_h * y /* + a */, ! font_w * fcursorlen, font_h /* - 2 * a */); ! paint.fillRect(tmpRect, fColor); ! paint.setPen(bColor); ! QString tmpstr(&disstrU[0], 1); ! paint.drawText(bX + tLx + font_w * redraw_x, ! bY + tLy + font_h * y + a, tmpstr, -1, ! bidiEnabled ? QPainter::Auto : QPainter::LTR ); ! paint.setPen(fColor); ! } ! } ! } ! if (x == columns) ! { ! x = 0; ! xpos += columns; ! } } ! for ( ; xpos + x < oimEnd; x = 0, xpos += columns) ! { ! int xlen = QMIN(columns - x, oimEnd - x - xpos); ! int y = QMIN(lines - 1, (xpos/columns)); ! tmpRect = QRect(bX + tLx + font_w * x, ! bY + tLy + font_h * y, font_w * xlen, font_h); ! paintContents(paint, tmpRect, backgroundPixmap() != 0); } + + drawFrame(&paint); + paint.end(); + setUpdatesEnabled(true); ! m_imPreeditText = NText; ! m_imCursorPos = CursorPos; ! m_imSelLen = SelLen; ! m_isIMForceRedraw = false; ! ! #ifdef IM_EVENT_DEBUG ! const char *s = (e == NULL) ? "refresh" : "normal"; ! printf("Compose(%s): %d %d %d %d: %d %d %d \n", s, ! m_imStart, m_imEnd, m_imSelStart, m_imSelEnd, ! NText.length(), CursorPos, SelLen); ! #endif ! } ! void TEWidget::imEndEvent( QIMEvent *e ) ! { ! // In the case of SCIM buggy behavior ! QString NText = QString::null; ! if (e != NULL) ! NText = e->text(); ! ! if (m_imStart < 0) ! { ! m_imEnd = m_imStart = m_cursorCol + m_cursorLine * columns; ! m_imSelStart = m_imSelEnd = 0; ! #ifdef IM_EVENT_DEBUG ! printf("DelayStart(E): %d %d %d %d \n", ! m_imStart, m_imEnd, m_imSelStart, m_imSelEnd); ! #endif ! } ! ! // Before call paintContents(), we should turn m_isIMEdit off. ! m_isIMEdit = m_isIMForceRedraw = false; ! m_imCursorPos = 0; ! m_imSelLen = 0; ! ! // Sanity check ! if (image != NULL && m_imStart < m_imEnd) ! { // Clear all preedit strings. ! QPainter paint; ! setUpdatesEnabled(false); ! paint.begin( this ); ! QPoint tL = contentsRect().topLeft(); ! int tLx = tL.x(); ! int tLy = tL.y(); ! int cpos, xpos, xlen; ! ! cpos = m_imStart; ! xpos = (m_imStart%columns); ! xlen = QMIN(columns - xpos, m_imEnd - cpos); ! while (cpos < m_imEnd) ! { ! int y = QMIN(lines - 1, cpos/columns); ! QRect tmpRect = QRect(bX + tLx + font_w * xpos, ! bY + tLy + font_h * y, font_w * xlen, font_h); ! paintContents(paint, tmpRect, backgroundPixmap() != 0); ! cpos += xlen; ! xlen = QMIN(columns, m_imEnd - cpos); ! xpos = 0; ! } ! drawFrame(&paint); ! paint.end(); ! setUpdatesEnabled(true); ! } ! ! // Calculte the true cursor position for the next im_start ! // in case of the non empty event queue ! int i, xpos, xlen; ! for (i = 0, xpos = m_imStart; i < (int) NText.length(); i ++) ! { ! int xres = columns - (xpos % columns); ! xlen = konsole_wcwidth(NText[i].unicode()); ! if (xres < xlen) ! xpos += xres; ! xpos += xlen; ! } ! ! // All informations are cleared here. ! m_imStart = xpos; ! m_imEnd = m_imStart; ! m_imSelStart = m_imSelEnd = 0; ! m_imPreeditText = QString::null; ! ! // Emit key events. ! if (NText.length() > 0 ) { ! QKeyEvent ke(QEvent::KeyPress, 0, -1, 0, NText); ! emit keyPressedSignal( &ke ); ! } ! ! #ifdef IM_EVENT_DEBUG ! if (e == NULL) ! printf("End(Buggy): %d %d %d %d\n", ! m_imStart, m_imEnd, m_imSelStart, m_imSelEnd); ! else ! printf("End: %d %d %d %d: %d %d %d \n", ! m_imStart, m_imEnd, m_imSelStart, m_imSelEnd, ! e->text().length(), e->cursorPos(), e->selectionLength()); ! #endif } // Override any Ctrl+<key> accelerator when pressed with the keyboard *** konsole/konsole/konsole_wcwidth.cpp.ORG 2007-11-22 09:47:00.000000000 +0900 --- konsole/konsole/konsole_wcwidth.cpp 2007-11-26 12:45:24.000000000 +0900 *************** *** 65,71 **** * in ISO 10646. */ ! int konsole_wcwidth(Q_UINT16 ucs) { /* sorted list of non-overlapping intervals of non-spacing characters */ static const struct interval combining[] = { --- 65,72 ---- * in ISO 10646. */ ! static int __konsole_wcwidth(Q_UINT16); ! static int __konsole_wcwidth(Q_UINT16 ucs) { /* sorted list of non-overlapping intervals of non-spacing characters */ static const struct interval combining[] = { *************** *** 131,137 **** (ucs >= 0x20000 && ucs <= 0x2ffff) */)); } ! #if 0 /* * The following function is the same as konsole_wcwidth(), except that * spacing characters in the East Asian Ambiguous (A) category as --- 132,138 ---- (ucs >= 0x20000 && ucs <= 0x2ffff) */)); } ! #if 1 /* * The following function is the same as konsole_wcwidth(), except that * spacing characters in the East Asian Ambiguous (A) category as *************** *** 140,146 **** * encodings who want to migrate to UCS. It is not otherwise * recommended for general use. */ ! int konsole_wcwidth_cjk(Q_UINT16 ucs) { /* sorted list of non-overlapping intervals of East Asian Ambiguous * characters */ --- 141,147 ---- * encodings who want to migrate to UCS. It is not otherwise * recommended for general use. */ ! int konsole_wcwidth(Q_UINT16 ucs) { /* sorted list of non-overlapping intervals of East Asian Ambiguous * characters */ *************** *** 184,190 **** { 0x226E, 0x226F }, { 0x2282, 0x2283 }, { 0x2286, 0x2287 }, { 0x2295, 0x2295 }, { 0x2299, 0x2299 }, { 0x22A5, 0x22A5 }, { 0x22BF, 0x22BF }, { 0x2312, 0x2312 }, { 0x2460, 0x24BF }, ! { 0x24D0, 0x24E9 }, { 0x2500, 0x254B }, { 0x2550, 0x2574 }, { 0x2580, 0x258F }, { 0x2592, 0x2595 }, { 0x25A0, 0x25A1 }, { 0x25A3, 0x25A9 }, { 0x25B2, 0x25B3 }, { 0x25B6, 0x25B7 }, { 0x25BC, 0x25BD }, { 0x25C0, 0x25C1 }, { 0x25C6, 0x25C8 }, --- 185,195 ---- { 0x226E, 0x226F }, { 0x2282, 0x2283 }, { 0x2286, 0x2287 }, { 0x2295, 0x2295 }, { 0x2299, 0x2299 }, { 0x22A5, 0x22A5 }, { 0x22BF, 0x22BF }, { 0x2312, 0x2312 }, { 0x2460, 0x24BF }, ! { 0x24D0, 0x24E9 }, ! #if 0 // Graphic line chars ! { 0x2500, 0x254B }, ! #endif ! { 0x2550, 0x2574 }, { 0x2580, 0x258F }, { 0x2592, 0x2595 }, { 0x25A0, 0x25A1 }, { 0x25A3, 0x25A9 }, { 0x25B2, 0x25B3 }, { 0x25B6, 0x25B7 }, { 0x25BC, 0x25BD }, { 0x25C0, 0x25C1 }, { 0x25C6, 0x25C8 }, *************** *** 202,208 **** sizeof(ambiguous) / sizeof(struct interval) - 1)) return 2; ! return konsole_wcwidth(ucs); } #endif --- 207,213 ---- sizeof(ambiguous) / sizeof(struct interval) - 1)) return 2; ! return __konsole_wcwidth(ucs); } #endif konsole-3.5.8-final.diff [^] (26,848 バイト) 2007-12-05 15:17 [表示] [非表示] *** konsole/konsole/TEWidget.cpp.ORG 2007-11-22 09:46:40.000000000 +0900 --- konsole/konsole/TEWidget.cpp 2007-12-05 14:19:45.000000000 +0900 *************** *** 329,334 **** --- 329,337 ---- /* Constructor / Destructor */ /* */ /* ------------------------------------------------------------------------- */ + #define m_isIMForceRedraw m_isIMSel + #define m_imCursorPos m_imPreeditLength + #define m_imSelLen m_imStartLine TEWidget::TEWidget(QWidget *parent, const char *name) :QFrame(parent,name,WNoAutoErase) *************** *** 372,387 **** ,rimX(1) ,rimY(1) ,m_imPreeditText(QString::null) ! ,m_imPreeditLength(0) ! ,m_imStart(0) ! ,m_imStartLine(0) ! ,m_imEnd(0) ,m_imSelStart(0) ,m_imSelEnd(0) ,m_cursorLine(0) ,m_cursorCol(0) ,m_isIMEdit(false) ! ,m_isIMSel(false) ,blend_color(qRgba(0,0,0,0xff)) { // The offsets are not yet calculated. --- 375,390 ---- ,rimX(1) ,rimY(1) ,m_imPreeditText(QString::null) ! ,m_imPreeditLength(0) // NOT USED! rename => m_imCursorPos ! ,m_imStart(-1) ! ,m_imStartLine(0) // NOT USED! rename => m_imSelLen ! ,m_imEnd(-1) ,m_imSelStart(0) ,m_imSelEnd(0) ,m_cursorLine(0) ,m_cursorCol(0) ,m_isIMEdit(false) ! ,m_isIMSel(false) // NOT USED! rename => m_isIMForceRedraw ,blend_color(qRgba(0,0,0,0xff)) { // The offsets are not yet calculated. *************** *** 543,549 **** if (toDraw & Int22) paint.drawPoint(cx, cy); if (toDraw & Int23) ! paint.drawPoint(cx+1, cy); if (toDraw & Int31) paint.drawPoint(cx-1, cy+1); --- 546,552 ---- if (toDraw & Int22) paint.drawPoint(cx, cy); if (toDraw & Int23) ! if (toDraw & Int31) paint.drawPoint(cx-1, cy+1); *************** *** 643,674 **** } else paint.fillRect(rect, bColor); } - - QString tmpStr = str.simplifyWhiteSpace(); - if ( m_isIMEdit && !tmpStr.isEmpty() ) { // imput method edit area background color - QRect tmpRect = rect; - if ( str != m_imPreeditText ) { // ugly hack - tmpRect.setLeft( tmpRect.left() + font_w ); - tmpRect.setWidth( tmpRect.width() + font_w ); - } - - paint.fillRect( tmpRect, Qt::darkCyan ); // currently use hard code color - } - - if ( m_isIMSel && !tmpStr.isEmpty() ) { // imput method selection background color - int x = rect.left() + ( font_w * (m_imSelStart - m_imStart) ); - int y = rect.top(); - int w = font_w * (m_imSelEnd - m_imSelStart); - int h = font_h; - - QRect tmpRect = QRect( x, y, w, h ); - if ( str != m_imPreeditText ) { // ugly hack - tmpRect.setLeft( tmpRect.left() + font_w ); - tmpRect.setWidth( tmpRect.width() + font_w ); - } - - paint.fillRect( tmpRect, Qt::darkGray ); // currently use hard code color - } } // Paint cursor --- 646,651 ---- *************** *** 791,796 **** --- 768,780 ---- // fprintf(stderr, "x/y = %d/%d\txpos/ypos = %d/%d\n", curx, cury, xpos, ypos); m_cursorLine = cury; m_cursorCol = curx; + + // OK, now the event queue is going to be flushed. + if (m_imStart == m_imEnd) + m_imEnd = m_imStart = -1; + else if (m_isIMEdit == true && + m_imStart != m_cursorLine * columns + m_cursorCol) + imComposeEvent(NULL); } /*! *************** *** 798,804 **** The size of the new image may or may not match the size of the widget. */ ! void TEWidget::setImage(const ca* const newimg, int lines, int columns) { if (!image) --- 782,808 ---- The size of the new image may or may not match the size of the widget. */ ! static bool __check_preedit(const int& cols, const int& lins, ! const int& imstart, const int& imend, const int& cx, const int& cy) ! { ! ! if (imstart/cols >= lins) ! return false; ! if (imend <= lins * cols || cy <= lins - 2) ! { ! int abspos = cy * cols + cx; ! return (imstart <= abspos && abspos < imend); ! } ! if (imend >= (lins + 1) * cols) ! return true; ! // ! // Here the current conditions are cy == lins - 1 and ! // lins * cols < imend < (lins + 1) * cols ! // ! int selp = (imstart/cols == lins - 1) ? (imstart % cols) : 0; ! return (cx >= selp || cx < (imend % cols)); ! } ! void TEWidget::setImage(const ca* const newimg, int lines, int columns) { if (!image) *************** *** 834,849 **** // mark surrounding neighbours dirty, in case the character exceeds // its cell boundaries memset(dirtyMask, 0, cols+2); // Two extra so that we don't have to have to care about start and end conditions ! for (x = 0; x < cols; x++) ! { ! if ( ( (m_imPreeditLength > 0) && ( ( m_imStartLine == y ) ! && ( ( m_imStart < m_imEnd ) && ( ( x > m_imStart ) ) && ( x < m_imEnd ) ) ! || ( ( m_imSelStart < m_imSelEnd ) && ( ( x > m_imSelStart ) ) ) ) ) ! || ext[x] != lcl[x]) ! { ! dirtyMask[x] = dirtyMask[x+1] = dirtyMask[x+2] = 1; ! } } dirtyMask++; // Position correctly --- 838,848 ---- // mark surrounding neighbours dirty, in case the character exceeds // its cell boundaries memset(dirtyMask, 0, cols+2); + // Two extra so that we don't have to have to care about start and end conditions ! for (x = 0; x < cols; x++) { ! if (ext[x] != lcl[x]) ! dirtyMask[x] = dirtyMask[x+1] = dirtyMask[x+2] = 1; } dirtyMask++; // Position correctly *************** *** 857,862 **** --- 856,865 ---- if (dirtyMask[x]) { Q_UINT16 c = ext[x+0].c; + if (m_isIMEdit == true && + m_imEnd > m_imStart && __check_preedit(cols, lins, + m_imStart, m_imEnd, x, y) == true) + continue; if ( !c ) continue; int p = 0; *************** *** 873,878 **** --- 876,886 ---- if (!c) continue; // Skip trailing part of multi-col chars. + if (m_isIMEdit == true && + m_imEnd > m_imStart && __check_preedit(cols, lins, + m_imStart, m_imEnd, x + len, y) == true) + break; + if (ext[x+len].f != cf || ext[x+len].b != cb || ext[x+len].r != cr || !dirtyMask[x+len] || isLineChar(c) != lineDraw || (ext[x+len+1].c == 0) != doubleWidth) break; *************** *** 882,904 **** QString unistr(disstrU, p); - // for XIM on the spot input style - m_isIMEdit = m_isIMSel = false; - if ( m_imStartLine == y ) { - if ( ( m_imStart < m_imEnd ) && ( x >= m_imStart-1 ) && ( x + int( unistr.length() ) <= m_imEnd ) ) - m_isIMEdit = true; - - if ( ( m_imSelStart < m_imSelEnd ) && ( x >= m_imStart-1 ) && ( x + int( unistr.length() ) <= m_imEnd ) ) - m_isIMSel = true; - } - else if ( m_imStartLine < y ) { // for word worp - if ( ( m_imStart < m_imEnd ) ) - m_isIMEdit = true; - - if ( ( m_imSelStart < m_imSelEnd ) ) - m_isIMSel = true; - } - bool save_fixed_font = fixed_font; if (lineDraw) fixed_font = false; --- 890,895 ---- *************** *** 981,987 **** between the old and the new image. Instead, the internal image is used and the painting bound by the PaintEvent box. */ - void TEWidget::paintEvent( QPaintEvent* pe ) { const QPixmap* pm = backgroundPixmap(); --- 972,977 ---- *************** *** 1045,1050 **** --- 1035,1046 ---- paint.end(); setUpdatesEnabled(true); + + if (m_isIMEdit == true && /* m_isIMForceRedraw == true &&*/ m_imStart < m_imEnd) + { + m_isIMForceRedraw = true; + imComposeEvent(NULL); + } } void TEWidget::print(QPainter &paint, bool friendly, bool exact) *************** *** 1105,1110 **** --- 1101,1110 ---- { int len = 1; int p = 0; + if (m_isIMEdit == true && + m_imEnd > m_imStart && __check_preedit(columns, lines, + m_imStart, m_imEnd, x, y) == true) + continue; c = image[loc(x,y)].c; if (c) disstrU[p++] = c; //fontMap(c); *************** *** 1120,1125 **** --- 1120,1129 ---- (image[loc(x+len,y)+1].c == 0) == doubleWidth && isLineChar( c = image[loc(x+len,y)].c) == lineDraw) // Assignment! { + if (m_isIMEdit == true && + m_imEnd > m_imStart && __check_preedit(columns, lines, + m_imStart, m_imEnd, x + len, y) == true) + break; if (c) disstrU[p++] = c; //fontMap(c); if (doubleWidth) // assert((image[loc(x+len,y)+1].c == 0)), see above if condition *************** *** 1159,1165 **** void TEWidget::blinkCursorEvent() { cursorBlinking = !cursorBlinking; ! repaint(cursorRect, true); } /* ------------------------------------------------------------------------- */ --- 1163,1170 ---- void TEWidget::blinkCursorEvent() { cursorBlinking = !cursorBlinking; ! if (m_isIMEdit == false) ! repaint(cursorRect, true); } /* ------------------------------------------------------------------------- */ *************** *** 1735,1748 **** void TEWidget::focusInEvent( QFocusEvent * ) { ! repaint(cursorRect, true); // *do* erase area, to get rid of the // hollow cursor rectangle. } void TEWidget::focusOutEvent( QFocusEvent * ) { ! repaint(cursorRect, true); // don't erase area } bool TEWidget::focusNextPrevChild( bool next ) --- 1740,1766 ---- void TEWidget::focusInEvent( QFocusEvent * ) { ! ! m_isIMForceRedraw = true; ! if (m_isIMEdit == false) ! { ! repaint(cursorRect, true); // *do* erase area, to get rid of the // hollow cursor rectangle. + } + else + { + if (m_imStart < m_imEnd) + imComposeEvent(NULL); + } } void TEWidget::focusOutEvent( QFocusEvent * ) { ! ! m_isIMForceRedraw = true; ! if (m_isIMEdit == false) ! repaint(cursorRect, true); // don't erase area } bool TEWidget::focusNextPrevChild( bool next ) *************** *** 1921,1983 **** void TEWidget::imStartEvent( QIMEvent */*e*/ ) { ! m_imStart = m_cursorCol; ! m_imStartLine = m_cursorLine; ! m_imPreeditLength = 0; ! ! m_imEnd = m_imSelStart = m_imSelEnd = 0; ! m_isIMEdit = m_isIMSel = false; } void TEWidget::imComposeEvent( QIMEvent *e ) { - QString text = QString::null; - if ( m_imPreeditLength > 0 ) { - text.fill( '\010', m_imPreeditLength ); - } ! m_imEnd = m_imStart + string_width( e->text() ); ! QString tmpStr = e->text().left( e->cursorPos() ); ! m_imSelStart = m_imStart + string_width( tmpStr ); ! tmpStr = e->text().mid( e->cursorPos(), e->selectionLength() ); ! m_imSelEnd = m_imSelStart + string_width( tmpStr ); ! m_imPreeditLength = e->text().length(); ! m_imPreeditText = e->text(); ! text += e->text(); ! if ( text.length() > 0 ) { ! QKeyEvent ke( QEvent::KeyPress, 0, -1, 0, text ); ! emit keyPressedSignal( &ke ); } - } ! void TEWidget::imEndEvent( QIMEvent *e ) ! { ! QString text = QString::null; ! if ( m_imPreeditLength > 0 ) { ! text.fill( '\010', m_imPreeditLength ); ! } ! m_imEnd = m_imSelStart = m_imSelEnd = 0; ! text += e->text(); ! if ( text.length() > 0 ) { ! QKeyEvent ke( QEvent::KeyPress, 0, -1, 0, text ); ! emit keyPressedSignal( &ke ); } ! QPoint tL = contentsRect().topLeft(); ! int tLx = tL.x(); ! int tLy = tL.y(); ! QRect repaintRect = QRect( bX+tLx, bY+tLy+font_h*m_imStartLine, ! contentsRect().width(), contentsRect().height() ); ! m_imStart = 0; ! m_imPreeditLength = 0; ! m_isIMEdit = m_isIMSel = false; ! repaint( repaintRect, true ); } // Override any Ctrl+<key> accelerator when pressed with the keyboard --- 1939,2343 ---- void TEWidget::imStartEvent( QIMEvent */*e*/ ) { ! //#define IM_EVENT_DEBUG 0 ! #ifdef IM_EVENT_DEBUG ! printf("Start: %d %d %d %d \n", ! m_imStart, m_imEnd, m_imSelStart, m_imSelEnd); ! #endif ! ! // Sometimes SCIM skips to send the XIM_END, buggy enough! ! if (m_imStart < m_imEnd) ! imEndEvent(NULL); ! ! // The m_imStart < 0 means that the event queue ! // is empty, thus we can trust the cursor position. ! // Moreover m_imStart == m_imEnd implies that ! // we have no preedit string currently or commited that already. ! // ! m_imEnd = m_imStart; ! m_imSelStart = m_imSelEnd = 0; ! m_isIMEdit = m_isIMForceRedraw = false; ! m_imCursorPos = 0; ! m_imSelLen = 0; } void TEWidget::imComposeEvent( QIMEvent *e ) { ! if (m_imStart < 0) ! { ! m_imEnd = m_imStart = m_cursorCol + m_cursorLine * columns; ! m_imSelStart = m_imSelEnd = 0; ! #ifdef IM_EVENT_DEBUG ! printf("DelayStart(C): %d %d %d %d \n", ! m_imStart, m_imEnd, m_imSelStart, m_imSelEnd); ! #endif ! } ! ! // Sanity check ! if (image == NULL) ! return; ! ! // In the case of refresh. ! QString NText; ! int CursorPos, SelLen; ! if (e == NULL) ! { ! NText = m_imPreeditText; ! CursorPos = m_imCursorPos; ! SelLen = m_imSelLen; ! } ! else ! { ! // Do not believe the behavior of IM! ! NText = e->text(); ! CursorPos = QMAX(0, QMIN(e->cursorPos(), (int) NText.length())); ! SelLen = QMAX(e->selectionLength(), 0); ! } ! ! // Setup the painter. ! QPainter paint; ! setUpdatesEnabled(false); ! paint.begin( this ); ! QPoint tL = contentsRect().topLeft(); ! int tLx = tL.x(); ! int tLy = tL.y(); ! QRect tmpRect; ! // If the cursor position has been changed, then try to ! // relocate the preedit area. ! if (e == NULL && m_imEnd > m_imStart && ! m_imStart != m_cursorCol + m_cursorLine * columns) ! { ! int cpos, xpos, xlen; ! ! m_isIMEdit = false; // Should be turned off!! ! cpos = m_imStart; ! xpos = (m_imStart%columns); ! xlen = QMIN(columns - xpos, m_imEnd - cpos); ! while (cpos < m_imEnd) ! { ! int y = QMIN(lines - 1, cpos/columns); ! tmpRect = QRect(bX + tLx + font_w * xpos, ! bY + tLy + font_h * y, font_w * xlen, font_h); ! paintContents(paint, tmpRect, backgroundPixmap() != 0); ! cpos += xlen; ! xlen = QMIN(columns, m_imEnd - cpos); ! xpos = 0; ! } ! ! m_isIMEdit = true; ! m_isIMForceRedraw = true; ! m_imStart = m_imEnd = m_cursorCol + m_cursorLine * columns; ! } ! ! // Let us begin to draw the preedit area! ! int oimEnd = m_imEnd; ! m_imEnd = m_imStart; ! m_imSelEnd = m_imSelStart; ! ! ca data[(columns + 2) * sizeof(ca)]; ! ca dft(' ',cacol(CO_DFT,DEFAULT_FORE_COLOR), ! cacol(CO_DFT,DEFAULT_BACK_COLOR),DEFAULT_RENDITION); ! ! int wcwidth = 1, i, x, xpos; ! #define FAST_REDRAW "yes" ! #ifdef FAST_REDRAW ! int minselstart = (CursorPos < (int) NText.length()) ? CursorPos : NText.length(); ! if (m_imCursorPos < (int) m_imPreeditText.length() && minselstart > m_imCursorPos) ! minselstart = m_imCursorPos; ! #endif /* FAST_REDRAW */ ! ! for (i = 0, x = (m_imStart % columns), ! xpos = m_imStart - (m_imStart % columns); ! i < (int) NText.length(); ) ! { ! int p = 0; ! int redraw_p = -1, redraw_x = -1; ! QChar disstrU[columns + 2]; ! ! wcwidth = konsole_wcwidth(NText[i].unicode()); ! for ( ; x < columns && i < (int) NText.length(); i++) ! { ! Q_UINT16 c; ! int tmpwcwidth; ! ! c = NText[i].unicode(); ! tmpwcwidth = konsole_wcwidth(c); ! if (wcwidth != tmpwcwidth) ! break; ! ! // Check a selection start point. ! if (i == CursorPos) ! { ! m_imSelStart = xpos + x; ! m_imSelEnd = m_imSelStart + lines * columns; /* XXX */ ! } ! #ifdef FAST_REDRAW ! if (redraw_x == -1 && ! (m_isIMForceRedraw == true || i >= minselstart || ! (i >= (int) m_imPreeditText.length() || ! m_imPreeditText[i].unicode() != c))) ! { ! redraw_p = p; redraw_x = x; ! } ! #else /* !FAST_REDRAW */ ! if (redraw_x == -1) ! { ! redraw_p = p; redraw_x = x; ! } ! #endif /* !FAST_REDRAW */ ! ! data[x] = dft; ! data[x++].c = c; ! m_imEnd ++; ! if (tmpwcwidth == 2) ! { ! // Check the wrapping. ! if (x >= columns) ! { ! disstrU[p ++] = data[x-1].c = ' '; ! break; ! } ! data[x] = dft; ! data[x++].c = 0; ! m_imEnd ++; ! } ! ! disstrU[p ++] = c; ! ! // Check a selection end point. ! if ((i + 1) == CursorPos + QMAX(1, SelLen)) ! m_imSelEnd = xpos + x; ! } ! ! int y = QMIN(lines - 1, (xpos/columns)); ! ! // Check if the boundary of the preedit area is located at ! // the middle of a wide character in the underlying screen. ! if (i == (int) NText.length() && i > 0) // The last segment. ! { ! const ca* img = &image[y*columns]; ! if (img[x].c == 0 && img[x-1].c != 0 && x < columns && x > 0) ! { ! if (redraw_x < 0) ! { ! redraw_x = x; redraw_p = p; ! } ! data[x] = dft; ! disstrU[p ++] = data[x ++].c = ' '; ! m_imEnd ++; ! } ! } ! // Render the screen. ! if (redraw_x >= 0 && x - redraw_x > 0) ! { ! // The fake cursor ! int fcursorlen = 0; ! if (xpos + redraw_x == m_imStart && p > 0) // The first segment. ! if (konsole_wcwidth(disstrU[0]) == 1) ! fcursorlen = 1; ! ! const ca *attr = &image[y*columns + redraw_x]; ! QColor fColor = attr->f.color(color_table); ! QColor bColor = attr->b.color(color_table); ! ! m_isIMEdit = true; ! ! tmpRect = QRect(bX + tLx + font_w * redraw_x, ! bY + tLy + font_h * y, ! font_w * (x - redraw_x), font_h); ! #define IM_UNDERLINE ! #ifdef IM_UNDERLINE ! if (attr->isTransparent(color_table)) ! erase(tmpRect); ! else ! paint.fillRect(tmpRect, bColor); ! #else /* IM_UNERLINE */ ! paint.fillRect(tmpRect, Qt::darkCyan); ! #endif /* IM_UNDERLINE */ ! ! if (redraw_p >= 0 && p - redraw_p > 0) ! { ! if (m_imSelStart < m_imSelEnd && ! !(xpos + redraw_x > m_imSelEnd || ! xpos + x <= m_imSelStart)) ! { ! int xlen, sels = redraw_x; ! if (xpos + redraw_x <= m_imSelStart && ! m_imSelStart < xpos + x) ! sels = (m_imSelStart % columns); ! xlen = QMIN(x - sels, ! m_imSelEnd - xpos - sels); ! tmpRect = QRect(bX + tLx + font_w * sels, ! bY + tLy + font_h * y, ! font_w * xlen, font_h); ! paint.fillRect(tmpRect, Qt::darkGray); ! } ! ! paint.setPen(fColor); ! QString unistr(&disstrU[redraw_p], p - redraw_p); ! int a = font_a + m_lineSpacing / 2; ! if (wcwidth == 2) ! { ! drawTextFixed(paint, bX + tLx + font_w * redraw_x, ! bY + tLy + font_h * y, unistr, &data[redraw_x]); ! } ! else ! { ! paint.drawText(bX + tLx + font_w * redraw_x, ! bY + tLy + font_h * y + a, ! unistr, -1, ! bidiEnabled ? QPainter::Auto : QPainter::LTR ); ! } ! ! #ifdef IM_UNDERLINE ! if (x - fcursorlen - redraw_x > 0) ! { ! // Draw an underline. ! paint.drawLine(bX + tLx + font_w * (redraw_x + fcursorlen), ! bY + tLy + font_h * y + a + 1, ! bX + tLx + font_w * (x - fcursorlen) - 1, ! bY + tLy + font_h * y + a + 1); ! } ! #endif /* IM_UNDERLINE */ ! ! if (fcursorlen > 0) ! { ! tmpRect = QRect(bX + tLx + font_w * redraw_x, ! bY + tLy + font_h * y /* + a */, ! font_w * fcursorlen, font_h /* - 2 * a */); ! paint.fillRect(tmpRect, fColor); ! paint.setPen(bColor); ! QString tmpstr(&disstrU[0], 1); ! paint.drawText(bX + tLx + font_w * redraw_x, ! bY + tLy + font_h * y + a, tmpstr, -1, ! bidiEnabled ? QPainter::Auto : QPainter::LTR ); ! paint.setPen(fColor); ! } ! } ! } ! if (x == columns) ! { ! x = 0; ! xpos += columns; ! } } ! for ( ; xpos + x < oimEnd; x = 0, xpos += columns) ! { ! int xlen = QMIN(columns - x, oimEnd - x - xpos); ! int y = QMIN(lines - 1, (xpos/columns)); ! tmpRect = QRect(bX + tLx + font_w * x, ! bY + tLy + font_h * y, font_w * xlen, font_h); ! paintContents(paint, tmpRect, backgroundPixmap() != 0); } + + drawFrame(&paint); + paint.end(); + setUpdatesEnabled(true); ! m_imPreeditText = NText; ! m_imCursorPos = CursorPos; ! m_imSelLen = SelLen; ! m_isIMForceRedraw = false; ! ! #ifdef IM_EVENT_DEBUG ! const char *s = (e == NULL) ? "refresh" : "normal"; ! printf("Compose(%s): %d %d %d %d: %d %d %d \n", s, ! m_imStart, m_imEnd, m_imSelStart, m_imSelEnd, ! NText.length(), CursorPos, SelLen); ! #endif ! } ! void TEWidget::imEndEvent( QIMEvent *e ) ! { ! // In the case of SCIM buggy behavior ! QString NText = QString::null; ! if (e != NULL) ! NText = e->text(); ! ! if (m_imStart < 0) ! { ! m_imEnd = m_imStart = m_cursorCol + m_cursorLine * columns; ! m_imSelStart = m_imSelEnd = 0; ! #ifdef IM_EVENT_DEBUG ! printf("DelayStart(E): %d %d %d %d \n", ! m_imStart, m_imEnd, m_imSelStart, m_imSelEnd); ! #endif ! } ! ! // Before call paintContents(), we should turn m_isIMEdit off. ! m_isIMEdit = m_isIMForceRedraw = false; ! m_imCursorPos = 0; ! m_imSelLen = 0; ! ! // Sanity check ! if (image != NULL && m_imStart < m_imEnd) ! { // Clear all preedit strings. ! QPainter paint; ! setUpdatesEnabled(false); ! paint.begin( this ); ! QPoint tL = contentsRect().topLeft(); ! int tLx = tL.x(); ! int tLy = tL.y(); ! int cpos, xpos, xlen; ! ! cpos = m_imStart; ! xpos = (m_imStart%columns); ! xlen = QMIN(columns - xpos, m_imEnd - cpos); ! while (cpos < m_imEnd) ! { ! int y = QMIN(lines - 1, cpos/columns); ! QRect tmpRect = QRect(bX + tLx + font_w * xpos, ! bY + tLy + font_h * y, font_w * xlen, font_h); ! paintContents(paint, tmpRect, backgroundPixmap() != 0); ! cpos += xlen; ! xlen = QMIN(columns, m_imEnd - cpos); ! xpos = 0; ! } ! drawFrame(&paint); ! paint.end(); ! setUpdatesEnabled(true); ! } ! ! // Calculte the true cursor position for the next im_start ! // in case of the non empty event queue ! int i, xpos, xlen; ! for (i = 0, xpos = m_imStart; i < (int) NText.length(); i ++) ! { ! int xres = columns - (xpos % columns); ! xlen = konsole_wcwidth(NText[i].unicode()); ! if (xres < xlen) ! xpos += xres; ! xpos += xlen; ! } ! ! // All informations are cleared here. ! m_imStart = xpos; ! m_imEnd = m_imStart; ! m_imSelStart = m_imSelEnd = 0; ! m_imPreeditText = QString::null; ! ! // Emit key events. ! if (NText.length() > 0 ) { ! QKeyEvent ke(QEvent::KeyPress, 0, -1, 0, NText); ! emit keyPressedSignal( &ke ); ! } ! ! #ifdef IM_EVENT_DEBUG ! if (e == NULL) ! printf("End(Buggy): %d %d %d %d\n", ! m_imStart, m_imEnd, m_imSelStart, m_imSelEnd); ! else ! printf("End: %d %d %d %d: %d %d %d \n", ! m_imStart, m_imEnd, m_imSelStart, m_imSelEnd, ! e->text().length(), e->cursorPos(), e->selectionLength()); ! #endif } // Override any Ctrl+<key> accelerator when pressed with the keyboard *** konsole/konsole/konsole_wcwidth.cpp.ORG 2007-11-22 09:47:00.000000000 +0900 --- konsole/konsole/konsole_wcwidth.cpp 2007-12-02 22:43:38.000000000 +0900 *************** *** 65,71 **** * in ISO 10646. */ ! int konsole_wcwidth(Q_UINT16 ucs) { /* sorted list of non-overlapping intervals of non-spacing characters */ static const struct interval combining[] = { --- 65,72 ---- * in ISO 10646. */ ! static int __konsole_wcwidth(Q_UINT16); ! static int __konsole_wcwidth(Q_UINT16 ucs) { /* sorted list of non-overlapping intervals of non-spacing characters */ static const struct interval combining[] = { *************** *** 131,137 **** (ucs >= 0x20000 && ucs <= 0x2ffff) */)); } ! #if 0 /* * The following function is the same as konsole_wcwidth(), except that * spacing characters in the East Asian Ambiguous (A) category as --- 132,138 ---- (ucs >= 0x20000 && ucs <= 0x2ffff) */)); } ! #if 1 /* * The following function is the same as konsole_wcwidth(), except that * spacing characters in the East Asian Ambiguous (A) category as *************** *** 140,146 **** * encodings who want to migrate to UCS. It is not otherwise * recommended for general use. */ ! int konsole_wcwidth_cjk(Q_UINT16 ucs) { /* sorted list of non-overlapping intervals of East Asian Ambiguous * characters */ --- 141,147 ---- * encodings who want to migrate to UCS. It is not otherwise * recommended for general use. */ ! int konsole_wcwidth(Q_UINT16 ucs) { /* sorted list of non-overlapping intervals of East Asian Ambiguous * characters */ *************** *** 184,191 **** { 0x226E, 0x226F }, { 0x2282, 0x2283 }, { 0x2286, 0x2287 }, { 0x2295, 0x2295 }, { 0x2299, 0x2299 }, { 0x22A5, 0x22A5 }, { 0x22BF, 0x22BF }, { 0x2312, 0x2312 }, { 0x2460, 0x24BF }, ! { 0x24D0, 0x24E9 }, { 0x2500, 0x254B }, { 0x2550, 0x2574 }, ! { 0x2580, 0x258F }, { 0x2592, 0x2595 }, { 0x25A0, 0x25A1 }, { 0x25A3, 0x25A9 }, { 0x25B2, 0x25B3 }, { 0x25B6, 0x25B7 }, { 0x25BC, 0x25BD }, { 0x25C0, 0x25C1 }, { 0x25C6, 0x25C8 }, { 0x25CB, 0x25CB }, { 0x25CE, 0x25D1 }, { 0x25E2, 0x25E5 }, --- 185,200 ---- { 0x226E, 0x226F }, { 0x2282, 0x2283 }, { 0x2286, 0x2287 }, { 0x2295, 0x2295 }, { 0x2299, 0x2299 }, { 0x22A5, 0x22A5 }, { 0x22BF, 0x22BF }, { 0x2312, 0x2312 }, { 0x2460, 0x24BF }, ! { 0x24D0, 0x24E9 }, ! #if 0 // Graphic line chars ! { 0x2500, 0x254B }, ! #endif ! { 0x2550, 0x2574 }, ! { 0x2580, 0x258F }, ! #if 0 // Meshed square ! { 0x2592, 0x2595 }, ! #endif ! { 0x25A0, 0x25A1 }, { 0x25A3, 0x25A9 }, { 0x25B2, 0x25B3 }, { 0x25B6, 0x25B7 }, { 0x25BC, 0x25BD }, { 0x25C0, 0x25C1 }, { 0x25C6, 0x25C8 }, { 0x25CB, 0x25CB }, { 0x25CE, 0x25D1 }, { 0x25E2, 0x25E5 }, *************** *** 202,208 **** sizeof(ambiguous) / sizeof(struct interval) - 1)) return 2; ! return konsole_wcwidth(ucs); } #endif --- 211,217 ---- sizeof(ambiguous) / sizeof(struct interval) - 1)) return 2; ! return __konsole_wcwidth(ucs); } #endif konsole-3.5.8-final.diff [^] (26,440 バイト) 2007-12-05 15:49 [表示] [非表示] *** konsole/konsole/TEWidget.cpp.ORG 2007-11-22 09:46:40.000000000 +0900 --- konsole/konsole/TEWidget.cpp 2007-12-05 15:39:36.000000000 +0900 *************** *** 329,334 **** --- 329,337 ---- /* Constructor / Destructor */ /* */ /* ------------------------------------------------------------------------- */ + #define m_isIMForceRedraw m_isIMSel + #define m_imCursorPos m_imPreeditLength + #define m_imSelLen m_imStartLine TEWidget::TEWidget(QWidget *parent, const char *name) :QFrame(parent,name,WNoAutoErase) *************** *** 372,387 **** ,rimX(1) ,rimY(1) ,m_imPreeditText(QString::null) ! ,m_imPreeditLength(0) ! ,m_imStart(0) ! ,m_imStartLine(0) ! ,m_imEnd(0) ,m_imSelStart(0) ,m_imSelEnd(0) ,m_cursorLine(0) ,m_cursorCol(0) ,m_isIMEdit(false) ! ,m_isIMSel(false) ,blend_color(qRgba(0,0,0,0xff)) { // The offsets are not yet calculated. --- 375,390 ---- ,rimX(1) ,rimY(1) ,m_imPreeditText(QString::null) ! ,m_imPreeditLength(0) // NOT USED! rename => m_imCursorPos ! ,m_imStart(-1) ! ,m_imStartLine(0) // NOT USED! rename => m_imSelLen ! ,m_imEnd(-1) ,m_imSelStart(0) ,m_imSelEnd(0) ,m_cursorLine(0) ,m_cursorCol(0) ,m_isIMEdit(false) ! ,m_isIMSel(false) // NOT USED! rename => m_isIMForceRedraw ,blend_color(qRgba(0,0,0,0xff)) { // The offsets are not yet calculated. *************** *** 643,674 **** } else paint.fillRect(rect, bColor); } - - QString tmpStr = str.simplifyWhiteSpace(); - if ( m_isIMEdit && !tmpStr.isEmpty() ) { // imput method edit area background color - QRect tmpRect = rect; - if ( str != m_imPreeditText ) { // ugly hack - tmpRect.setLeft( tmpRect.left() + font_w ); - tmpRect.setWidth( tmpRect.width() + font_w ); - } - - paint.fillRect( tmpRect, Qt::darkCyan ); // currently use hard code color - } - - if ( m_isIMSel && !tmpStr.isEmpty() ) { // imput method selection background color - int x = rect.left() + ( font_w * (m_imSelStart - m_imStart) ); - int y = rect.top(); - int w = font_w * (m_imSelEnd - m_imSelStart); - int h = font_h; - - QRect tmpRect = QRect( x, y, w, h ); - if ( str != m_imPreeditText ) { // ugly hack - tmpRect.setLeft( tmpRect.left() + font_w ); - tmpRect.setWidth( tmpRect.width() + font_w ); - } - - paint.fillRect( tmpRect, Qt::darkGray ); // currently use hard code color - } } // Paint cursor --- 646,651 ---- *************** *** 791,796 **** --- 768,780 ---- // fprintf(stderr, "x/y = %d/%d\txpos/ypos = %d/%d\n", curx, cury, xpos, ypos); m_cursorLine = cury; m_cursorCol = curx; + + // OK, now the event queue is going to be flushed. + if (m_imStart == m_imEnd) + m_imEnd = m_imStart = -1; + else if (m_isIMEdit == true && + m_imStart != m_cursorLine * columns + m_cursorCol) + imComposeEvent(NULL); } /*! *************** *** 798,804 **** The size of the new image may or may not match the size of the widget. */ ! void TEWidget::setImage(const ca* const newimg, int lines, int columns) { if (!image) --- 782,808 ---- The size of the new image may or may not match the size of the widget. */ ! static bool __check_preedit(const int& cols, const int& lins, ! const int& imstart, const int& imend, const int& cx, const int& cy) ! { ! ! if (imstart/cols >= lins) ! return false; ! if (imend <= lins * cols || cy <= lins - 2) ! { ! int abspos = cy * cols + cx; ! return (imstart <= abspos && abspos < imend); ! } ! if (imend >= (lins + 1) * cols) ! return true; ! // ! // Here the current conditions are cy == lins - 1 and ! // lins * cols < imend < (lins + 1) * cols ! // ! int selp = (imstart/cols == lins - 1) ? (imstart % cols) : 0; ! return (cx >= selp || cx < (imend % cols)); ! } ! void TEWidget::setImage(const ca* const newimg, int lines, int columns) { if (!image) *************** *** 834,849 **** // mark surrounding neighbours dirty, in case the character exceeds // its cell boundaries memset(dirtyMask, 0, cols+2); // Two extra so that we don't have to have to care about start and end conditions ! for (x = 0; x < cols; x++) ! { ! if ( ( (m_imPreeditLength > 0) && ( ( m_imStartLine == y ) ! && ( ( m_imStart < m_imEnd ) && ( ( x > m_imStart ) ) && ( x < m_imEnd ) ) ! || ( ( m_imSelStart < m_imSelEnd ) && ( ( x > m_imSelStart ) ) ) ) ) ! || ext[x] != lcl[x]) ! { ! dirtyMask[x] = dirtyMask[x+1] = dirtyMask[x+2] = 1; ! } } dirtyMask++; // Position correctly --- 838,848 ---- // mark surrounding neighbours dirty, in case the character exceeds // its cell boundaries memset(dirtyMask, 0, cols+2); + // Two extra so that we don't have to have to care about start and end conditions ! for (x = 0; x < cols; x++) { ! if (ext[x] != lcl[x]) ! dirtyMask[x] = dirtyMask[x+1] = dirtyMask[x+2] = 1; } dirtyMask++; // Position correctly *************** *** 857,862 **** --- 856,865 ---- if (dirtyMask[x]) { Q_UINT16 c = ext[x+0].c; + if (m_isIMEdit == true && + m_imEnd > m_imStart && __check_preedit(cols, lins, + m_imStart, m_imEnd, x, y) == true) + continue; if ( !c ) continue; int p = 0; *************** *** 873,878 **** --- 876,886 ---- if (!c) continue; // Skip trailing part of multi-col chars. + if (m_isIMEdit == true && + m_imEnd > m_imStart && __check_preedit(cols, lins, + m_imStart, m_imEnd, x + len, y) == true) + break; + if (ext[x+len].f != cf || ext[x+len].b != cb || ext[x+len].r != cr || !dirtyMask[x+len] || isLineChar(c) != lineDraw || (ext[x+len+1].c == 0) != doubleWidth) break; *************** *** 882,904 **** QString unistr(disstrU, p); - // for XIM on the spot input style - m_isIMEdit = m_isIMSel = false; - if ( m_imStartLine == y ) { - if ( ( m_imStart < m_imEnd ) && ( x >= m_imStart-1 ) && ( x + int( unistr.length() ) <= m_imEnd ) ) - m_isIMEdit = true; - - if ( ( m_imSelStart < m_imSelEnd ) && ( x >= m_imStart-1 ) && ( x + int( unistr.length() ) <= m_imEnd ) ) - m_isIMSel = true; - } - else if ( m_imStartLine < y ) { // for word worp - if ( ( m_imStart < m_imEnd ) ) - m_isIMEdit = true; - - if ( ( m_imSelStart < m_imSelEnd ) ) - m_isIMSel = true; - } - bool save_fixed_font = fixed_font; if (lineDraw) fixed_font = false; --- 890,895 ---- *************** *** 981,987 **** between the old and the new image. Instead, the internal image is used and the painting bound by the PaintEvent box. */ - void TEWidget::paintEvent( QPaintEvent* pe ) { const QPixmap* pm = backgroundPixmap(); --- 972,977 ---- *************** *** 1045,1050 **** --- 1035,1046 ---- paint.end(); setUpdatesEnabled(true); + + if (m_isIMEdit == true && /* m_isIMForceRedraw == true &&*/ m_imStart < m_imEnd) + { + m_isIMForceRedraw = true; + imComposeEvent(NULL); + } } void TEWidget::print(QPainter &paint, bool friendly, bool exact) *************** *** 1105,1110 **** --- 1101,1110 ---- { int len = 1; int p = 0; + if (m_isIMEdit == true && + m_imEnd > m_imStart && __check_preedit(columns, lines, + m_imStart, m_imEnd, x, y) == true) + continue; c = image[loc(x,y)].c; if (c) disstrU[p++] = c; //fontMap(c); *************** *** 1120,1125 **** --- 1120,1129 ---- (image[loc(x+len,y)+1].c == 0) == doubleWidth && isLineChar( c = image[loc(x+len,y)].c) == lineDraw) // Assignment! { + if (m_isIMEdit == true && + m_imEnd > m_imStart && __check_preedit(columns, lines, + m_imStart, m_imEnd, x + len, y) == true) + break; if (c) disstrU[p++] = c; //fontMap(c); if (doubleWidth) // assert((image[loc(x+len,y)+1].c == 0)), see above if condition *************** *** 1159,1165 **** void TEWidget::blinkCursorEvent() { cursorBlinking = !cursorBlinking; ! repaint(cursorRect, true); } /* ------------------------------------------------------------------------- */ --- 1163,1170 ---- void TEWidget::blinkCursorEvent() { cursorBlinking = !cursorBlinking; ! if (m_isIMEdit == false) ! repaint(cursorRect, true); } /* ------------------------------------------------------------------------- */ *************** *** 1735,1748 **** void TEWidget::focusInEvent( QFocusEvent * ) { ! repaint(cursorRect, true); // *do* erase area, to get rid of the // hollow cursor rectangle. } void TEWidget::focusOutEvent( QFocusEvent * ) { ! repaint(cursorRect, true); // don't erase area } bool TEWidget::focusNextPrevChild( bool next ) --- 1740,1766 ---- void TEWidget::focusInEvent( QFocusEvent * ) { ! ! m_isIMForceRedraw = true; ! if (m_isIMEdit == false) ! { ! repaint(cursorRect, true); // *do* erase area, to get rid of the // hollow cursor rectangle. + } + else + { + if (m_imStart < m_imEnd) + imComposeEvent(NULL); + } } void TEWidget::focusOutEvent( QFocusEvent * ) { ! ! m_isIMForceRedraw = true; ! if (m_isIMEdit == false) ! repaint(cursorRect, true); // don't erase area } bool TEWidget::focusNextPrevChild( bool next ) *************** *** 1921,1983 **** void TEWidget::imStartEvent( QIMEvent */*e*/ ) { ! m_imStart = m_cursorCol; ! m_imStartLine = m_cursorLine; ! m_imPreeditLength = 0; ! ! m_imEnd = m_imSelStart = m_imSelEnd = 0; ! m_isIMEdit = m_isIMSel = false; } void TEWidget::imComposeEvent( QIMEvent *e ) { - QString text = QString::null; - if ( m_imPreeditLength > 0 ) { - text.fill( '\010', m_imPreeditLength ); - } ! m_imEnd = m_imStart + string_width( e->text() ); ! QString tmpStr = e->text().left( e->cursorPos() ); ! m_imSelStart = m_imStart + string_width( tmpStr ); ! tmpStr = e->text().mid( e->cursorPos(), e->selectionLength() ); ! m_imSelEnd = m_imSelStart + string_width( tmpStr ); ! m_imPreeditLength = e->text().length(); ! m_imPreeditText = e->text(); ! text += e->text(); ! if ( text.length() > 0 ) { ! QKeyEvent ke( QEvent::KeyPress, 0, -1, 0, text ); ! emit keyPressedSignal( &ke ); } - } ! void TEWidget::imEndEvent( QIMEvent *e ) ! { ! QString text = QString::null; ! if ( m_imPreeditLength > 0 ) { ! text.fill( '\010', m_imPreeditLength ); ! } ! m_imEnd = m_imSelStart = m_imSelEnd = 0; ! text += e->text(); ! if ( text.length() > 0 ) { ! QKeyEvent ke( QEvent::KeyPress, 0, -1, 0, text ); ! emit keyPressedSignal( &ke ); } ! QPoint tL = contentsRect().topLeft(); ! int tLx = tL.x(); ! int tLy = tL.y(); ! QRect repaintRect = QRect( bX+tLx, bY+tLy+font_h*m_imStartLine, ! contentsRect().width(), contentsRect().height() ); ! m_imStart = 0; ! m_imPreeditLength = 0; ! m_isIMEdit = m_isIMSel = false; ! repaint( repaintRect, true ); } // Override any Ctrl+<key> accelerator when pressed with the keyboard --- 1939,2343 ---- void TEWidget::imStartEvent( QIMEvent */*e*/ ) { ! //#define IM_EVENT_DEBUG 0 ! #ifdef IM_EVENT_DEBUG ! printf("Start: %d %d %d %d \n", ! m_imStart, m_imEnd, m_imSelStart, m_imSelEnd); ! #endif ! ! // Sometimes SCIM skips to send the XIM_END, buggy enough! ! if (m_imStart < m_imEnd) ! imEndEvent(NULL); ! ! // The m_imStart < 0 means that the event queue ! // is empty, thus we can trust the cursor position. ! // Moreover m_imStart == m_imEnd implies that ! // we have no preedit string currently or commited that already. ! // ! m_imEnd = m_imStart; ! m_imSelStart = m_imSelEnd = 0; ! m_isIMEdit = m_isIMForceRedraw = false; ! m_imCursorPos = 0; ! m_imSelLen = 0; } void TEWidget::imComposeEvent( QIMEvent *e ) { ! if (m_imStart < 0) ! { ! m_imEnd = m_imStart = m_cursorCol + m_cursorLine * columns; ! m_imSelStart = m_imSelEnd = 0; ! #ifdef IM_EVENT_DEBUG ! printf("DelayStart(C): %d %d %d %d \n", ! m_imStart, m_imEnd, m_imSelStart, m_imSelEnd); ! #endif ! } ! ! // Sanity check ! if (image == NULL) ! return; ! ! // In the case of refresh. ! QString NText; ! int CursorPos, SelLen; ! if (e == NULL) ! { ! NText = m_imPreeditText; ! CursorPos = m_imCursorPos; ! SelLen = m_imSelLen; ! } ! else ! { ! // Do not believe the behavior of IM! ! NText = e->text(); ! CursorPos = QMAX(0, QMIN(e->cursorPos(), (int) NText.length())); ! SelLen = QMAX(e->selectionLength(), 0); ! } ! ! // Setup the painter. ! QPainter paint; ! setUpdatesEnabled(false); ! paint.begin( this ); ! QPoint tL = contentsRect().topLeft(); ! int tLx = tL.x(); ! int tLy = tL.y(); ! QRect tmpRect; ! // If the cursor position has been changed, then try to ! // relocate the preedit area. ! if (e == NULL && m_imEnd > m_imStart && ! m_imStart != m_cursorCol + m_cursorLine * columns) ! { ! int cpos, xpos, xlen; ! ! m_isIMEdit = false; // Should be turned off!! ! cpos = m_imStart; ! xpos = (m_imStart%columns); ! xlen = QMIN(columns - xpos, m_imEnd - cpos); ! while (cpos < m_imEnd) ! { ! int y = QMIN(lines - 1, cpos/columns); ! tmpRect = QRect(bX + tLx + font_w * xpos, ! bY + tLy + font_h * y, font_w * xlen, font_h); ! paintContents(paint, tmpRect, backgroundPixmap() != 0); ! cpos += xlen; ! xlen = QMIN(columns, m_imEnd - cpos); ! xpos = 0; ! } ! ! m_isIMEdit = true; ! m_isIMForceRedraw = true; ! m_imStart = m_imEnd = m_cursorCol + m_cursorLine * columns; ! } ! ! // Let us begin to draw the preedit area! ! int oimEnd = m_imEnd; ! m_imEnd = m_imStart; ! m_imSelEnd = m_imSelStart; ! ! ca data[(columns + 2) * sizeof(ca)]; ! ca dft(' ',cacol(CO_DFT,DEFAULT_FORE_COLOR), ! cacol(CO_DFT,DEFAULT_BACK_COLOR),DEFAULT_RENDITION); ! ! int wcwidth = 1, i, x, xpos; ! #define FAST_REDRAW "yes" ! #ifdef FAST_REDRAW ! int minselstart = (CursorPos < (int) NText.length()) ? CursorPos : NText.length(); ! if (m_imCursorPos < (int) m_imPreeditText.length() && minselstart > m_imCursorPos) ! minselstart = m_imCursorPos; ! #endif /* FAST_REDRAW */ ! ! for (i = 0, x = (m_imStart % columns), ! xpos = m_imStart - (m_imStart % columns); ! i < (int) NText.length(); ) ! { ! int p = 0; ! int redraw_p = -1, redraw_x = -1; ! QChar disstrU[columns + 2]; ! ! wcwidth = konsole_wcwidth(NText[i].unicode()); ! for ( ; x < columns && i < (int) NText.length(); i++) ! { ! Q_UINT16 c; ! int tmpwcwidth; ! ! c = NText[i].unicode(); ! tmpwcwidth = konsole_wcwidth(c); ! if (wcwidth != tmpwcwidth) ! break; ! ! // Check a selection start point. ! if (i == CursorPos) ! { ! m_imSelStart = xpos + x; ! m_imSelEnd = m_imSelStart + lines * columns; /* XXX */ ! } ! #ifdef FAST_REDRAW ! if (redraw_x == -1 && ! (m_isIMForceRedraw == true || i >= minselstart || ! (i >= (int) m_imPreeditText.length() || ! m_imPreeditText[i].unicode() != c))) ! { ! redraw_p = p; redraw_x = x; ! } ! #else /* !FAST_REDRAW */ ! if (redraw_x == -1) ! { ! redraw_p = p; redraw_x = x; ! } ! #endif /* !FAST_REDRAW */ ! ! data[x] = dft; ! data[x++].c = c; ! m_imEnd ++; ! if (tmpwcwidth == 2) ! { ! // Check the wrapping. ! if (x >= columns) ! { ! disstrU[p ++] = data[x-1].c = ' '; ! break; ! } ! data[x] = dft; ! data[x++].c = 0; ! m_imEnd ++; ! } ! ! disstrU[p ++] = c; ! ! // Check a selection end point. ! if ((i + 1) == CursorPos + QMAX(1, SelLen)) ! m_imSelEnd = xpos + x; ! } ! ! int y = QMIN(lines - 1, (xpos/columns)); ! ! // Check if the boundary of the preedit area is located at ! // the middle of a wide character in the underlying screen. ! if (i == (int) NText.length() && i > 0) // The last segment. ! { ! const ca* img = &image[y*columns]; ! if (img[x].c == 0 && img[x-1].c != 0 && x < columns && x > 0) ! { ! if (redraw_x < 0) ! { ! redraw_x = x; redraw_p = p; ! } ! data[x] = dft; ! disstrU[p ++] = data[x ++].c = ' '; ! m_imEnd ++; ! } ! } ! // Render the screen. ! if (redraw_x >= 0 && x - redraw_x > 0) ! { ! // The fake cursor ! int fcursorlen = 0; ! if (xpos + redraw_x == m_imStart && p > 0) // The first segment. ! if (konsole_wcwidth(disstrU[0]) == 1) ! fcursorlen = 1; ! ! const ca *attr = &image[y*columns + redraw_x]; ! QColor fColor = attr->f.color(color_table); ! QColor bColor = attr->b.color(color_table); ! ! m_isIMEdit = true; ! ! tmpRect = QRect(bX + tLx + font_w * redraw_x, ! bY + tLy + font_h * y, ! font_w * (x - redraw_x), font_h); ! #define IM_UNDERLINE ! #ifdef IM_UNDERLINE ! if (attr->isTransparent(color_table)) ! erase(tmpRect); ! else ! paint.fillRect(tmpRect, bColor); ! #else /* IM_UNERLINE */ ! paint.fillRect(tmpRect, Qt::darkCyan); ! #endif /* IM_UNDERLINE */ ! ! if (redraw_p >= 0 && p - redraw_p > 0) ! { ! if (m_imSelStart < m_imSelEnd && ! !(xpos + redraw_x > m_imSelEnd || ! xpos + x <= m_imSelStart)) ! { ! int xlen, sels = redraw_x; ! if (xpos + redraw_x <= m_imSelStart && ! m_imSelStart < xpos + x) ! sels = (m_imSelStart % columns); ! xlen = QMIN(x - sels, ! m_imSelEnd - xpos - sels); ! tmpRect = QRect(bX + tLx + font_w * sels, ! bY + tLy + font_h * y, ! font_w * xlen, font_h); ! paint.fillRect(tmpRect, Qt::darkGray); ! } ! ! paint.setPen(fColor); ! QString unistr(&disstrU[redraw_p], p - redraw_p); ! int a = font_a + m_lineSpacing / 2; ! if (wcwidth == 2) ! { ! drawTextFixed(paint, bX + tLx + font_w * redraw_x, ! bY + tLy + font_h * y, unistr, &data[redraw_x]); ! } ! else ! { ! paint.drawText(bX + tLx + font_w * redraw_x, ! bY + tLy + font_h * y + a, ! unistr, -1, ! bidiEnabled ? QPainter::Auto : QPainter::LTR ); ! } ! ! #ifdef IM_UNDERLINE ! if (x - fcursorlen - redraw_x > 0) ! { ! // Draw an underline. ! paint.drawLine(bX + tLx + font_w * (redraw_x + fcursorlen), ! bY + tLy + font_h * y + a + 1, ! bX + tLx + font_w * (x - fcursorlen) - 1, ! bY + tLy + font_h * y + a + 1); ! } ! #endif /* IM_UNDERLINE */ ! ! if (fcursorlen > 0) ! { ! tmpRect = QRect(bX + tLx + font_w * redraw_x, ! bY + tLy + font_h * y /* + a */, ! font_w * fcursorlen, font_h /* - 2 * a */); ! paint.fillRect(tmpRect, fColor); ! paint.setPen(bColor); ! QString tmpstr(&disstrU[0], 1); ! paint.drawText(bX + tLx + font_w * redraw_x, ! bY + tLy + font_h * y + a, tmpstr, -1, ! bidiEnabled ? QPainter::Auto : QPainter::LTR ); ! paint.setPen(fColor); ! } ! } ! } ! if (x == columns) ! { ! x = 0; ! xpos += columns; ! } } ! for ( ; xpos + x < oimEnd; x = 0, xpos += columns) ! { ! int xlen = QMIN(columns - x, oimEnd - x - xpos); ! int y = QMIN(lines - 1, (xpos/columns)); ! tmpRect = QRect(bX + tLx + font_w * x, ! bY + tLy + font_h * y, font_w * xlen, font_h); ! paintContents(paint, tmpRect, backgroundPixmap() != 0); } + + drawFrame(&paint); + paint.end(); + setUpdatesEnabled(true); ! m_imPreeditText = NText; ! m_imCursorPos = CursorPos; ! m_imSelLen = SelLen; ! m_isIMForceRedraw = false; ! ! #ifdef IM_EVENT_DEBUG ! const char *s = (e == NULL) ? "refresh" : "normal"; ! printf("Compose(%s): %d %d %d %d: %d %d %d \n", s, ! m_imStart, m_imEnd, m_imSelStart, m_imSelEnd, ! NText.length(), CursorPos, SelLen); ! #endif ! } ! void TEWidget::imEndEvent( QIMEvent *e ) ! { ! // In the case of SCIM buggy behavior ! QString NText = QString::null; ! if (e != NULL) ! NText = e->text(); ! ! if (m_imStart < 0) ! { ! m_imEnd = m_imStart = m_cursorCol + m_cursorLine * columns; ! m_imSelStart = m_imSelEnd = 0; ! #ifdef IM_EVENT_DEBUG ! printf("DelayStart(E): %d %d %d %d \n", ! m_imStart, m_imEnd, m_imSelStart, m_imSelEnd); ! #endif ! } ! ! // Before call paintContents(), we should turn m_isIMEdit off. ! m_isIMEdit = m_isIMForceRedraw = false; ! m_imCursorPos = 0; ! m_imSelLen = 0; ! ! // Sanity check ! if (image != NULL && m_imStart < m_imEnd) ! { // Clear all preedit strings. ! QPainter paint; ! setUpdatesEnabled(false); ! paint.begin( this ); ! QPoint tL = contentsRect().topLeft(); ! int tLx = tL.x(); ! int tLy = tL.y(); ! int cpos, xpos, xlen; ! ! cpos = m_imStart; ! xpos = (m_imStart%columns); ! xlen = QMIN(columns - xpos, m_imEnd - cpos); ! while (cpos < m_imEnd) ! { ! int y = QMIN(lines - 1, cpos/columns); ! QRect tmpRect = QRect(bX + tLx + font_w * xpos, ! bY + tLy + font_h * y, font_w * xlen, font_h); ! paintContents(paint, tmpRect, backgroundPixmap() != 0); ! cpos += xlen; ! xlen = QMIN(columns, m_imEnd - cpos); ! xpos = 0; ! } ! drawFrame(&paint); ! paint.end(); ! setUpdatesEnabled(true); ! } ! ! // Calculte the true cursor position for the next im_start ! // in case of the non empty event queue ! int i, xpos, xlen; ! for (i = 0, xpos = m_imStart; i < (int) NText.length(); i ++) ! { ! int xres = columns - (xpos % columns); ! xlen = konsole_wcwidth(NText[i].unicode()); ! if (xres < xlen) ! xpos += xres; ! xpos += xlen; ! } ! ! // All informations are cleared here. ! m_imStart = xpos; ! m_imEnd = m_imStart; ! m_imSelStart = m_imSelEnd = 0; ! m_imPreeditText = QString::null; ! ! // Emit key events. ! if (NText.length() > 0 ) { ! QKeyEvent ke(QEvent::KeyPress, 0, -1, 0, NText); ! emit keyPressedSignal( &ke ); ! } ! ! #ifdef IM_EVENT_DEBUG ! if (e == NULL) ! printf("End(Buggy): %d %d %d %d\n", ! m_imStart, m_imEnd, m_imSelStart, m_imSelEnd); ! else ! printf("End: %d %d %d %d: %d %d %d \n", ! m_imStart, m_imEnd, m_imSelStart, m_imSelEnd, ! e->text().length(), e->cursorPos(), e->selectionLength()); ! #endif } // Override any Ctrl+<key> accelerator when pressed with the keyboard *** konsole/konsole/konsole_wcwidth.cpp.ORG 2007-11-22 09:47:00.000000000 +0900 --- konsole/konsole/konsole_wcwidth.cpp 2007-12-02 22:43:38.000000000 +0900 *************** *** 65,71 **** * in ISO 10646. */ ! int konsole_wcwidth(Q_UINT16 ucs) { /* sorted list of non-overlapping intervals of non-spacing characters */ static const struct interval combining[] = { --- 65,72 ---- * in ISO 10646. */ ! static int __konsole_wcwidth(Q_UINT16); ! static int __konsole_wcwidth(Q_UINT16 ucs) { /* sorted list of non-overlapping intervals of non-spacing characters */ static const struct interval combining[] = { *************** *** 131,137 **** (ucs >= 0x20000 && ucs <= 0x2ffff) */)); } ! #if 0 /* * The following function is the same as konsole_wcwidth(), except that * spacing characters in the East Asian Ambiguous (A) category as --- 132,138 ---- (ucs >= 0x20000 && ucs <= 0x2ffff) */)); } ! #if 1 /* * The following function is the same as konsole_wcwidth(), except that * spacing characters in the East Asian Ambiguous (A) category as *************** *** 140,146 **** * encodings who want to migrate to UCS. It is not otherwise * recommended for general use. */ ! int konsole_wcwidth_cjk(Q_UINT16 ucs) { /* sorted list of non-overlapping intervals of East Asian Ambiguous * characters */ --- 141,147 ---- * encodings who want to migrate to UCS. It is not otherwise * recommended for general use. */ ! int konsole_wcwidth(Q_UINT16 ucs) { /* sorted list of non-overlapping intervals of East Asian Ambiguous * characters */ *************** *** 184,191 **** { 0x226E, 0x226F }, { 0x2282, 0x2283 }, { 0x2286, 0x2287 }, { 0x2295, 0x2295 }, { 0x2299, 0x2299 }, { 0x22A5, 0x22A5 }, { 0x22BF, 0x22BF }, { 0x2312, 0x2312 }, { 0x2460, 0x24BF }, ! { 0x24D0, 0x24E9 }, { 0x2500, 0x254B }, { 0x2550, 0x2574 }, ! { 0x2580, 0x258F }, { 0x2592, 0x2595 }, { 0x25A0, 0x25A1 }, { 0x25A3, 0x25A9 }, { 0x25B2, 0x25B3 }, { 0x25B6, 0x25B7 }, { 0x25BC, 0x25BD }, { 0x25C0, 0x25C1 }, { 0x25C6, 0x25C8 }, { 0x25CB, 0x25CB }, { 0x25CE, 0x25D1 }, { 0x25E2, 0x25E5 }, --- 185,200 ---- { 0x226E, 0x226F }, { 0x2282, 0x2283 }, { 0x2286, 0x2287 }, { 0x2295, 0x2295 }, { 0x2299, 0x2299 }, { 0x22A5, 0x22A5 }, { 0x22BF, 0x22BF }, { 0x2312, 0x2312 }, { 0x2460, 0x24BF }, ! { 0x24D0, 0x24E9 }, ! #if 0 // Graphic line chars ! { 0x2500, 0x254B }, ! #endif ! { 0x2550, 0x2574 }, ! { 0x2580, 0x258F }, ! #if 0 // Meshed square ! { 0x2592, 0x2595 }, ! #endif ! { 0x25A0, 0x25A1 }, { 0x25A3, 0x25A9 }, { 0x25B2, 0x25B3 }, { 0x25B6, 0x25B7 }, { 0x25BC, 0x25BD }, { 0x25C0, 0x25C1 }, { 0x25C6, 0x25C8 }, { 0x25CB, 0x25CB }, { 0x25CE, 0x25D1 }, { 0x25E2, 0x25E5 }, *************** *** 202,208 **** sizeof(ambiguous) / sizeof(struct interval) - 1)) return 2; ! return konsole_wcwidth(ucs); } #endif --- 211,217 ---- sizeof(ambiguous) / sizeof(struct interval) - 1)) return 2; ! return __konsole_wcwidth(ucs); } #endif | ||||||||
コメント | |
(0002712) anonymous (参照) 2007-11-22 01:53 |
> > 解決策: > kdelibsのkonsole/konsoleに以下の添付patchを適用すると kdebaseの誤りです。 |
(0002713) anonymous (参照) 2007-11-22 09:43 |
このバグの投稿者です。より良いパッチを添付します。 |
(0002714) anonymous (参照) 2007-11-22 09:43 |
このバグの投稿者です。より良いパッチを添付します。 |
(0002715) anonymous (参照) 2007-11-23 04:13 |
PatchですがAsian ambiguous charactersのうち罫線は半角にした方が 良いようです(もちろんどちらが正解という事はないのですが。本来は 選択できるべきですが、DEC graphic character setがunicodeにmapされ ているKonsoleの構造上簡単ではないので。) この部分を修正したpatchを添付します。ついでですが、複数行にまたがる 変換も正しく反転強調されるようにしておきました。 |
(0002716) anonymous (参照) 2007-11-28 02:08 |
何度も投稿して申し訳ありません。 Patchですが、オリジナルの実装はあまりにad hocで その方針を改善するより、やはり真面目に実装した方 が良いと思えて来ました。 オリジナルでは、preedit stringsをすべて端末clientに 渡しています。これは実装は楽ですが非常に問題が多いのです。 #この様な実装の例はgvimなどですが、gvimとconsoleでは話が #大きく異ります(Konsoleのclientの挙動が仮定出来無いから)。 例えば cat として何か日本語を変換してみると、この方法では 駄目な事があからさまに判ります。 やはり、preedit stringsはcommitされるまで自前で処理するのが 結局のところ様々な問題を回避するために必要です。以下に添付 するpatchはこの部分を実装したものです。 動作確認は vje, wnn7, uim, scim, skkinput で確認してありますの。 既知の問題としては、 1) Preedit stringsを残したまま、tabを切り換えると preedit stringsの挙動は保証されない (確定してから切り替えましょう) 2) 連続確定入力(XIM_END -> XIM_START->XIM_CHANGEDが一挙に来る)で preedit stringsの表示位置がずれる事がある。 これは、確定させると期待どおりになりますから無視しましょう。 3)Focus in/out で cursorの処理をしていない。無視してください。 もちろん、これらの問題はオリジナルにも存在しますし、オリジナル よりは遥かに良くなっているはずです。Header filesを変更しないで 出来る変更はこの辺りで限界です。 |
(0002717) anonymous (参照) 2007-11-30 17:20 |
レスポンスがないのに投稿を続けるのも何ですが。。 Patchを投稿した以上、最後まで責任があるので。 上記の既知の問題をfixしたpatchを添付します。 あと、オリジナルでは変換エリアがシアン系の バックグラウンドになりますが、これは目が疲れるので 標準的な下線を引くものに変更しておきました。 Konsoleはkateやkdevelopでも使われるので結構 幸せになる人もいるのではないかと思うのですが。。 |
(0002718) anonymous (参照) 2007-12-04 17:45 |
送っていただいたパッチを含むkdebaseパッケージをplus/4.0にputしました。 必要ならQTのデフォルトをOverTheSpot→OnTheSpotに戻したqtパッケージもputします。 |
(0002719) anonymous (参照) 2007-12-05 15:17 |
> 送っていただいたパッチを含むkdebaseパッケージをplus/4.0にputしました。 対応ありがとうございます。ええと、もし許すならば1か所ほど変更した 次のpatchにして頂けないでしょうか? 修正内容は unicode 0x2592を半角扱いにする。 unicode 0x2592は通常の日本語font fileで何もないところです。 konsoleはDEC graphic characterの網線squareを0x2592にmapしています (これは明らかにkonsoleがだめだと思いますが、仕様なのでしかたありません) この変更をしないと、alsamixerのbarやcursesのscrollbarが全角扱いになり 表示が乱れます。これはkonsoleがだめだめなのですが、現実にあわせたいと 思います。 ええと、DEC graphic charactersのうち、通常使われるものには対策を 施したのでこの種の変更はこれ以上ないと思います。ただ、半角diamondは もともとそのようなフォントがallocate出来ないので全角diamondになります。 > 必要ならQTのデフォルトをOverTheSpot→OnTheSpotに戻したqtパッケージもputし > ます。 これはvine projectのメンバーの方の判断によると思うのです。 たぶん、ほとんど全てのKDE appsはOnTheSpotの方が現状では幸せになります。 しかし、LyXはOnTheSpotでは入力出来ません。しかもLyXは--qt-inputstyle optionを受け付けないのです。 ここは判断の迷うところではないでしょうか? .... あと、ここに付け足すべきなのかわかりませんが。。 今回のpatch作成でずいぶん様々な日本語入力interfaceのeventのやりとりを 観察したのですが、Vine 付属のversionのscimはかなり問題があるのではない でしょうか?次の4.2では新しいscimが採用されるようですが、次の点は 確認しておいた方が良いと思います。 1) scim(xim)はXIM_ENDのあと何をしなくともすぐにXIM_STARTを必ず送って来る。 これはトラブルの元です。 2) Input focusをはずしてまたinput focusを得るとXIM_ENDなしにまたXIM_START を送ってくることがある。これは論外です。 3) 変換中にcursor keyを動かしても文字単位の移動が出来ない。具体的には cursorposが常に同じ値で返ってくる。これでは途中の挿入削除が出来ません。 私は日本語変換のfront endに思い入れは全くないのですが、vine付属の現状では (市販品を除くとvje,wnn等)uimが一番真っ当なやりとりをしているように思えます。 |
(0002720) anonymous (参照) 2007-12-05 15:49 |
すいません。前に添付したpatchは 妙なところが削れていました。 |
(0002721) anonymous (参照) 2007-12-12 13:58 |
いただいたpatch(と別のセキュリティpatch)をあてたパッケージをplusにputしました。 |
(0002722) anonymous (参照) 2007-12-13 12:31 |
> いただいたpatch(と別のセキュリティpatch)をあてたパッケージをplusにputし > ました。 ありがとうございます。 これでこの報告もcloseとして下さい。 PS: もしKDEのversion up等でpatchがあたらなく なったら一報下さい。対応致します。 |
(0002723) kazutaka (開発者) 2007-12-13 18:41 |
対応ありがとうございました。 完了とします。 ハラダ |
課題の履歴 | |||
変更日 | ユーザー名 | 項目 | 変更内容 |
2007-11-22 01:37 | anonymous | 添付ファイル追加: kdebase-3.5.8.diff | |
2007-11-22 01:37 | anonymous | 新規課題 | |
2007-11-22 01:53 | anonymous | コメント追加: 0002712 | |
2007-11-22 09:43 | anonymous | コメント追加: 0002713 | |
2007-11-22 09:43 | anonymous | 添付ファイル追加: konsole-3.5.8-1122.diff | |
2007-11-22 09:43 | anonymous | コメント追加: 0002714 | |
2007-11-23 04:13 | anonymous | 添付ファイル追加: konsole-3.5.8-1123.diff | |
2007-11-23 04:13 | anonymous | コメント追加: 0002715 | |
2007-11-28 02:08 | anonymous | 添付ファイル追加: konsole-3.5.8-1127.diff | |
2007-11-28 02:08 | anonymous | コメント追加: 0002716 | |
2007-11-30 17:20 | anonymous | 添付ファイル追加: konsole-3.5.8-1130.diff | |
2007-11-30 17:20 | anonymous | コメント追加: 0002717 | |
2007-12-04 17:45 | anonymous | コメント追加: 0002718 | |
2007-12-05 15:17 | anonymous | 添付ファイル追加: konsole-3.5.8-final.diff | |
2007-12-05 15:17 | anonymous | コメント追加: 0002719 | |
2007-12-05 15:49 | anonymous | 添付ファイル追加: konsole-3.5.8-final.diff | |
2007-12-05 15:49 | anonymous | コメント追加: 0002720 | |
2007-12-12 13:58 | anonymous | コメント追加: 0002721 | |
2007-12-13 12:31 | anonymous | コメント追加: 0002722 | |
2007-12-13 18:41 | kazutaka | 担当者 | => packager |
2007-12-13 18:41 | kazutaka | 状態 | 新規 => 完了 |
2007-12-13 18:41 | kazutaka | コメント追加: 0002723 |
Copyright © 2000 - 2024 MantisBT Team Copyright © 2012 - 2024 Project Vine |