#前提
今、Linux 上で Qt と C++ の勉強を開始したばかりです。Cの経験はありますが、Xアプリの経験はほとんどありません。
ディストリのKDEがQt4のようなので、Qt4で使っています。
(「grep libqt /proc//maps 2>/dev/null | grep qt4」は表示されたけれど、「grep libqt /proc//maps 2>/dev/null | grep qt5」は表示されませんでした。)
Qt5はまだ未経験です。
なお、Qiita初投稿なので、不備があったらスミマセン。
#困ったこと
次のようなアプリを作成中。
1.表示させるのはTreeView だけを持ったウィンドウ
2.タスクバーに登録しない
3.TreeViewにフォーカスをあてて起動する
4.フォーカス・アウトを検知する
1.は色々ありましたが問題なくできました。2.3.4.もそれぞれ単体なら何とかできました。
しかし、2.3.4.を同時に満たす方法が分かりませんでした。
2.を実現するために、setWindowFlags()で、「Qt::Popup」を指定した場合、他にフォーカスを移せないようで、4.が実現できません。
では、と「Qt::Tool」や「Qt::ToolTip」を指定すると、TreeViewにフォーカスが当たらない状態で起動してしまいます。ダメ元でsetFocusPolicy(Qt::StrongFocus)をしてみても、変わらず。
闇雲にほかも試してみました。「Qt::Desktop」を指定した時はびっくりしました。
Xアプリの基本が分かっていないのですが、詰んでいました。
#自分なりの解決策
仕方がないので、2.をQtではなく、X11の機能で実現する方法を調べて、ようやく解決です。
次のような関数を登録して使えば良いようです。
bool hoge_class::skipTaskbar(void){
QX11Info xinfo = x11Info();
Display *display = xinfo.display(); // デフォルトディスプレイ
Atom win_type = XInternAtom(display, "_NET_WM_STATE", false);
Atom value = XInternAtom(display, "_NET_WM_STATE_SKIP_TASKBAR", false);
Status status =
XChangeProperty( display,winId(),
win_type,
XA_ATOM, 32, PropModeReplace,
(unsigned char *) &value,1);
return true;
}
エラー処理は省略しています。
show()の直前に呼び出すようにしてみた所、setWindowFlags()で「Qt::CustomizeWindowHint | Qt::Widget」を指定しても、タスクバーに登録されず、TreeViewにフォーカスが当たった状態で起動され、フォーカスアウトも検知できました。
単純にタスクバーに登録させないAPIがQtに用意されていれば何の問題も無かったと思うのですが、なんとか解決しました(実はあるのかも知れません...)。
winId()関数を見つけられずに、appRootWindow()がそれだと思い込み、結果はまった事は内緒です。