星期五, 12月 26, 2014

Escaping from alternative charset (weird characters in tmux)

When I'm playing mud, sometimes my terminal run into a queer mode that leaves the characters all messed up:
After some research I found that it's because the terminal went into the 'Alternative charset' mode, that translate some characters to symbols (See the last section of man 5 termcap). As for the reason why it went into this mode, it's because that I accidentally echoed '^N' into the terminal. To escape, you can simply echo '^O' to restore the state. most common way:

$ cat
^O
^D
or you can use echo, if your shell supports entering special characters
$ echo ^V^O
If you want to reproduce this, just change the ^O above to ^N then you'll find yourself in the AC mode again.

Some in-depth explanation and other more complicated cases are described here:
http://www.in-ulm.de/~mascheck/various/alternate_charset/

星期四, 8月 07, 2014

Lock on suspend & Systemd

Ever since I switched to systemd, I found that the acpi-support LOCK_SCREEN(in /etc/default/acpi-support) setting doesn't work anymore. While acpi_listen still shows that the lid closing event is detected, my screenlock program(i3lock) wasn't getting executed whatsoever.

With a little bit of tracing I found that the lid event and relevant scripts are indeed executed but after invoking the 'CheckPolicy' function in the /etc/acpi/lid.sh the script halted. This is because the script checks the system to see if there are other program being in charge of power management and if there is acpi gets aborted.

So, to enforce screen locking after resume (or before sleep), we'll need to setup a service in systemd that gets executed at the appropriate time. After a bit of searching and playing with the options, I found this ready-to-use unit file by Karsten Gebbert:
https://github.com/krgn/systemd/blob/master/i3lock@.service

to use this, download the .service file to /etc/systemd/system and enable the service with the following command:
(sudo) systemctl enable i3lock@[user].service
Where [user] should be replaced by the username whose password would be used to unlock.

To check if the service is enabled correctly you can either just try to suspend and see if the i3lock is fired up or check the list of currently enabled services:
 systemctl list-unit-files | grep i3lock
if you have successfully enabled it, there should be message like this:
i3lock@.service                            enabled

Note on the file name:
With an @ in the file name means this file is a template and can be enabled with specified instance name if provided. In this case the instance name will be [user] and it will replace the %i variable in the file.

星期五, 5月 17, 2013

installing Paragon NTFS & HFS driver

Recently, I bought a portable HD, which came NTFS-formatted. At first I considered formatting it to XFS or ext4 but it occurred to me that I might have to mount it with windows from time to time (although I don't have many windows PCs and will not have more than one unless necessary.)

Rather than trying to fix/install anything on the stupid Windows to support xfs/ext4, I prefer messing up with my linux which, in some way, is more intuitive for me than dealing with those mysterious bugs in windows.

There's a ntfs driver called ntfs-3g. It is fine, but somehow too slow. I don't know why it has been staying on FUSE all these years, or if staying on FUSE is the reason that makes it so slow. There's a couple of commercial alternatives that come into play: Tuxera(which I suspect is the reason that ntfs-3g being so slow) and Paragon but only the later one offers a free driver for linux, so I gave it a try and it works pretty well so far.

Here's how I do it:

星期二, 3月 19, 2013

cross-compile node.js (0.10.0) for mipsel (Asus RT-N16 with tomatousb)

最近入手了一台 RT-N16, 馬上是刷了 tomatousb, 還算蠻滿意的, 看了那精美的記憶體, 開完機還剩下 100+ MB, 家裡的裝置也很少使用 p2p, 這些記憶體不用好像有點浪費,於是便想把一些本來跑在桌電的 node server 來跑在 rt-n16 上。
記錄一下 cross-compile 的步驟:
先從 tomatousb 抓他們的 toolchain:

$ git clone git://repo.or.cz/tomato.git tomato
$ cd tomato
$ git checkout tomatousb-K26-1.28.9054 
$ sudo ln -s tools/brcm /opt/brcm
這邊用的是 linux 2.6 的版本, 其他版本可以參考 git tag。
然後再抓 node.js 的 source: 我這邊用的是最新的 node-v0.10.0
$ mkdir $HOME/node-src && cd $HOME/node-src
$ wget http://nodejs.org/dist/v0.10.0/node-v0.10.0.tar.gz
$ tar xf node-v0.10.0.tar.gz
$ cd node-v0.10.0
設定的部分,因為是 cross-compiling, 所以把 snapshot 關掉, 因為 compile 出來的 mksnapshot 也沒辦法在 host 上跑:

$ ./configure --prefix=/opt --dest-cpu=mipsel --dest-os=linux --without-snapshot
編譯過程中會有些錯,主要是 linux 版本的問題跟 pthread 有些函數(pthread_barrier_init|destroy|wait)在 uclibc 不支援,所以我做了個 patch, 這會讓有用到 ub_barrier_init|destroy|wait 的 module 無把編譯但 node 本身似乎是沒有用到這些函數,所以暫時可以這樣做:
$ wget -O - http://moon.cse.yzu.edu.tw/~s961449/node-mipsel.patch | patch -p0
$ PREFIX=/opt/brcm/K26/hndtools-mipsel-uclibc-4.2.4/bin/mipsel-linux-
$ export CC=${PREFIX}gcc
$ export CXX=${PREFIX}g++
$ export AR=${PREFIX}ar
$ export RANLIB=${PREFIX}ranlib
$ export LINK=$CXX
$ make -j4 #4 cores
基本上這樣就可以編出能在 tomato 上跑的 node 了, 編完以後 binary 會在 out/Release/node,但是不知道為什麼 tomato 的 firmware 並沒有把一些必要的 library 包進去,所以還要再附上 librt, libstdc++ 才行(optware 用來編譯的 toolchain 不同,所以也無法使用他們的 librt), 並設定 LD_LIBRARY_PATH 才能跑: node.sh:
#!/bin/sh
LD_LIBRARY_PATH="/lib:/usr/lib:/opt/node/lib" /opt/node/bin/node $@
把檔案傳到 ap 上, 我這邊是用 optware 裝了 sftp, 所以直接用 sftp 上傳:
sftp root@your.ap.address
$ cd /opt
$ mkdir node
$ mkdir node/bin
$ mkdir node/lib
$ put out/Release/node node/bin/
$ put node.sh bin/node
$ put /opt/brcm/K26/hndtools-mipsel-uclibc-4.2.4/lib/librt.so node/lib
$ put /opt/brcm/K26/hndtools-mipsel-uclibc-4.2.4/lib/libstdc++.so node/lib/libstdc++.so.6
或是你要打包好在上傳也可以, 各人喜好啦,(因為當初是先上傳了才發現缺 lib)。 這樣應該就可以在 tomato 上跑 node 了! 但是馬上會用掉 30+% 的記憶體,也許可以再 tune 一下,但可以跑已經大喜大賀了, haha.

星期三, 2月 13, 2013

ibus override xmodmap, use xkb options instead

之前寫過一篇關於把 caps lock 重新 map 到 control 的方法,但昨天更新了 ibus 以後突然發現我的 xmodmap 只要切換輸入法引擎的時候就會被覆寫過去,google 了一下,大家似乎是推薦用 xkb 的設定選項來作調整:

Debian 來講的話,就是修改 /etc/default/keyboard
把 XKBOPTIONS 這行加入 ctrl:nocaps (有其他選項的話以逗號分隔)
XKBOPTIONS="ctrl:nocaps"
重新開 X 以後就可以囉!似乎是比 xmodmap 乾淨一些,但缺點就是這樣改到的是整個系統的設定,如果使用者要改就沒辦法了。 若沒有 root 的權限可以改 /etc/default/keyboard, 也可以在 ~/.xsession 加上:
setxkbmap -option "ctrl:nocaps" &
其他的選項可以參考 man xkeyboard-config, /etc/default/keyboard 相關的資訊: man keyboard

星期六, 2月 09, 2013

pathogen, manage your vim plugins in a clean way

vim 用久了, 裝很多 plugin 很正常, 但有時候只是想試看看某些 plugin 用完要移除的時候卻發現很麻煩, 要自己把檔案刪掉。好加在 vim 發展到現在也有許多人做了套件的工具/套件: pathogenVimana 算是我比較常聽到的管理套件。但 Vimana 需要透過 perl,如果在 windows 下要使用還頗不方便的(雖然我很久沒用windows寫程式了..)。 Pathogen 的運作方式是透過增加 runtime path 的方式,把 plugin 獨自存放在各自,vim 開啟的時候會搜尋所有的 runtime path,把這些設定都讀進來,所以要刪除時只要把該套件的資料夾刪除就可以了。 安裝的方式也很簡單,pathogen 本身就是一個 vim plugin:
$mkdir -p ~/.vim/autoload ~/.vim/bundle; \
$curl -Sso ~/.vim/autoload/pathogen.vim \
    https://raw.github.com/tpope/vim-pathogen/master/autoload/pathogen.vim
基本上就是把 pathogen.vim 下載下來放到 ~/.vim/autoload/,再把套件預設存放的資料夾 ~/.vim/bundle 建立起來。 最後再將
execute pathogen#infect()
加入 vimrc 就可以了,這邊就完成 pathogen 的安裝。 裝好 pathogen 以後,開 vim 時他就會去 ~/.vim/bundle 把下面的資料夾路徑都加入 runtime path,所以安裝套件時只需要在底下開一個資料夾東西丟進去就可以正常使用了,比如說安裝 ctrlp.vim 可以直接 git clone 到 ~/.vim/bundle 下即可:
$ cd ~/.vim/bundle && git clone git://github.com/kien/ctrlp.vim.git
個人還蠻喜歡這個方式的,很乾淨。

星期四, 1月 17, 2013

xfs repair in root fs

用 xfs 好一陣子了,都沒有發生過什麼問題,但今天在做系統 update 的時候居然發現有硬碟有資料毀損的情況,而且還是 root fs... 頓時背脊都涼了一半,才發現 xfs 居然都沒有自己 repair(但說實在其實那些會自己修復的 fsck 有時候也蠻恐怖的)。

xfs 在開機 fsck 的時候並不會做任何動作,所以有問題的話要自己用 xfs_check 及 xfs_repair 做檢查及修復。

但 xfs_check 時需要 fs 在 read-only 的狀況下,xfs_repair 需要 fs 不被 mount 的狀況下才能動作,但這次是 root filesystem... umount 了就不能執行 xfs_repair 了阿!
首先想到的是用 ubcd 或其他 livecd 來做但有點麻煩,翻了一下 man 看到 xfs_repair 的 -d 選項:
Repair dangerously. Allow xfs_repair to repair an XFS filesystem mounted read only. This is typically done on a root fileystem from single user mode, immediately followed by a reboot.
有多 dangerous 我是不知道,但 google 了一下好像也沒發現過有什麼災情,反正 /home 還在,大部分的 config 都在這裡了,大不了重灌嘛!
於是就豁達的重開機到 recovery mode:(/dev/sda1 是我的 root device)
$ mount -oremount,ro /
$ xfs_check /dev/sda1
$ xfs_repair -n /dev/sda1 #測試, 看到好長的一串要修復蠻抖的...
$ xfs_repair /dev/sda1 #但指令還是拍了下去
然後重開機就正常了(汗...(至少看起來沒什麼問題,雖然 /lost+found 有 93 個檔案,但大部分好像都是每刪除乾淨的而已)

星期三, 1月 16, 2013

vim command/search history

用 vim 用了快十年了吧,對於這個一直會不小心跳出來的功能總是覺得有點煩。今天終於是受不了了,查了一下發現是 command/search history 的功能,觸發的方式是 q: 及 q/, 前者跟 :q 太接近了難怪常常莫名其妙的跑出來。本來是要找到把這個功能關掉的方法但突然覺得好像還有點用處,於是乎就研究了一下。

他作用的法式就跟很多 plugin 一樣,會開啓一個 split window 來瀏覽過去的記錄,這個 window 裡面可以搜尋,找到要重複的 cmd/search 按下 enter 就可以了。

比較有趣的地方是,vim 的 cmdline mode 提供的移動指令實在不是很符合 vim 的精神,但用 cmdline window 就可以做到這件事:假如我在打一串很長很複雜的指令,打到一半發現中間有錯,這時候可以按 C-f 打開 cmdline window,剛剛輸入的指令會在最下面,這邊就可以用 vim 的其他移動方法來做修改,修改完再按 enter 就會送出了,同時,在這個 window 裡也可以用 <tab> 來 auto-complete command (多選的話會有 menu)。

更多詳情可以參考 :help cmdline-history

星期二, 12月 25, 2012

npm 在自訂路徑安裝全域套件

有時候系統想裝 coffee-script 但因爲不是自己的機器沒有 root,這時候可以把 npm 的安裝路徑自訂成想要的地方,再把他加到 PATH 就可以了:
npm config set prefix=$HOME/npm
echo export PATH=\$PATH:$HOME/npm/bin >> .bashrc

星期六, 12月 08, 2012

rimeime 注音查拼音

最近想來學拼音,主要是因爲我覺得手機上的注音輸入法都只是堪用而已,然後又剛好看到有所謂的 google pinyin,掛了 google 的名字就讓我很想試試看。http://code.google.com/p/rimeime/ 先是找了 google pinyin,雖然是從 android 上移植過來的但不太好用的感覺。後來就找到了 RIMEIME,基於 ibus 上但又好像是獨立的一個框架。 由於真的不太收悉拼音,希望有個反查的功能,rimeime 剛好有這個功能所以我就選了它。 rimeime 預設拼音的反查是用倉頡但我也不會,要改成注音的話,我的方法是複製一份拼音,把 reverse_lookup 的部分改成
reverse_lookup:
  dictionary: terra_pinyin
  prism: bopomofo
  enable_completion: true
  prefix: "`" 
  tips: 〔注音〕
  preedit_format:
    - 'xlit|1qaz2wsxedcrfv5tgbyhnujm8ik,9ol.0p;/-6347|ㄅㄆㄇㄈㄉㄊㄋㄌㄍㄎㄏㄐㄑㄒㄓㄔㄕㄖㄗㄘㄙㄧㄨㄩㄚㄛㄜㄝㄞ
  comment_format:
    - xform/([nl])v/$1ü/
然後 recognizer 的地方改成
recognizer:
  import_preset: default
  patterns:
    reverse_lookup: "`[a-z0-9,./;\\-]*$"
在 default.xml 裡加入自訂的方案再重新載入以後用 ` 就會是注音反查的功能囉! (這篇用拼音打了快一個小時吧...加油!)

星期四, 11月 29, 2012

awesome wm 陽春 clipboard manager

雖然說我使用滑鼠的時間真的是很少,但偶爾還是不免要從網頁上複製一些文字下來,但 X 的複製機制有時候有點令人抓狂,如果我要把一個 Textbox 的字取代掉,我不能把裡面的文字選起來按刪除,因為這樣我的 Primary buffer 裡就會被蓋掉,用 shift-ins 貼上的東西只會是我剛剛選起來刪掉的文字而已,這樣一來變成要先刪除,回到我要複製的地方重選然後再來貼上。
網路上是有不少的 clipboard manager 但是我覺得為了這個不太常用但是需要的時候才打開又太遲的功能應該是要整合到 wm 裡,所以我就寫了一個簡單的 clipboard manager,其實沒什麼 manager 的功能,只是提供三個功能:把現在的 primary buffer 存到檔案裡,選擇之前存起來的內容貼回 primary buffer 裡,跟清除暫存起來的 buffer。

code 在 github 可以下載,用法大致如下:
把 clipboard.lua 放置在 rc.lua 同個目錄,然後在 rc.lua 的開頭引入
require("clipboard")
然後在全域快捷鍵設定的地方加入下面的 code
    -- clipboard
    -- {{{
    awful.key({ modkey },            "c",     copy_to_clipboard),
    awful.key({ modkey, "Shift"   }, "c",     clear_clipboard),
    awful.key({ modkey },            "v",     clipboard_menu),
    -- }}}

我是設定 modkey(win) + c, 把 primary buffer(選取的文字)寫入 ~/.sel
modkey + shift + c 把 ~/.sel 清空
modkey + v 則會跳出一個選單把暫存的 buffer 都列出來,選擇以後就會覆蓋掉目前的 primary buffer,再按 shift + ins 即可貼上。

目前的作法蠻陽春的,換行的部份我用 #NL 取代掉才寫入,可想而知早晚會出事(?!),而且面對不是文字的 buffer 也還有待測試,不過對我來說算是夠用了啦,我會複製的東西也就是純文字的 code 而已 XDD,當然如果有意願想要改進它,也歡迎送 pull request 過來。

星期六, 11月 17, 2012

ctrlp.vim 專案開發時開檔案的好幫手

最近看到一些人開始用 Sublime Text2,所以去官網看了一下介紹,個人是沒有使用過但是那個 fuzzy search 的功能讓我蠻喜歡的。 剛好,上個禮拜在 Vim-Taiwan 中看到有人分享 ctrlp.vim 這個 plugin,雖然大部分的時候我很清楚什麼檔案放在什麼地方,但是有時候要輸入一堆路徑,即使大部分都可以 tab 補完,還是覺得有點煩人,決定來試看看這個 plugin。 這個 plugin 主要的目的就是找檔案,裝好以後按 ctrl+p 會叫出搜尋的 window,比如說我想找到的檔案路徑是
/assets/js/user.iced
那我只要輸入類似這種的路徑: as/j/u.id 就可以找到需要的檔案(當然要看有沒有其他檔案有類似的組成) 找到以後有幾種開啟方法:

  • enter: 可以在目前 window 中打開(如果已存在其他 tab 中會跳過去)
  • C-t: 會開新的 tab
  • C-v: 把目前的 window 做垂直切割開啟
其他一些指令可以參考 :help ctrlp-mappings 剛裝完 ctrlp 的時候可能會覺得他啟動有點慢,在 OSX/Linux 底下的話可以設定用 git ls-files 或 find 來做檔案列表的建立,速度會有明顯的改善,在 ~/.vimrc 裡面加入
  let g:ctrlp_user_command = {
    \ 'types': {
      \ 1: ['.git', 'cd %s && git ls-files -c -o --exclude-standard'],
      \ 2: ['.hg', 'hg --cwd %s locate -I .'],
      \ },
    \ 'fallback': 'find %s -type f'
    \ }
*2014 09/11 Update: 加入 --exclude-standard 這是從 :help ctrlp_user_command 複製下來的範例把 git ls-files 改成 git ls-files -c -o,這樣才能一併搜尋到還沒被 cache 的檔案。
----
另外有一個 plugin 叫做 unite.vim,似乎也不錯,自訂性更高,除了該有的檔案, MRU, Buffer 搜尋,使用者還可以自訂搜尋的來源,如何篩選,以及如何打開。換句話說,你可以搜任何存在/不存在的東西,讓我想到也許可以做出類似 Dash 的東西(一開始看到 dash 是想說可能要做成一種輸入法應該蠻酷的)

Node.js mysql connection pool

Node.js 中,我常用的 mysql module 大概是 node-mysql 了吧,但是因為想要盡量避免太多連線的建立,以前會在 module 中戶傳連線的物件,但又發現會有 timeout 的問題,這部分 node-mysql 的處理方式並不是很好需要重建連線,但是重建連線以後除非又要再把連線的物件傳到每個 module 不然無法使用。 另一方面,node-mysql 本身的 query 是 serial 的,人一多的時候若整個 application 只存在一個連線其實是不夠的,但以我以前的做法,多個連線會變成非常複雜。 於是我翻到了 node-mysql 首頁的最下面 TODO:

  • Prepared statements
  • setTimeout() for Connection / Query
  • connection pooling
  • ...
想一想,做一個共用的 connection pool 的話應該就能免去一些不必要的連線建立,同時也能在不同 module 中共用連線,又能達到多個 query 同時處理(用多個 connection 達到)的效果。以下是我透過 generic-pool 做出來的 mysql_pool.iced
mysql = require('mysql')
config = require __dirname + '/../config'

poolFactory = require 'generic-pool'
module.exports = poolFactory.Pool {
        name: 'mysql'
        create: (callback)->
                conn = mysql.createConnection {
                        host : 'localhost',
                        user :config.dbuser,
                        password : config.dbpass,
                }
                conn.query 'use ' + config.dbname
                callback(null, conn)
                return
        destroy: (conn)->
                conn.end()
                return
        max: 10
        idleTimeoutMillis: 30000
}
然後將這個 module 放到 node_modules 底下(方便各個 module require),因為 node.js 載入 module 的特性,同個位置的 module (基本上)會被 cache 起來,所以所有用到 pool 的地方都會從同一個 connection pool 來取得/試放連線,達到共用連線的目的。 這邊我建完 connection 先下了 use 的 query 再回傳,理論上應該要等 query 返回再回傳,但因為前面講過 node-mysql 是 serial 的所以沒關係(但以後可能會需要改就是了)..

星期六, 11月 03, 2012

LinearLayout & weight

個人在 Android 中最常用的就是 LinearLayout 了,可能是因為以前寫 gtk 的關係吧,對這個方式覺得比較直覺。

LinearLayout 中,有時後會用到 weight 來讓版面達到滿版的效果。但是有時候 child view 的 weight 越大,暫的空間越大,有時候又是相反。為了釐清只好找了 LinearLayout 的 Source 來研究:(widget/LinearLayout.java)
1147 // Either expand children with weight to take up available space or                                        
1148 // shrink them if they extend beyond our current bounds
1149 int delta = widthSize - mTotalLength;
1150 if (delta != 0 && totalWeight > 0.0f) {
1151     float weightSum = mWeightSum > 0.0f ? mWeightSum : totalWeight;
...
...
1169 float childExtra = lp.weight;
1170 if (childExtra > 0) {
1171     // Child said it could absorb extra space -- give him his share
1172     int share = (int) (childExtra * delta / weightSum);
1173     weightSum -= childExtra;
1174     delta -= share;
上面這兩段基本上就是原因,當所有 child view 算出來的高度/寬度小於自己的高/寬的時候,delta 是正的,會依照 weight 的比例分給這些 child view 讓 weight > 0 的 child view 來吸收多出來的空間。反之,若寬度超過預算,也是由這些 child view 縮小吸收,所以會才會有兩種不同的狀況。

星期一, 4月 30, 2012

ContentObserver, 觀察 ContentProvider 的更新

當我們需要對 ContentProvider 的內容更新做出即時的反應,可以用 ContentObserver 來達到監控的效果。

用起來還蠻簡單的,實做一個 ContentObserver 以後,用 ContentResolver 來註冊一個 observer。
private class MyObserver extends ContentObserver {
 public MyObserver(Handler handler)
 {
  super(handler);
 }

 /**
  * {@inheritDoc}
  * @see ContentObserver#onChange(boolean)
  */
 public void onChange(boolean selfChange)
 {
  Log.d("MyObserver", String.format("onChange: %s", selfChange?"1":"0"));
 }
}
ContentResolver cr = getContentResolver();
cr.registerContentObserver(Events.CONTENT_URI, false,
 new MyObserver(new Handler()));

Observer 中除了 constructor,我們只要 override onChange 就可以了。當目標內容有改變並通知時,onChange 就會被呼叫。

有個問題是,我不知道為什麼我實際上在使用的時候,每次資料有變更 onChange 都會被呼叫兩次。目前因為資料的變動週期不短,所以我對每個 onChange 都做出反應不會有什麼問題,但是如果遇到資料更新頻率很高的應用時,也許可以配合 PendingIntent (FLAG_UPDATE_CURRENT, FLAG_NO_CREATE) 來做延後的合併處理。

return values of Android Service onStartCommand

實做 Service 時,最重要的應該就是 onStartCommand 的實作了吧,當其他 context 呼叫 startService 時,這個函數都會被呼叫。
onStartCommand 的回傳值可以有 4 種,分別是 START_NOT_STICKYSTART_REDELIVER_INTENTSTART_STICKY 跟 START_STICKY_COMPATIBILITY

若回傳 START_NOT_STICKY,表示這個服務不需要一直存留,當 Service 因其他程序需要記憶體砍掉以後,除非有另一次的 startService 呼叫,不然系統不會幫你重新執行 Service。

回傳 START_REDELIVER_INTENT 時,若 Service 被砍掉以後,系統會嘗試使用當初呼叫 startService 的 intent 來重新啟動這個 Service。

START_STICKY 跟 START_REDELIVER_INTENT 類似,但並不會保留上次用來開啟服務的 intent,也就是說如果 service 被系統砍掉後重開,被砍掉到重新啟動中間如果沒有 startService 來傳遞新的 intent,送進來的 intent 就有可能為 null,所以如果在 onStartCommand 裡面需要讀取 intent 裡的 bundle 一定要先確認 intent 是否為 null。

最後一個 START_STICKY_COMPATIBILITY,跟 START_STICKY 一樣,但根據官方的文件,使用這個 return code 時當 service 被砍掉後系統不一定會再呼叫一次 onStartCommand。也就是說如果是 sticky 的話系統一定會再 reschedule 一個 onStartCommand 嗎.?

Refs:
http://developer.android.com/reference/android/app/Service.html

星期五, 4月 27, 2012

query content provider with LIMIT

在 query ContentProvider 的時候要用 limit 的話,直接加在 sortOrder 後面就可以了。

Cursor c = cr.query(
 Uri.parse(uri),
 INS_PROJECTION,
 Instances.CALENDAR_ID + "=" + cal_id,
 null,
 "limit 1"
)

星期一, 4月 16, 2012

SimpleCursorAdapter & _id

基本上 Android 裡面的 Adapter 的工作就是一個將 "Item" (包括 data, meta-data) 包裝成 item view 的類別.
ListView 在 render 的時候會向 Adapter 要一個一個 view 用來表示每個資料.
SimpleCursorAdapter 是把 Cursor 包裝起來, 用來產生 listview 需要顯示的一個個項目。值得一提的是,Cursor 代表的資料需要一個 "_id" 的欄位, 用來當作 onListItemClick 的識別碼,也就是第三個參數。
所以在做查詢的時候都要 Projection 記得選 _ID,不然會噴 IllegalArgumentException。

Ref:

星期日, 6月 12, 2011

jumper

今天答應要幫媽媽的朋友在喪禮上放 ppt,有好幾份會需要跳來跳去,電腦又只有一個輸出沒辦法用雙螢幕來切,只好手動切但 Alt + Tab 只有兩個視窗的時候還好,超過三個以後有時候還是需要按幾次,在大螢幕上效果不佳,於是就寫了這個小程式...

基本上就是列出一些看得到的視窗然後讓使用者指定 1-9 的位置 (輸入 q 結束選取),設好以後直接用 Win + 1~9 就可以把視窗拉到前面來,ALT + CTRL + Q 關閉程式, ALT + CTRL + R 可以重新設定。今天自己試用的效果不賴,丟出來讓大家看一看,有興趣的可以拿去改的更好,只是我昨天也稍微 google 了一下居然沒找到類似的軟體,難道大家都這麼喜歡浪費時間一個一個  Alt+tab 找嗎 @@"

程式 & source : http://moon.cse.yzu.edu.tw/~s961449/jumper.zip

星期五, 4月 15, 2011

~/.xsession 突然不被執行了..

最近更新了以後發現 ~/.xsession 在開機不會被執行 (因為很少重開所以現在才發現....), 看了一下 /etc/X11/Xsession.d/50x11-common_determine-startup  裡面的判斷, 才發現現在如果 ~/.xsession, ~/.Xsession 不能被執行就會被跳過, 採用系統預設的 startup command. 所以只要將他設定為 executable 就行囉!

chmod +x ~/.xsession