/[rdesktop]/sourceforge.net/branches/seamlessrdp-branch/rdesktop/xwin.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /sourceforge.net/branches/seamlessrdp-branch/rdesktop/xwin.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1118 by astrand, Tue Mar 14 13:56:50 2006 UTC revision 1157 by astrand, Fri Mar 17 12:39:09 2006 UTC
# Line 54  typedef struct _seamless_window Line 54  typedef struct _seamless_window
54  {  {
55          Window wnd;          Window wnd;
56          unsigned long id;          unsigned long id;
57            unsigned long parent;
58            unsigned long behind;
59          int xoffset, yoffset;          int xoffset, yoffset;
60          int width, height;          int width, height;
61          unsigned int state;     /* normal/minimized/maximized */          int state;              /* normal/minimized/maximized. */
62            unsigned int desktop;
63            struct timeval *position_timer;
64          struct _seamless_window *next;          struct _seamless_window *next;
65  } seamless_window;  } seamless_window;
66  static seamless_window *g_seamless_windows = NULL;  static seamless_window *g_seamless_windows = NULL;
67    static unsigned long g_seamless_focused = 0;
68    static BOOL g_seamless_started = False; /* Server end is up and running */
69    static BOOL g_seamless_active = False;  /* We are currently in seamless mode */
70  extern BOOL g_seamless_rdp;  extern BOOL g_seamless_rdp;
71    
72  extern uint32 g_embed_wnd;  extern uint32 g_embed_wnd;
# Line 85  static Cursor g_current_cursor; Line 92  static Cursor g_current_cursor;
92  static HCURSOR g_null_cursor = NULL;  static HCURSOR g_null_cursor = NULL;
93  static Atom g_protocol_atom, g_kill_atom;  static Atom g_protocol_atom, g_kill_atom;
94  extern Atom g_net_wm_state_atom;  extern Atom g_net_wm_state_atom;
95    extern Atom g_net_wm_desktop_atom;
96  static BOOL g_focused;  static BOOL g_focused;
97  static BOOL g_mouse_in_wnd;  static BOOL g_mouse_in_wnd;
98  /* Indicates that:  /* Indicates that:
# Line 300  seamless_remove_window(seamless_window * Line 308  seamless_remove_window(seamless_window *
308  }  }
309    
310    
311    /* Move all windows except wnd to new desktop */
312    static void
313    seamless_all_to_desktop(Window wnd, unsigned int desktop)
314    {
315            seamless_window *sw;
316            for (sw = g_seamless_windows; sw; sw = sw->next)
317            {
318                    if (sw->wnd == wnd)
319                            continue;
320                    if (sw->desktop != desktop)
321                    {
322                            ewmh_move_to_desktop(sw->wnd, desktop);
323                            sw->desktop = desktop;
324                    }
325            }
326    }
327    
328    
329    /* Send our position */
330    static void
331    seamless_update_position(seamless_window * sw)
332    {
333            XWindowAttributes wa;
334            int x, y;
335            Window child_return;
336    
337            XGetWindowAttributes(g_display, sw->wnd, &wa);
338            XTranslateCoordinates(g_display, sw->wnd, wa.root,
339                                  -wa.border_width, -wa.border_width, &x, &y, &child_return);
340    
341            seamless_send_position(sw->id, x, y, wa.width, wa.height, 0);
342            sw->xoffset = x;
343            sw->yoffset = y;
344            sw->width = wa.width;
345            sw->height = wa.height;
346    }
347    
348    
349    /* Check if it's time to send our position */
350    static void
351    seamless_check_timers()
352    {
353            seamless_window *sw;
354            struct timeval now;
355    
356            gettimeofday(&now, NULL);
357            for (sw = g_seamless_windows; sw; sw = sw->next)
358            {
359                    if (timerisset(sw->position_timer) && timercmp(sw->position_timer, &now, <))
360                    {
361                            timerclear(sw->position_timer);
362                            seamless_update_position(sw);
363                    }
364            }
365    }
366    
367    
368    static void
369    seamless_restack_window(seamless_window * sw, unsigned long behind)
370    {
371            seamless_window *sw_above;
372    
373            /* Remove window from stack */
374            for (sw_above = g_seamless_windows; sw_above; sw_above = sw_above->next)
375            {
376                    if (sw_above->behind == sw->id)
377                            break;
378            }
379    
380            if (sw_above)
381                    sw_above->behind = sw->behind;
382    
383            /* And then add it at the new position */
384    
385            for (sw_above = g_seamless_windows; sw_above; sw_above = sw_above->next)
386            {
387                    if (sw_above->behind == behind)
388                            break;
389            }
390    
391            if (sw_above)
392                    sw_above->behind = sw->id;
393    
394            sw->behind = behind;
395    }
396    
397    
398  static void  static void
399  mwm_hide_decorations(Window wnd)  mwm_hide_decorations(Window wnd)
400  {  {
# Line 1544  ui_create_window(void) Line 1639  ui_create_window(void)
1639          }          }
1640    
1641          XSelectInput(g_display, g_wnd, input_mask);          XSelectInput(g_display, g_wnd, input_mask);
1642          if (!g_seamless_rdp)  
1643            XMapWindow(g_display, g_wnd);
1644            /* wait for VisibilityNotify */
1645            do
1646          {          {
1647                  XMapWindow(g_display, g_wnd);                  XMaskEvent(g_display, VisibilityChangeMask, &xevent);
                 /* wait for VisibilityNotify */  
                 do  
                 {  
                         XMaskEvent(g_display, VisibilityChangeMask, &xevent);  
                 }  
                 while (xevent.type != VisibilityNotify);  
                 g_Unobscured = xevent.xvisibility.state == VisibilityUnobscured;  
1648          }          }
1649            while (xevent.type != VisibilityNotify);
1650            g_Unobscured = xevent.xvisibility.state == VisibilityUnobscured;
1651    
1652          g_focused = False;          g_focused = False;
1653          g_mouse_in_wnd = False;          g_mouse_in_wnd = False;
# Line 1618  xwin_toggle_fullscreen(void) Line 1711  xwin_toggle_fullscreen(void)
1711  {  {
1712          Pixmap contents = 0;          Pixmap contents = 0;
1713    
1714          if (g_seamless_rdp)          if (g_seamless_active)
1715                  /* Turn off SeamlessRDP mode */                  /* Turn off SeamlessRDP mode */
1716                  ui_seamless_toggle();                  ui_seamless_toggle();
1717    
# Line 1723  handle_button_event(XEvent xevent, BOOL Line 1816  handle_button_event(XEvent xevent, BOOL
1816          }          }
1817  }  }
1818    
1819    static void
1820    ui_seamless_handle_restack(seamless_window * sw)
1821    {
1822            Status status;
1823            Window root, parent, *children;
1824            unsigned int nchildren, i;
1825            seamless_window *sw_below;
1826    
1827            status = XQueryTree(g_display, RootWindowOfScreen(g_screen),
1828                                &root, &parent, &children, &nchildren);
1829            if (!status || !nchildren)
1830                    return;
1831    
1832            sw_below = NULL;
1833    
1834            i = 0;
1835            while (children[i] != sw->wnd)
1836            {
1837                    i++;
1838                    if (i >= nchildren)
1839                            return;
1840            }
1841    
1842            for (i++; i < nchildren; i++)
1843            {
1844                    sw_below = seamless_get_window_by_wnd(children[i]);
1845                    if (sw_below)
1846                            break;
1847            }
1848    
1849            if (!sw_below && !sw->behind)
1850                    return;
1851            if (sw_below && (sw_below->id == sw->behind))
1852                    return;
1853    
1854            if (sw_below)
1855            {
1856                    seamless_send_zchange(sw->id, sw_below->id, 0);
1857                    seamless_restack_window(sw, sw_below->id);
1858            }
1859            else
1860            {
1861                    seamless_send_zchange(sw->id, 0, 0);
1862                    seamless_restack_window(sw, 0);
1863            }
1864    }
1865    
1866  /* Process events in Xlib queue  /* Process events in Xlib queue
1867     Returns 0 after user quit, 1 otherwise */     Returns 0 after user quit, 1 otherwise */
1868  static int  static int
# Line 1855  xwin_process_events(void) Line 1995  xwin_process_events(void)
1995                                  if (g_grab_keyboard && g_mouse_in_wnd)                                  if (g_grab_keyboard && g_mouse_in_wnd)
1996                                          XGrabKeyboard(g_display, g_wnd, True,                                          XGrabKeyboard(g_display, g_wnd, True,
1997                                                        GrabModeAsync, GrabModeAsync, CurrentTime);                                                        GrabModeAsync, GrabModeAsync, CurrentTime);
1998    
1999                                    sw = seamless_get_window_by_wnd(xevent.xfocus.window);
2000                                    if (!sw)
2001                                            break;
2002    
2003                                    if (sw->id != g_seamless_focused)
2004                                    {
2005                                            seamless_send_focus(sw->id, 0);
2006                                            g_seamless_focused = sw->id;
2007                                    }
2008                                  break;                                  break;
2009    
2010                          case FocusOut:                          case FocusOut:
# Line 1957  xwin_process_events(void) Line 2107  xwin_process_events(void)
2107                                          sw->state = ewmh_get_window_state(sw->wnd);                                          sw->state = ewmh_get_window_state(sw->wnd);
2108                                          seamless_send_state(sw->id, sw->state, 0);                                          seamless_send_state(sw->id, sw->state, 0);
2109                                  }                                  }
2110    
2111                                    if ((xevent.xproperty.atom == g_net_wm_desktop_atom)
2112                                        && (xevent.xproperty.state == PropertyNewValue))
2113                                    {
2114                                            sw->desktop = ewmh_get_window_desktop(sw->wnd);
2115                                            seamless_all_to_desktop(sw->wnd, sw->desktop);
2116                                    }
2117    
2118                                  break;                                  break;
2119                          case MapNotify:                          case MapNotify:
2120                                  if (!g_seamless_rdp)                                  if (!g_seamless_active)
2121                                          rdp_send_client_window_status(1);                                          rdp_send_client_window_status(1);
2122                                  break;                                  break;
2123                          case UnmapNotify:                          case UnmapNotify:
2124                                  if (!g_seamless_rdp)                                  if (!g_seamless_active)
2125                                          rdp_send_client_window_status(0);                                          rdp_send_client_window_status(0);
2126                                  break;                                  break;
2127                            case ConfigureNotify:
2128                                    if (!g_seamless_active)
2129                                            break;
2130    
2131                                    sw = seamless_get_window_by_wnd(xevent.xconfigure.window);
2132                                    if (!sw)
2133                                    {
2134                                            error("ConfigureNotify for unknown window 0x%lx\n",
2135                                                  xevent.xconfigure.window);
2136                                    }
2137    
2138                                    gettimeofday(sw->position_timer, NULL);
2139                                    if (sw->position_timer->tv_usec + SEAMLESSRDP_POSITION_TIMER >=
2140                                        1000000)
2141                                    {
2142                                            sw->position_timer->tv_usec +=
2143                                                    SEAMLESSRDP_POSITION_TIMER - 1000000;
2144                                            sw->position_timer->tv_sec += 1;
2145                                    }
2146                                    else
2147                                    {
2148                                            sw->position_timer->tv_usec += SEAMLESSRDP_POSITION_TIMER;
2149                                    }
2150    
2151                                    ui_seamless_handle_restack(sw);
2152                                    break;
2153                  }                  }
2154          }          }
2155          /* Keep going */          /* Keep going */
# Line 1989  ui_select(int rdp_socket) Line 2173  ui_select(int rdp_socket)
2173                          /* User quit */                          /* User quit */
2174                          return 0;                          return 0;
2175    
2176                    if (g_seamless_active)
2177                            seamless_check_timers();
2178    
2179                  FD_ZERO(&rfds);                  FD_ZERO(&rfds);
2180                  FD_ZERO(&wfds);                  FD_ZERO(&wfds);
2181                  FD_SET(rdp_socket, &rfds);                  FD_SET(rdp_socket, &rfds);
# Line 2008  ui_select(int rdp_socket) Line 2195  ui_select(int rdp_socket)
2195    
2196                  /* add redirection handles */                  /* add redirection handles */
2197                  rdpdr_add_fds(&n, &rfds, &wfds, &tv, &s_timeout);                  rdpdr_add_fds(&n, &rfds, &wfds, &tv, &s_timeout);
2198                    seamless_select_timeout(&tv);
2199    
2200                  n++;                  n++;
2201    
# Line 2977  ui_end_update(void) Line 3165  ui_end_update(void)
3165  }  }
3166    
3167  void  void
3168    ui_seamless_begin()
3169    {
3170            if (!g_seamless_rdp)
3171                    return;
3172    
3173            if (g_seamless_started)
3174                    return;
3175    
3176            g_seamless_started = True;
3177    
3178            ui_seamless_toggle();
3179    }
3180    
3181    void
3182  ui_seamless_toggle()  ui_seamless_toggle()
3183  {  {
3184          if (g_seamless_rdp)          if (!g_seamless_rdp)
3185                    return;
3186    
3187            if (!g_seamless_started)
3188                    return;
3189    
3190            if (g_seamless_active)
3191          {          {
3192                  /* Deactivate */                  /* Deactivate */
3193                  while (g_seamless_windows)                  while (g_seamless_windows)
# Line 2992  ui_seamless_toggle() Line 3200  ui_seamless_toggle()
3200          else          else
3201          {          {
3202                  /* Activate */                  /* Activate */
                 if (g_win_button_size)  
                 {  
                         error("SeamlessRDP mode cannot be activated when using single application mode\n");  
                         return;  
                 }  
                 if (!g_using_full_workarea)  
                 {  
                         error("SeamlessRDP mode requires a session that covers the whole screen");  
                         return;  
                 }  
   
3203                  XUnmapWindow(g_display, g_wnd);                  XUnmapWindow(g_display, g_wnd);
3204                  seamless_send_sync();                  seamless_send_sync();
3205          }          }
3206    
3207          g_seamless_rdp = !g_seamless_rdp;          g_seamless_active = !g_seamless_active;
3208  }  }
3209    
3210  void  void
# Line 3016  ui_seamless_create_window(unsigned long Line 3213  ui_seamless_create_window(unsigned long
3213          Window wnd;          Window wnd;
3214          XSetWindowAttributes attribs;          XSetWindowAttributes attribs;
3215          XClassHint *classhints;          XClassHint *classhints;
3216            XSizeHints *sizehints;
3217          long input_mask;          long input_mask;
3218          seamless_window *sw, *sw_parent;          seamless_window *sw, *sw_parent;
3219    
3220          get_window_attribs(&attribs);          if (!g_seamless_active)
3221                    return;
3222    
3223            /* Ignore CREATEs for existing windows */
3224            sw = seamless_get_window_by_id(id);
3225            if (sw)
3226                    return;
3227    
3228            get_window_attribs(&attribs);
3229          attribs.override_redirect = False;          attribs.override_redirect = False;
3230    
3231          /* FIXME: Do not assume that -1, -1 is outside screen Consider          wnd = XCreateWindow(g_display, RootWindowOfScreen(g_screen), -1, -1, 1, 1, 0, g_depth,
            wait with showing the window until STATE and others have  
            been recieved. */  
         wnd = XCreateWindow(g_display, RootWindowOfScreen(g_screen), -1, -1, 1, 1, 0, 0,  
3232                              InputOutput, g_visual,                              InputOutput, g_visual,
3233                              CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap |                              CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap |
3234                              CWBorderPixel, &attribs);                              CWBorderPixel, &attribs);
3235    
3236          XStoreName(g_display, wnd, "rdesktop-seamless");          XStoreName(g_display, wnd, "SeamlessRDP");
3237            ewmh_set_wm_name(wnd, "SeamlessRDP");
3238    
3239          mwm_hide_decorations(wnd);          mwm_hide_decorations(wnd);
3240    
3241          classhints = XAllocClassHint();          classhints = XAllocClassHint();
3242          if (classhints != NULL)          if (classhints != NULL)
3243          {          {
3244                  classhints->res_name = classhints->res_class = "rdesktop";                  classhints->res_name = "rdesktop";
3245                    classhints->res_class = "SeamlessRDP";
3246                  XSetClassHint(g_display, wnd, classhints);                  XSetClassHint(g_display, wnd, classhints);
3247                  XFree(classhints);                  XFree(classhints);
3248          }          }
3249    
3250            /* WM_NORMAL_HINTS */
3251            sizehints = XAllocSizeHints();
3252            if (sizehints != NULL)
3253            {
3254                    sizehints->flags = USPosition;
3255                    XSetWMNormalHints(g_display, wnd, sizehints);
3256                    XFree(sizehints);
3257            }
3258    
3259          /* Set WM_TRANSIENT_FOR, if necessary */          /* Set WM_TRANSIENT_FOR, if necessary */
3260          if (parent)          if ((parent != 0x00000000) && (parent != 0xFFFFFFFF))
3261          {          {
3262                  sw_parent = seamless_get_window_by_id(parent);                  sw_parent = seamless_get_window_by_id(parent);
3263                  if (sw_parent)                  if (sw_parent)
# Line 3053  ui_seamless_create_window(unsigned long Line 3266  ui_seamless_create_window(unsigned long
3266                          warning("ui_seamless_create_window: No parent window 0x%lx\n", parent);                          warning("ui_seamless_create_window: No parent window 0x%lx\n", parent);
3267          }          }
3268    
3269    
3270          /* FIXME: Support for Input Context:s */          /* FIXME: Support for Input Context:s */
3271    
3272          get_input_mask(&input_mask);          get_input_mask(&input_mask);
# Line 3060  ui_seamless_create_window(unsigned long Line 3274  ui_seamless_create_window(unsigned long
3274    
3275          XSelectInput(g_display, wnd, input_mask);          XSelectInput(g_display, wnd, input_mask);
3276    
         XMapWindow(g_display, wnd);  
   
3277          /* handle the WM_DELETE_WINDOW protocol. FIXME: When killing a          /* handle the WM_DELETE_WINDOW protocol. FIXME: When killing a
3278             seamless window, we could try to close the window on the             seamless window, we could try to close the window on the
3279             serverside, instead of terminating rdesktop */             serverside, instead of terminating rdesktop */
3280          XSetWMProtocols(g_display, wnd, &g_kill_atom, 1);          XSetWMProtocols(g_display, wnd, &g_kill_atom, 1);
3281    
3282          sw = malloc(sizeof(seamless_window));          sw = xmalloc(sizeof(seamless_window));
3283          sw->wnd = wnd;          sw->wnd = wnd;
3284          sw->id = id;          sw->id = id;
3285            sw->parent = parent;
3286            sw->behind = 0;
3287          sw->xoffset = 0;          sw->xoffset = 0;
3288          sw->yoffset = 0;          sw->yoffset = 0;
3289          sw->width = 0;          sw->width = 0;
3290          sw->height = 0;          sw->height = 0;
3291            sw->state = SEAMLESSRDP_NOTYETMAPPED;
3292            sw->desktop = 0;
3293            sw->position_timer = xmalloc(sizeof(struct timeval));
3294            timerclear(sw->position_timer);
3295          sw->next = g_seamless_windows;          sw->next = g_seamless_windows;
3296          g_seamless_windows = sw;          g_seamless_windows = sw;
3297  }  }
# Line 3084  ui_seamless_destroy_window(unsigned long Line 3302  ui_seamless_destroy_window(unsigned long
3302  {  {
3303          seamless_window *sw;          seamless_window *sw;
3304    
3305            if (!g_seamless_active)
3306                    return;
3307    
3308          sw = seamless_get_window_by_id(id);          sw = seamless_get_window_by_id(id);
3309          if (!sw)          if (!sw)
3310          {          {
# Line 3101  ui_seamless_move_window(unsigned long id Line 3322  ui_seamless_move_window(unsigned long id
3322  {  {
3323          seamless_window *sw;          seamless_window *sw;
3324    
3325            if (!g_seamless_active)
3326                    return;
3327    
3328          sw = seamless_get_window_by_id(id);          sw = seamless_get_window_by_id(id);
3329          if (!sw)          if (!sw)
3330          {          {
# Line 3112  ui_seamless_move_window(unsigned long id Line 3336  ui_seamless_move_window(unsigned long id
3336                  /* X11 windows must be at least 1x1 */                  /* X11 windows must be at least 1x1 */
3337                  return;                  return;
3338    
3339          /* About MAX and MIN: Windows allows moving a window outside          sw->xoffset = x;
3340             the desktop. This happens, for example, when maximizing an          sw->yoffset = y;
3341             application. In this case, the position is set to something          sw->width = width;
3342             like -4,-4,1288,1032. Many WMs does not allow windows          sw->height = height;
            outside the desktop, however. Therefore, clip the window  
            ourselves. */  
         sw->xoffset = MAX(0, x);  
         sw->yoffset = MAX(0, y);  
         sw->width = MIN(MIN(width, width + x), g_width - sw->xoffset);  
         sw->height = MIN(MIN(height, height + y), g_height - sw->yoffset);  
3343    
3344          /* If we move the window in a maximized state, then KDE won't          /* If we move the window in a maximized state, then KDE won't
3345             accept restoration */             accept restoration */
3346          if (sw->state != SEAMLESSRDP_NORMAL)          switch (sw->state)
3347                  return;          {
3348                    case SEAMLESSRDP_MINIMIZED:
3349                    case SEAMLESSRDP_MAXIMIZED:
3350                            return;
3351            }
3352    
3353          /* FIXME: Perhaps use ewmh_net_moveresize_window instead */          /* FIXME: Perhaps use ewmh_net_moveresize_window instead */
3354          XMoveResizeWindow(g_display, sw->wnd, sw->xoffset, sw->yoffset, sw->width, sw->height);          XMoveResizeWindow(g_display, sw->wnd, sw->xoffset, sw->yoffset, sw->width, sw->height);
3355  }  }
3356    
3357    void
3358    ui_seamless_restack_window(unsigned long id, unsigned long behind, unsigned long flags)
3359    {
3360            seamless_window *sw;
3361    
3362            if (!g_seamless_active)
3363                    return;
3364    
3365            sw = seamless_get_window_by_id(id);
3366            if (!sw)
3367            {
3368                    warning("ui_seamless_restack_window: No information for window 0x%lx\n", id);
3369                    return;
3370            }
3371    
3372            if (behind)
3373            {
3374                    seamless_window *sw_behind;
3375                    Window wnds[2];
3376    
3377                    sw_behind = seamless_get_window_by_id(behind);
3378                    if (!sw_behind)
3379                    {
3380                            warning("ui_seamless_restack_window: No information for window 0x%lx\n",
3381                                    behind);
3382                            return;
3383                    }
3384    
3385                    wnds[1] = sw_behind->wnd;
3386                    wnds[0] = sw->wnd;
3387    
3388                    XRestackWindows(g_display, wnds, 2);
3389            }
3390            else
3391            {
3392                    XRaiseWindow(g_display, sw->wnd);
3393            }
3394    
3395            seamless_restack_window(sw, behind);
3396    }
3397    
3398  void  void
3399  ui_seamless_settitle(unsigned long id, const char *title, unsigned long flags)  ui_seamless_settitle(unsigned long id, const char *title, unsigned long flags)
3400  {  {
3401          seamless_window *sw;          seamless_window *sw;
3402    
3403            if (!g_seamless_active)
3404                    return;
3405    
3406          sw = seamless_get_window_by_id(id);          sw = seamless_get_window_by_id(id);
3407          if (!sw)          if (!sw)
3408          {          {
# Line 3145  ui_seamless_settitle(unsigned long id, c Line 3410  ui_seamless_settitle(unsigned long id, c
3410                  return;                  return;
3411          }          }
3412    
3413            /* FIXME: Might want to convert the name for non-EWMH WMs */
3414          XStoreName(g_display, sw->wnd, title);          XStoreName(g_display, sw->wnd, title);
3415            ewmh_set_wm_name(sw->wnd, title);
3416  }  }
3417    
3418    
# Line 3154  ui_seamless_setstate(unsigned long id, u Line 3421  ui_seamless_setstate(unsigned long id, u
3421  {  {
3422          seamless_window *sw;          seamless_window *sw;
3423    
3424            if (!g_seamless_active)
3425                    return;
3426    
3427          sw = seamless_get_window_by_id(id);          sw = seamless_get_window_by_id(id);
3428          if (!sw)          if (!sw)
3429          {          {
# Line 3161  ui_seamless_setstate(unsigned long id, u Line 3431  ui_seamless_setstate(unsigned long id, u
3431                  return;                  return;
3432          }          }
3433    
         sw->state = state;  
   
3434          switch (state)          switch (state)
3435          {          {
3436                  case SEAMLESSRDP_NORMAL:                  case SEAMLESSRDP_NORMAL:
3437                  case SEAMLESSRDP_MAXIMIZED:                  case SEAMLESSRDP_MAXIMIZED:
3438                          ewmh_change_state(sw->wnd, state);                          ewmh_change_state(sw->wnd, state);
3439                            XMapWindow(g_display, sw->wnd);
3440                          break;                          break;
3441                  case SEAMLESSRDP_MINIMIZED:                  case SEAMLESSRDP_MINIMIZED:
3442                          /* EWMH says: "if an Application asks to toggle _NET_WM_STATE_HIDDEN                          /* EWMH says: "if an Application asks to toggle _NET_WM_STATE_HIDDEN
# Line 3175  ui_seamless_setstate(unsigned long id, u Line 3444  ui_seamless_setstate(unsigned long id, u
3444                             _NET_WM_STATE_HIDDEN is a function of some other aspect of the window                             _NET_WM_STATE_HIDDEN is a function of some other aspect of the window
3445                             such as minimization, rather than an independent state." Besides,                             such as minimization, rather than an independent state." Besides,
3446                             XIconifyWindow is easier. */                             XIconifyWindow is easier. */
3447                          XIconifyWindow(g_display, sw->wnd, DefaultScreen(g_display));                          if (sw->state == SEAMLESSRDP_NOTYETMAPPED)
3448                            {
3449                                    XWMHints *hints;
3450                                    hints = XAllocWMHints();
3451                                    hints->flags = StateHint;
3452                                    hints->initial_state = IconicState;
3453                                    XSetWMHints(g_display, sw->wnd, hints);
3454                                    XFree(hints);
3455                                    XMapWindow(g_display, sw->wnd);
3456                            }
3457                            else
3458                                    XIconifyWindow(g_display, sw->wnd, DefaultScreen(g_display));
3459                          break;                          break;
3460                  default:                  default:
3461                          warning("SeamlessRDP: Invalid state %d\n", state);                          warning("SeamlessRDP: Invalid state %d\n", state);
3462                          break;                          break;
3463          }          }
3464    
3465            /* Handle popups without parents through some ewm hints */
3466            if ((sw->state == SEAMLESSRDP_NOTYETMAPPED) && (sw->parent == 0xFFFFFFFF))
3467                    ewmh_set_window_popup(sw->wnd);
3468    
3469            sw->state = state;
3470    }
3471    
3472    
3473    void
3474    ui_seamless_syncbegin(unsigned long flags)
3475    {
3476            if (!g_seamless_active)
3477                    return;
3478    
3479            /* Destroy all seamless windows */
3480            while (g_seamless_windows)
3481            {
3482                    XDestroyWindow(g_display, g_seamless_windows->wnd);
3483                    seamless_remove_window(g_seamless_windows);
3484            }
3485  }  }

Legend:
Removed from v.1118  
changed lines
  Added in v.1157

  ViewVC Help
Powered by ViewVC 1.1.26