2013-05-09 2 views
5

얼마 전에 C에서 Windows API 함수 EnumWindows, SetWindowPos 및 SetForegroundWindow를 사용하여 내가 일반적으로 원하는 특정 레이아웃에 제목 (제목)으로 창을 정렬했습니다.SetWindowPos와 동일한 Linux가 있습니까?

이 기능에 해당하는 Linux가 있습니까? Kubuntu를 사용하게 될 것이므로 KDE 특정 및/또는 우분투 특정 솔루션이 좋습니다.

+0

KDE와 함께 wiling을 사용하고 싶을 수도 있습니다. http://awesome.naquadah.org/wiki/KDE_and_awesome 또는 http://blog.frozen-zone.org/2010/01/kde4-with-xmonad/ –

답변

2

예, X Windows 프로토콜을 사용하여이 작업을 수행 할 수 있습니다. 매우 낮은 수준의 프로토콜이므로 약간의 작업이 필요합니다. xcb_query_tree을 사용하여 작동 할 창을 찾은 다음 xcb_configure_window으로 옮길 수 있습니다. This page에는 수행 방법에 대한 세부 정보가 나와 있습니다. 이러한 기능을 사용하는 라이브러리를 사용하는 데는 basic tutorial이 있지만 더 나은 기능을 제공하기 위해 Google에 도움을 드리고자합니다.

너무 힘들지는 모르지만 그렇게 나쁘지는 않습니다. 여기서 오른쪽으로 10px 모든 xterms을 이동합니다 50 라인 C 프로그램입니다 :

#include <stdio.h> 
#include <string.h> 
#include <xcb/xcb.h> 

void handle(xcb_connection_t* connection, xcb_window_t window) { 

    xcb_query_tree_reply_t *tree = xcb_query_tree_reply(connection, 
     xcb_query_tree(connection, window), NULL); 
    xcb_window_t *children = xcb_query_tree_children(tree); 

    for (int i = 0; i < xcb_query_tree_children_length(tree); i++) { 

     xcb_get_property_reply_t *class_reply = xcb_get_property_reply(
      connection, 
      xcb_get_property(connection, 0, children[i], XCB_ATOM_WM_CLASS, 
       XCB_ATOM_STRING, 0, 512), NULL); 
     char* class = (char*)xcb_get_property_value(class_reply); 
     class[xcb_get_property_value_length(class_reply)] = '\0'; 

     if (!strcmp(class, "xterm")) { 
      /* Get geometry relative to parent window */ 
      xcb_get_geometry_reply_t* geom = xcb_get_geometry_reply(
       connection, 
       xcb_get_geometry(connection, window), 
       NULL); 

      /* Move 10 pixels right */ 
      uint32_t values[] = {geom->x + 10}; 
      xcb_configure_window(connection, children[i], 
       XCB_CONFIG_WINDOW_X, values); 
     } 

     /* Recurse down window tree */ 
     handle(connection, children[i]); 
    } 
} 

int main() { 
    xcb_connection_t *connection; 
    const xcb_setup_t *setup; 

    connection = xcb_connect(NULL, NULL); 
    setup = xcb_get_setup(connection); 
    xcb_screen_iterator_t screen = xcb_setup_roots_iterator(setup); 
    handle(connection, screen.data->root); 

    return 0; 
} 

이 오류 검사 또는 메모리 관리 없습니다, 그리고 무엇을 할 수있는 것은 매우 제한적이다. 그러나 원하는 작업을 수행하는 프로그램으로 업데이트하거나 작업 할 창과 수행 할 작업을 지정하는 명령 줄 옵션을 추가하여 범용 목적의 도우미 프로그램으로 바꾸는 것이 간단해야합니다.

+5

@rubenvb \t 당신이 더 좋은 대답을 가지고 있다면 꼭 게시하고 나는 대답을 upvote 하고이 하나를 삭제합니다. 하지만 당신이 더 나은 대답을했다면 당신이 모욕에 의지 할 것이라고 생각하지 않습니다. – andrewdotn

+1

+1 현대 XCB 예제를 제공하기 위해 레거시 코드가 Xlib을 계속 사용하는 것이 중요하지만 새로운 코드는 실제로 최신 방법을 사용해야합니다. 또는 더 나은 아직 X없이 완전히 가고,하지만 그것은 OP에 대해 구체적으로 X에 대한 의미가되지 않을 것입니다. – TechZilla

+0

나는 모든 오래된 코드 때문에 새로운 프로그래머가 처음에는 xlib에서 물건을 다 끝내고 TechZilla에 동의합니다. 그들은 요즘 모든 스레딩 때문에 xcb로 전환해야한다는 것을 깨닫습니다. 나는 xlib로 설명 할 수없는 행동을하기 때문에 xcb로 모든 작업을 재실행하고있다. 이 예제를 주셔서 감사합니다. – Noitidart

2

@andrewdotn이 좋은 답을 가지고 있지만 XQueryTree를 사용하여 디스플레이의 루트 창에서 트리의 시작을 걷고 XFetchName 다음 XMoveWindow으로 움직이는 창 이름을 가져 오는으로 매우 간단뿐만 아니라이 오래된 학교를 할 수 있습니다. 다음은 모든 창을 나열하고 'xeyes'라고 불리는 항목이 있으면 왼쪽 상단으로 이동하는 예제입니다. 대부분의 X 프로그램과 마찬가지로 더 많은 기능이 있으므로 _NET_WM_NAME 확장 윈도우 관리자 속성을 가져 오려면 XGetWindowProperty를 호출해야하지만 예제는 초보자로 작동합니다. gcc -Wall -g -o demo demo.c -lX11

#include <X11/Xlib.h> 
#include <stdio.h> 
#include <string.h> 

static int 
EnumWindows(Display *display, Window window, int depth) 
{ 
    Window parent, *children; 
    unsigned int count = 0; 
    int r = 1, n = 0; 
    char *name = NULL; 

    XFetchName(display, window, &name); 
    for (n = 0; n < depth; ++n) putchar(' '); 
    printf("%08x %s\n", (int)window, name?name:"(null)"); 
    if (name && strcmp("xeyes", name) == 0) { 
     XMoveWindow(display, window, 5, 5); 
    } 
    if (name) XFree(name); 

    if (XQueryTree(display, window, &window, &parent, &children, &count) == 0) { 
     fprintf(stderr, "error: XQueryTree error\n"); 
     return 0; 
    } 
    for (n = 0; r && n < count; ++n) { 
     r = EnumWindows(display, children[n], depth+1); 
    } 
    XFree(children); 
    return r; 
} 

int 
main(int argc, char *const argv[]) 
{ 
    Display *display = NULL; 

    if ((display = XOpenDisplay(NULL)) == NULL) { 
     fprintf(stderr, "error: cannot connect to X server\n"); 
     return 1; 
    } 

    EnumWindows(display, DefaultRootWindow(display), 0); 
    XCloseDisplay(display); 
    return 0; 
} 
5

으로이 중 창 관리자 자체 (당신이 확장을 지원하는 경우) 또는 "호출기"를 지원하기위한 프로토콜과 힌트입니다 (호출기 = 비 윈도우 매니저를 할 수있는 가장 좋은 방법을 컴파일 창 구성 또는 탐색 기능을 수행하는 프로세스).

EWMH 사양에는 호출기에서 사용하도록 설계된 _NET_MOVERESIZE_WINDOW가 포함되어 있습니다. http://standards.freedesktop.org/wm-spec/wm-spec-1.3.html#id2731465

Raw Xlib 또는 Xcb는 꽤 거칠지 만, 당신이 말하는 종류의 작업을 수행하도록 특별히 고안된 라이브러리 인 libwnck가 있습니다. (저는 오래 전 원래의 라이브러리를 썼지 만, 다른 사람들이 영원히 유지해 왔습니다.) 사용하지 않더라도, 코드를 읽고 어떻게하는지보십시오. KDE에는 확실하지 않은 KDE 스타일의 API와 동등한 기능을 제공 할 수 있습니다.

필요한 것들이 모두 EWMH에 있기 때문에 KDE 나 GNOME 또는 배포판을 사용할 필요가 없습니다. 즉,이 기능을 확장으로 사용하는 특정 창 관리자는 별도의 응용 프로그램을 작성하는 것보다 쉽습니다.

올드 스쿨 X 콜을 직접 사용하면 확실히 작동 할 수 있지만 모든 버그와 코너 사례를 철저히 제거하려면 상당한 전문 지식이 필요합니다. 제 생각에는 WM 확장 API 또는 호출기 라이브러리 내 충고가 될 것입니다.

0

코드에서 솔루션이 아닌 데스크탑 환경 에서처럼 이러한 데스크톱 환경에서 창 배치를 처리하는 창 관리자 중 하나를 살펴볼 필요가 있습니다.

  1. KDE의 KWin's Window Attributes

  2. 컴 피즈 (GNOME)는 CompizConfig 설정 관리자 응용 프로그램에서 "창 규칙"과 "장소 윈도우"를 가지고있다. 예 : here

  3. Openbox는 this page의 하단에있는 GUI 도구에 연결 되긴하지만 제대로 작동하는 것이 훨씬 어려워 보입니다.

X를 직접 사용하면 문제는 데스크톱 환경 (패널, 바로 가기 등)에 대해 X 자체가 아무 것도 모르기 때문에 수동으로 보정해야한다는 것입니다.

Google 검색 결과를 얻은 후 KDE가이 작업을 수행하는 유일한 방법 인 것은 놀랍습니다.

관련 문제