Floatbar self contained.

This commit is contained in:
Armin Novak 2018-11-15 14:42:31 +01:00
parent 6c88c21736
commit 56156d217e
9 changed files with 317 additions and 178 deletions

View File

@ -1164,7 +1164,6 @@ static BOOL xf_pre_connect(freerdp* instance)
xfc->decorations = settings->Decorations;
xfc->grab_keyboard = settings->GrabKeyboard;
xfc->fullscreen_toggle = settings->ToggleFullscreen;
xfc->floatbar = settings->Floatbar;
xf_button_map_init(xfc);
return TRUE;
}
@ -1546,9 +1545,7 @@ static DWORD WINAPI xf_client_thread(LPVOID param)
nCount += tmp;
}
if (xfc->floatbar && xfc->fullscreen && !xfc->remote_app)
xf_floatbar_hide_and_show(xfc);
xf_floatbar_hide_and_show(xfc->window->floatbar);
waitStatus = WaitForMultipleObjects(nCount, handles, FALSE, INFINITE);
if (waitStatus == WAIT_FAILED)

View File

@ -367,9 +367,7 @@ static BOOL xf_event_MotionNotify(xfContext* xfc, XEvent* event, BOOL app)
if (xfc->use_xinput)
return TRUE;
if(xfc->floatbar && !(app))
xf_floatbar_set_root_y(xfc, event->xmotion.y);
xf_floatbar_set_root_y(xfc->window->floatbar, event->xmotion.y);
return xf_generic_MotionNotify(xfc, event->xmotion.x, event->xmotion.y,
event->xmotion.state, event->xmotion.window, app);
}
@ -1018,9 +1016,9 @@ BOOL xf_event_process(freerdp* instance, XEvent* event)
}
}
if (xfc->floatbar && xf_floatbar_check_event(xfc, event))
if (xf_floatbar_check_event(xfc->window->floatbar, event))
{
xf_floatbar_event_process(xfc, event);
xf_floatbar_event_process(xfc->window->floatbar, event);
return TRUE;
}

View File

@ -57,6 +57,8 @@
#define XF_FLOATBAR_BUTTON_MINIMIZE 3
#define XF_FLOATBAR_BUTTON_LOCKED 4
typedef BOOL(*OnClick)(xfFloatbar*);
typedef struct xf_floatbar_button xfFloatbarButton;
struct xf_floatbar
@ -71,6 +73,11 @@ struct xf_floatbar
bool locked;
xfFloatbarButton* buttons[4];
Window handle;
BOOL hasCursor;
xfContext* xfc;
DWORD flags;
BOOL created;
Window root_window;
};
struct xf_floatbar_button
@ -84,43 +91,70 @@ struct xf_floatbar_button
Window handle;
};
static void xf_floatbar_button_onclick_close(xfContext* xfc)
static xfFloatbarButton* xf_floatbar_new_button(xfFloatbar* floatbar, int type);
static BOOL xf_floatbar_button_onclick_close(xfFloatbar* floatbar)
{
freerdp_abort_connect(xfc->context.instance);
if (!floatbar)
return FALSE;
return freerdp_abort_connect(floatbar->xfc->context.instance);
}
static void xf_floatbar_button_onclick_minimize(xfContext* xfc)
static BOOL xf_floatbar_button_onclick_minimize(xfFloatbar* floatbar)
{
xfContext* xfc;
if (!floatbar || !floatbar->xfc)
return FALSE;
xfc = floatbar->xfc;
xf_SetWindowMinimized(xfc, xfc->window);
return TRUE;
}
static void xf_floatbar_button_onclick_restore(xfContext* xfc)
static BOOL xf_floatbar_button_onclick_restore(xfFloatbar* floatbar)
{
xf_toggle_fullscreen(xfc);
if (!floatbar)
return FALSE;
xf_toggle_fullscreen(floatbar->xfc);
return TRUE;
}
static void xf_floatbar_button_onclick_locked(xfContext* xfc)
static BOOL xf_floatbar_button_onclick_locked(xfFloatbar* floatbar)
{
xfFloatbar* floatbar;
floatbar = xfc->window->floatbar;
if (!floatbar)
return FALSE;
floatbar->locked = (floatbar->locked) ? FALSE : TRUE;
return xf_floatbar_hide_and_show(floatbar);
}
void xf_floatbar_set_root_y(xfContext* xfc, int y)
BOOL xf_floatbar_set_root_y(xfFloatbar* floatbar, int y)
{
xfFloatbar* floatbar;
floatbar = xfc->window->floatbar;
if (!floatbar)
return FALSE;
floatbar->last_motion_y_root = y;
return TRUE;
}
void xf_floatbar_hide_and_show(xfContext* xfc)
BOOL xf_floatbar_hide_and_show(xfFloatbar* floatbar)
{
xfFloatbar* floatbar;
floatbar = xfc->window->floatbar;
xfContext* xfc;
if (!floatbar || !floatbar->xfc)
return FALSE;
if (!floatbar->created)
return TRUE;
xfc = floatbar->xfc;
if (!floatbar->locked)
{
if ((floatbar->mode == 0) && (floatbar->last_motion_y_root > 10) &&
if ((floatbar->mode == XF_FLOATBAR_MODE_NONE) && (floatbar->last_motion_y_root > 10) &&
(floatbar->y > (FLOATBAR_HEIGHT * -1)))
{
floatbar->y = floatbar->y - 1;
@ -132,16 +166,70 @@ void xf_floatbar_hide_and_show(xfContext* xfc)
XMoveWindow(xfc->display, floatbar->handle, floatbar->x, floatbar->y);
}
}
return TRUE;
}
void xf_floatbar_toggle_visibility(xfContext* xfc, bool visible)
static BOOL create_floatbar(xfFloatbar* floatbar)
{
xfContext* xfc;
Status status;
XWindowAttributes attr;
if (floatbar->created)
return TRUE;
xfc = floatbar->xfc;
status = XGetWindowAttributes(xfc->display, floatbar->root_window, &attr);
floatbar->x = attr.x + attr.width / 2 - FLOATBAR_DEFAULT_WIDTH / 2;
floatbar->y = 0;
if (((floatbar->flags & 0x0004) == 0) && !floatbar->locked)
floatbar->y = -FLOATBAR_HEIGHT + 1;
floatbar->handle = XCreateWindow(xfc->display, floatbar->root_window,
floatbar->x, 0, FLOATBAR_DEFAULT_WIDTH,
FLOATBAR_HEIGHT, 0,
CopyFromParent, InputOutput, CopyFromParent, 0, NULL);
floatbar->width = FLOATBAR_DEFAULT_WIDTH;
floatbar->height = FLOATBAR_HEIGHT;
floatbar->mode = XF_FLOATBAR_MODE_NONE;
floatbar->buttons[0] = xf_floatbar_new_button(floatbar, XF_FLOATBAR_BUTTON_CLOSE);
floatbar->buttons[1] = xf_floatbar_new_button(floatbar, XF_FLOATBAR_BUTTON_RESTORE);
floatbar->buttons[2] = xf_floatbar_new_button(floatbar, XF_FLOATBAR_BUTTON_MINIMIZE);
floatbar->buttons[3] = xf_floatbar_new_button(floatbar, XF_FLOATBAR_BUTTON_LOCKED);
XSelectInput(xfc->display, floatbar->handle, ExposureMask | ButtonPressMask | ButtonReleaseMask |
PointerMotionMask | FocusChangeMask | LeaveWindowMask | EnterWindowMask | StructureNotifyMask |
PropertyChangeMask);
floatbar->created = TRUE;
return TRUE;
}
BOOL xf_floatbar_toggle_fullscreen(xfFloatbar* floatbar, bool fullscreen)
{
xfFloatbar* floatbar;
int i, size;
floatbar = xfc->window->floatbar;
bool visible = False;
xfContext* xfc;
if (!floatbar || !floatbar->xfc)
return FALSE;
xfc = floatbar->xfc;
/* Only visible if enabled */
if (floatbar->flags & 0x0001)
{
/* Visible if fullscreen and flag visible in fullscreen mode */
visible |= ((floatbar->flags & 0x0010) != 0) && fullscreen;
/* Visible if window and flag visible in window mode */
visible |= ((floatbar->flags & 0x0020) != 0) && !fullscreen;
}
if (visible)
{
if (!create_floatbar(floatbar))
return FALSE;
XMapWindow(xfc->display, floatbar->handle);
size = ARRAYSIZE(floatbar->buttons);
@ -149,15 +237,23 @@ void xf_floatbar_toggle_visibility(xfContext* xfc, bool visible)
{
XMapWindow(xfc->display, floatbar->buttons[i]->handle);
}
/* If default is hidden (and not sticky) don't show on fullscreen state changes */
if (((floatbar->flags & 0x0004) == 0) && !floatbar->locked)
floatbar->y = -FLOATBAR_HEIGHT + 1;
xf_floatbar_hide_and_show(floatbar);
}
else
else if (floatbar->created)
{
XUnmapSubwindows(xfc->display, floatbar->handle);
XUnmapWindow(xfc->display, floatbar->handle);
}
return TRUE;
}
static xfFloatbarButton* xf_floatbar_new_button(xfContext* xfc, xfFloatbar* floatbar, int type)
xfFloatbarButton* xf_floatbar_new_button(xfFloatbar* floatbar, int type)
{
xfFloatbarButton* button;
button = (xfFloatbarButton*) calloc(1, sizeof(xfFloatbarButton));
@ -191,74 +287,67 @@ static xfFloatbarButton* xf_floatbar_new_button(xfContext* xfc, xfFloatbar* floa
button->y = 0;
button->focus = FALSE;
button->handle = XCreateWindow(xfc->display, floatbar->handle, button->x, 0, FLOATBAR_BUTTON_WIDTH,
button->handle = XCreateWindow(floatbar->xfc->display, floatbar->handle, button->x, 0,
FLOATBAR_BUTTON_WIDTH,
FLOATBAR_BUTTON_WIDTH, 0, CopyFromParent, InputOutput, CopyFromParent, 0, NULL);
XSelectInput(xfc->display, button->handle, ExposureMask | ButtonPressMask | ButtonReleaseMask |
XSelectInput(floatbar->xfc->display, button->handle,
ExposureMask | ButtonPressMask | ButtonReleaseMask |
FocusChangeMask | LeaveWindowMask | EnterWindowMask | StructureNotifyMask);
return button;
}
xfFloatbar* xf_floatbar_new(xfContext* xfc, Window window)
xfFloatbar* xf_floatbar_new(xfContext* xfc, Window window, DWORD flags)
{
xfFloatbar* floatbar;
XWindowAttributes attr;
int i, width;
/* Floatbar not enabled */
if ((flags & 0x0001) == 0)
return NULL;
if (!xfc)
return NULL;
/* Force disable with remote app */
if (xfc->remote_app)
return NULL;
floatbar = (xfFloatbar*) calloc(1, sizeof(xfFloatbar));
floatbar->locked = TRUE;
XGetWindowAttributes(xfc->display, window, &attr);
for (i = 0; i < xfc->vscreen.nmonitors; i++)
{
if (attr.x >= xfc->vscreen.monitors[i].area.left && attr.x <= xfc->vscreen.monitors[i].area.right)
{
width = xfc->vscreen.monitors[i].area.right - xfc->vscreen.monitors[i].area.left;
floatbar->x = width / 2 + xfc->vscreen.monitors[i].area.left - FLOATBAR_DEFAULT_WIDTH / 2;
}
}
if (!floatbar)
return NULL;
floatbar->y = 0;
floatbar->handle = XCreateWindow(xfc->display, window, floatbar->x, 0, FLOATBAR_DEFAULT_WIDTH,
FLOATBAR_HEIGHT, 0,
CopyFromParent, InputOutput, CopyFromParent, 0, NULL);
floatbar->width = FLOATBAR_DEFAULT_WIDTH;
floatbar->height = FLOATBAR_HEIGHT;
floatbar->mode = XF_FLOATBAR_MODE_NONE;
floatbar->buttons[0] = xf_floatbar_new_button(xfc, floatbar, XF_FLOATBAR_BUTTON_CLOSE);
floatbar->buttons[1] = xf_floatbar_new_button(xfc, floatbar, XF_FLOATBAR_BUTTON_RESTORE);
floatbar->buttons[2] = xf_floatbar_new_button(xfc, floatbar, XF_FLOATBAR_BUTTON_MINIMIZE);
floatbar->buttons[3] = xf_floatbar_new_button(xfc, floatbar, XF_FLOATBAR_BUTTON_LOCKED);
XSelectInput(xfc->display, floatbar->handle, ExposureMask | ButtonPressMask | ButtonReleaseMask |
PointerMotionMask | FocusChangeMask | LeaveWindowMask | EnterWindowMask | StructureNotifyMask |
PropertyChangeMask);
floatbar->root_window = window;
floatbar->flags = flags;
floatbar->xfc = xfc;
floatbar->locked = flags & 0x0002;
xf_floatbar_toggle_fullscreen(floatbar, FALSE);
return floatbar;
}
static unsigned long xf_floatbar_get_color(xfContext* xfc, char* rgb_value)
static unsigned long xf_floatbar_get_color(xfFloatbar* floatbar, char* rgb_value)
{
Colormap cmap;
XColor color;
cmap = DefaultColormap(xfc->display, XDefaultScreen(xfc->display));
XParseColor(xfc->display, cmap, rgb_value, &color);
XAllocColor(xfc->display, cmap, &color);
XFreeColormap(xfc->display, cmap);
Display* display = floatbar->xfc->display;
cmap = DefaultColormap(display, XDefaultScreen(display));
XParseColor(display, cmap, rgb_value, &color);
XAllocColor(display, cmap, &color);
XFreeColormap(display, cmap);
return color.pixel;
}
static void xf_floatbar_event_expose(xfContext* xfc, XEvent* event)
static void xf_floatbar_event_expose(xfFloatbar* floatbar, XEvent* event)
{
GC gc, shape_gc;
Pixmap pmap;
XPoint shape[5], border[5];
xfFloatbar* floatbar;
int len;
floatbar = xfc->window->floatbar;
rdpSettings* settings = floatbar->xfc->context.settings;
Display* display = floatbar->xfc->display;
/* create the pixmap that we'll use for shaping the window */
pmap = XCreatePixmap(xfc->display, floatbar->handle, floatbar->width, floatbar->height, 1);
gc = XCreateGC(xfc->display, floatbar->handle, 0, 0);
shape_gc = XCreateGC(xfc->display, pmap, 0, 0);
pmap = XCreatePixmap(display, floatbar->handle, floatbar->width, floatbar->height, 1);
gc = XCreateGC(display, floatbar->handle, 0, 0);
shape_gc = XCreateGC(display, pmap, 0, 0);
/* points for drawing the floatbar */
shape[0].x = 0;
shape[0].y = 0;
@ -282,34 +371,32 @@ static void xf_floatbar_event_expose(xfContext* xfc, XEvent* event)
border[4].x = border[0].x;
border[4].y = border[0].y;
/* Fill all pixels with 0 */
XSetForeground(xfc->display, shape_gc, 0);
XFillRectangle(xfc->display, pmap, shape_gc, 0, 0, floatbar->width,
XSetForeground(display, shape_gc, 0);
XFillRectangle(display, pmap, shape_gc, 0, 0, floatbar->width,
floatbar->height);
/* Fill all pixels which should be shown with 1 */
XSetForeground(xfc->display, shape_gc, 1);
XFillPolygon(xfc->display, pmap, shape_gc, shape, 5, 0, CoordModeOrigin);
XShapeCombineMask(xfc->display, floatbar->handle, ShapeBounding, 0, 0, pmap, ShapeSet);
XSetForeground(display, shape_gc, 1);
XFillPolygon(display, pmap, shape_gc, shape, 5, 0, CoordModeOrigin);
XShapeCombineMask(display, floatbar->handle, ShapeBounding, 0, 0, pmap, ShapeSet);
/* draw the float bar */
XSetForeground(xfc->display, gc, xf_floatbar_get_color(xfc, FLOATBAR_COLOR_BACKGROUND));
XFillPolygon(xfc->display, floatbar->handle, gc, shape, 4, 0, CoordModeOrigin);
XSetForeground(display, gc, xf_floatbar_get_color(floatbar, FLOATBAR_COLOR_BACKGROUND));
XFillPolygon(display, floatbar->handle, gc, shape, 4, 0, CoordModeOrigin);
/* draw an border for the floatbar */
XSetForeground(xfc->display, gc, xf_floatbar_get_color(xfc, FLOATBAR_COLOR_BORDER));
XDrawLines(xfc->display, floatbar->handle, gc, border, 5, CoordModeOrigin);
XSetForeground(display, gc, xf_floatbar_get_color(floatbar, FLOATBAR_COLOR_BORDER));
XDrawLines(display, floatbar->handle, gc, border, 5, CoordModeOrigin);
/* draw the host name connected to */
len = strlen(xfc->context.settings->ServerHostname);
XSetForeground(xfc->display, gc, xf_floatbar_get_color(xfc, FLOATBAR_COLOR_FOREGROUND));
XDrawString(xfc->display, floatbar->handle, gc, floatbar->width / 2 - len * 2, 15,
xfc->context.settings->ServerHostname, len);
XFreeGC(xfc->display, gc);
XFreeGC(xfc->display, shape_gc);
len = strlen(settings->ServerHostname);
XSetForeground(display, gc, xf_floatbar_get_color(floatbar, FLOATBAR_COLOR_FOREGROUND));
XDrawString(display, floatbar->handle, gc, floatbar->width / 2 - len * 2, 15,
settings->ServerHostname, len);
XFreeGC(display, gc);
XFreeGC(display, shape_gc);
}
static xfFloatbarButton* xf_floatbar_get_button(xfContext* xfc, XEvent* event)
static xfFloatbarButton* xf_floatbar_get_button(xfFloatbar* floatbar, XEvent* event)
{
xfFloatbar* floatbar;
int i, size;
size = ARRAYSIZE(floatbar->buttons);
floatbar = xfc->window->floatbar;
for (i = 0; i < size; i++)
{
@ -322,12 +409,11 @@ static xfFloatbarButton* xf_floatbar_get_button(xfContext* xfc, XEvent* event)
return NULL;
}
static void xf_floatbar_button_update_positon(xfContext* xfc, XEvent* event)
static void xf_floatbar_button_update_positon(xfFloatbar* floatbar, XEvent* event)
{
xfFloatbar* floatbar;
xfFloatbarButton* button;
int i, size;
floatbar = xfc->window->floatbar;
xfContext* xfc = floatbar->xfc;
size = ARRAYSIZE(floatbar->buttons);
for (i = 0; i < size; i++)
@ -353,18 +439,17 @@ static void xf_floatbar_button_update_positon(xfContext* xfc, XEvent* event)
}
XMoveWindow(xfc->display, button->handle, button->x, button->y);
xf_floatbar_event_expose(xfc, event);
xf_floatbar_event_expose(floatbar, event);
}
}
static void xf_floatbar_button_event_expose(xfContext* xfc, XEvent* event)
static void xf_floatbar_button_event_expose(xfFloatbar* floatbar, XEvent* event)
{
xfFloatbar* floatbar;
xfFloatbarButton* button;
xfFloatbarButton* button = xf_floatbar_get_button(floatbar, event);
static unsigned char* bits;
GC gc;
Pixmap pattern;
button = xf_floatbar_get_button(xfc, event);
xfContext* xfc = floatbar->xfc;
if (!button)
return;
@ -402,43 +487,39 @@ static void xf_floatbar_button_event_expose(xfContext* xfc, XEvent* event)
FLOATBAR_BUTTON_WIDTH, FLOATBAR_BUTTON_WIDTH);
if (!(button->focus))
XSetForeground(xfc->display, gc, xf_floatbar_get_color(xfc, FLOATBAR_COLOR_BACKGROUND));
XSetForeground(xfc->display, gc, xf_floatbar_get_color(floatbar, FLOATBAR_COLOR_BACKGROUND));
else
XSetForeground(xfc->display, gc, xf_floatbar_get_color(xfc, FLOATBAR_COLOR_BORDER));
XSetForeground(xfc->display, gc, xf_floatbar_get_color(floatbar, FLOATBAR_COLOR_BORDER));
XSetBackground(xfc->display, gc, xf_floatbar_get_color(xfc, FLOATBAR_COLOR_FOREGROUND));
XSetBackground(xfc->display, gc, xf_floatbar_get_color(floatbar, FLOATBAR_COLOR_FOREGROUND));
XCopyPlane(xfc->display, pattern, button->handle, gc, 0, 0, FLOATBAR_BUTTON_WIDTH,
FLOATBAR_BUTTON_WIDTH, 0, 0, 1);
XFreePixmap(xfc->display, pattern);
XFreeGC(xfc->display, gc);
}
static void xf_floatbar_button_event_buttonpress(xfContext* xfc, XEvent* event)
static void xf_floatbar_button_event_buttonpress(xfFloatbar* floatbar, XEvent* event)
{
xfFloatbarButton* button;
button = xf_floatbar_get_button(xfc, event);
xfFloatbarButton* button = xf_floatbar_get_button(floatbar, event);
if (button)
button->clicked = TRUE;
}
static void xf_floatbar_button_event_buttonrelease(xfContext* xfc, XEvent* event)
static void xf_floatbar_button_event_buttonrelease(xfFloatbar* floatbar, XEvent* event)
{
xfFloatbarButton* button;
button = xf_floatbar_get_button(xfc, event);
button = xf_floatbar_get_button(floatbar, event);
if (button)
{
if (button->clicked)
button->onclick(xfc);
button->onclick(floatbar);
}
}
static void xf_floatbar_event_buttonpress(xfContext* xfc, XEvent* event)
static void xf_floatbar_event_buttonpress(xfFloatbar* floatbar, XEvent* event)
{
xfFloatbar* floatbar;
floatbar = xfc->window->floatbar;
switch (event->xbutton.button)
{
case Button1:
@ -456,12 +537,12 @@ static void xf_floatbar_event_buttonpress(xfContext* xfc, XEvent* event)
}
}
static void xf_floatbar_event_buttonrelease(xfContext* xfc, XEvent* event)
static void xf_floatbar_event_buttonrelease(xfFloatbar* floatbar, XEvent* event)
{
switch (event->xbutton.button)
{
case Button1:
xfc->window->floatbar->mode = XF_FLOATBAR_MODE_NONE;
floatbar->mode = XF_FLOATBAR_MODE_NONE;
break;
default:
@ -469,11 +550,10 @@ static void xf_floatbar_event_buttonrelease(xfContext* xfc, XEvent* event)
}
}
static void xf_floatbar_resize(xfContext* xfc, XEvent* event)
static void xf_floatbar_resize(xfFloatbar* floatbar, XEvent* event)
{
xfFloatbar* floatbar;
floatbar = xfc->window->floatbar;
int x, width, movement;
xfContext* xfc = floatbar->xfc;
/* calculate movement which happened on the root window */
movement = event->xmotion.x_root - floatbar->last_motion_x_root;
@ -498,11 +578,10 @@ static void xf_floatbar_resize(xfContext* xfc, XEvent* event)
}
}
static void xf_floatbar_dragging(xfContext* xfc, XEvent* event)
static void xf_floatbar_dragging(xfFloatbar* floatbar, XEvent* event)
{
xfFloatbar* floatbar;
floatbar = xfc->window->floatbar;
int x, movement;
xfContext* xfc = floatbar->xfc;
/* calculate movement and new x position */
movement = event->xmotion.x_root - floatbar->last_motion_x_root;
x = floatbar->x + movement;
@ -518,78 +597,82 @@ static void xf_floatbar_dragging(xfContext* xfc, XEvent* event)
floatbar->x = x;
}
static void xf_floatbar_event_motionnotify(xfContext* xfc, XEvent* event)
static void xf_floatbar_event_motionnotify(xfFloatbar* floatbar, XEvent* event)
{
int mode;
xfFloatbar* floatbar;
Cursor cursor;
mode = xfc->window->floatbar->mode;
floatbar = xfc->window->floatbar;
xfContext* xfc = floatbar->xfc;
mode = floatbar->mode;
cursor = XCreateFontCursor(xfc->display, XC_arrow);
if ((event->xmotion.state & Button1Mask) && (mode > XF_FLOATBAR_MODE_DRAGGING))
{
xf_floatbar_resize(xfc, event);
xf_floatbar_resize(floatbar, event);
}
else if ((event->xmotion.state & Button1Mask) && (mode == XF_FLOATBAR_MODE_DRAGGING))
{
xf_floatbar_dragging(xfc, event);
xf_floatbar_dragging(floatbar, event);
}
else
{
if (event->xmotion.x <= FLOATBAR_BORDER ||
event->xmotion.x >= xfc->window->floatbar->width - FLOATBAR_BORDER)
event->xmotion.x >= floatbar->width - FLOATBAR_BORDER)
cursor = XCreateFontCursor(xfc->display, XC_sb_h_double_arrow);
}
XDefineCursor(xfc->display, xfc->window->handle, cursor);
XFreeCursor(xfc->display, cursor);
xfc->window->floatbar->last_motion_x_root = event->xmotion.x_root;
floatbar->last_motion_x_root = event->xmotion.x_root;
}
static void xf_floatbar_button_event_focusin(xfContext* xfc, XEvent* event)
static void xf_floatbar_button_event_focusin(xfFloatbar* floatbar, XEvent* event)
{
xfFloatbarButton* button;
button = xf_floatbar_get_button(xfc, event);
button = xf_floatbar_get_button(floatbar, event);
if (button)
{
button->focus = TRUE;
xf_floatbar_button_event_expose(xfc, event);
xf_floatbar_button_event_expose(floatbar, event);
}
}
static void xf_floatbar_button_event_focusout(xfContext* xfc, XEvent* event)
static void xf_floatbar_button_event_focusout(xfFloatbar* floatbar, XEvent* event)
{
xfFloatbarButton* button;
button = xf_floatbar_get_button(xfc, event);
button = xf_floatbar_get_button(floatbar, event);
if (button)
{
button->focus = FALSE;
button->clicked = FALSE;
xf_floatbar_button_event_expose(xfc, event);
xf_floatbar_button_event_expose(floatbar, event);
}
}
static void xf_floatbar_event_focusout(xfContext* xfc, XEvent* event)
static void xf_floatbar_event_focusout(xfFloatbar* floatbar, XEvent* event)
{
Cursor cursor;
cursor = XCreateFontCursor(xfc->display, XC_arrow);
XDefineCursor(xfc->display, xfc->window->handle, cursor);
XFreeCursor(xfc->display, cursor);
xfContext* xfc = floatbar->xfc;
if (xfc->pointer)
{
XDefineCursor(xfc->display, xfc->window->handle, xfc->pointer->cursor);
}
}
BOOL xf_floatbar_check_event(xfContext* xfc, XEvent* event)
BOOL xf_floatbar_check_event(xfFloatbar* floatbar, XEvent* event)
{
xfFloatbar* floatbar;
xfFloatbarButton* button;
size_t i, size;
xfContext* xfc;
if (!xfc || !event || !xfc->window)
if (!floatbar || !floatbar->xfc || !event)
return FALSE;
floatbar = xfc->window->floatbar;
if (!floatbar->created)
return FALSE;
xfc = floatbar->xfc;
if (event->xany.window == floatbar->handle)
return TRUE;
@ -607,70 +690,69 @@ BOOL xf_floatbar_check_event(xfContext* xfc, XEvent* event)
return FALSE;
}
BOOL xf_floatbar_event_process(xfContext* xfc, XEvent* event)
BOOL xf_floatbar_event_process(xfFloatbar* floatbar, XEvent* event)
{
xfFloatbar* floatbar;
if (!xfc || !xfc->window || !event)
if (!floatbar || !floatbar->xfc || !event)
return FALSE;
floatbar = xfc->window->floatbar;
if (!floatbar->created)
return FALSE;
switch (event->type)
{
case Expose:
if (event->xany.window == floatbar->handle)
xf_floatbar_event_expose(xfc, event);
xf_floatbar_event_expose(floatbar, event);
else
xf_floatbar_button_event_expose(xfc, event);
xf_floatbar_button_event_expose(floatbar, event);
break;
case MotionNotify:
xf_floatbar_event_motionnotify(xfc, event);
xf_floatbar_event_motionnotify(floatbar, event);
break;
case ButtonPress:
if (event->xany.window == floatbar->handle)
xf_floatbar_event_buttonpress(xfc, event);
xf_floatbar_event_buttonpress(floatbar, event);
else
xf_floatbar_button_event_buttonpress(xfc, event);
xf_floatbar_button_event_buttonpress(floatbar, event);
break;
case ButtonRelease:
if (event->xany.window == floatbar->handle)
xf_floatbar_event_buttonrelease(xfc, event);
xf_floatbar_event_buttonrelease(floatbar, event);
else
xf_floatbar_button_event_buttonrelease(xfc, event);
xf_floatbar_button_event_buttonrelease(floatbar, event);
break;
case EnterNotify:
case FocusIn:
if (event->xany.window != floatbar->handle)
xf_floatbar_button_event_focusin(xfc, event);
xf_floatbar_button_event_focusin(floatbar, event);
break;
case LeaveNotify:
case FocusOut:
if (event->xany.window == floatbar->handle)
xf_floatbar_event_focusout(xfc, event);
xf_floatbar_event_focusout(floatbar, event);
else
xf_floatbar_button_event_focusout(xfc, event);
xf_floatbar_button_event_focusout(floatbar, event);
break;
case ConfigureNotify:
if (event->xany.window == floatbar->handle)
xf_floatbar_button_update_positon(xfc, event);
xf_floatbar_button_update_positon(floatbar, event);
break;
case PropertyNotify:
if (event->xany.window == floatbar->handle)
xf_floatbar_button_update_positon(xfc, event);
xf_floatbar_button_update_positon(floatbar, event);
break;
@ -695,16 +777,19 @@ static void xf_floatbar_button_free(xfContext* xfc, xfFloatbarButton* button)
free(button);
}
void xf_floatbar_free(xfContext* xfc, xfWindow* window, xfFloatbar* floatbar)
void xf_floatbar_free(xfFloatbar* floatbar)
{
size_t i, size;
size = ARRAYSIZE(floatbar->buttons);
xfContext* xfc;
if (!floatbar)
return;
if (window->floatbar == floatbar)
window->floatbar = NULL;
xfc = floatbar->xfc;
size = ARRAYSIZE(floatbar->buttons);
if (!floatbar)
return;
for (i = 0; i < size; i++)
{

View File

@ -22,13 +22,13 @@ typedef struct xf_floatbar xfFloatbar;
#include "xfreerdp.h"
typedef void(*OnClick)(xfContext*);
xfFloatbar* xf_floatbar_new(xfContext* xfc, Window window);
BOOL xf_floatbar_event_process(xfContext* xfc, XEvent* event);
BOOL xf_floatbar_check_event(xfContext* xfc, XEvent* event);
void xf_floatbar_toggle_visibility(xfContext* xfc, bool visible);
void xf_floatbar_free(xfContext* xfc, xfWindow* window, xfFloatbar* floatbar);
void xf_floatbar_hide_and_show(xfContext* xfc);
void xf_floatbar_set_root_y(xfContext* xfc, int y);
xfFloatbar* xf_floatbar_new(xfContext* xfc, Window window, DWORD flags);
void xf_floatbar_free(xfFloatbar* floatbar);
BOOL xf_floatbar_event_process(xfFloatbar* floatbar, XEvent* event);
BOOL xf_floatbar_check_event(xfFloatbar* floatbar, XEvent* event);
BOOL xf_floatbar_toggle_fullscreen(xfFloatbar* floatbar, bool visible);
BOOL xf_floatbar_hide_and_show(xfFloatbar* floatbar);
BOOL xf_floatbar_set_root_y(xfFloatbar* floatbar, int y);
#endif /* FREERDP_CLIENT_X11_FLOATBAR_H */

View File

@ -163,9 +163,7 @@ void xf_SetWindowFullscreen(xfContext* xfc, xfWindow* window, BOOL fullscreen)
/* show/hide decorations (e.g. title bar) as guided by xfc->decorations */
xf_SetWindowDecorations(xfc, window->handle, window->decorations);
DEBUG_X11(TAG, "X window decoration set to %d", (int)window->decorations);
if (xfc->floatbar)
xf_floatbar_toggle_visibility(xfc, fullscreen);
xf_floatbar_toggle_fullscreen(xfc->window->floatbar, fullscreen);
if (fullscreen)
{
@ -587,7 +585,7 @@ xfWindow* xf_CreateDesktopWindow(xfContext* xfc, char* name, int width,
settings->DesktopPosY);
}
window->floatbar = xf_floatbar_new(xfc, window->handle);
window->floatbar = xf_floatbar_new(xfc, window->handle, settings->Floatbar);
return window;
}
@ -636,8 +634,7 @@ void xf_DestroyDesktopWindow(xfContext* xfc, xfWindow* window)
if (xfc->window == window)
xfc->window = NULL;
if (window->floatbar)
xf_floatbar_free(xfc, window, window->floatbar);
xf_floatbar_free(window->floatbar);
if (window->gc)
XFreeGC(xfc->display, window->gc);

View File

@ -161,7 +161,6 @@ struct xf_context
BOOL use_xinput;
BOOL mouse_active;
BOOL fullscreen_toggle;
BOOL floatbar;
BOOL controlToggle;
UINT32 KeyboardLayout;
BOOL KeyboardState[256];

View File

@ -2628,7 +2628,70 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
}
CommandLineSwitchCase(arg, "floatbar")
{
settings->Floatbar = enable;
/* Defaults are enabled, visible, sticky, fullscreen */
settings->Floatbar = 0x0017;
if (arg->Value)
{
char* start = arg->Value;
do
{
char* cur = start;
start = strchr(start, ',');
if (start)
{
*start = '\0';
start = start + 1;
}
/* sticky:[on|off] */
if (strncasecmp(cur, "sticky:", 7) == 0)
{
const char* val = cur + 7;
settings->Floatbar &= ~0x02u;
if (strncasecmp(val, "on", 3) == 0)
settings->Floatbar |= 0x02u;
else if (strncasecmp(val, "off", 4) == 0)
settings->Floatbar &= ~0x02u;
else
return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
}
/* default:[visible|hidden] */
else if (strncasecmp(cur, "default:", 8) == 0)
{
const char* val = cur + 8;
settings->Floatbar &= ~0x04u;
if (strncasecmp(val, "visible", 8) == 0)
settings->Floatbar |= 0x04u;
else if (strncasecmp(val, "hidden", 7) == 0)
settings->Floatbar &= ~0x04u;
else
return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
}
/* show:[always|fullscreen|window] */
else if (strncasecmp(cur, "show:", 5) == 0)
{
const char* val = cur + 5;
settings->Floatbar &= ~0x30u;
if (strncasecmp(val, "always", 7) == 0)
settings->Floatbar |= 0x30u;
else if (strncasecmp(val, "fullscreen", 11) == 0)
settings->Floatbar |= 0x10u;
else if (strncasecmp(val, "window", 7) == 0)
settings->Floatbar |= 0x20u;
else
return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
}
else
return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
}
while (start);
}
}
CommandLineSwitchCase(arg, "mouse-motion")
{

View File

@ -68,7 +68,7 @@ static COMMAND_LINE_ARGUMENT_A args[] =
{ "f", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "Fullscreen mode (<Ctrl>+<Alt>+<Enter> toggles fullscreen)" },
{ "fast-path", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "fast-path input/output" },
{ "fipsmode", COMMAND_LINE_VALUE_BOOL, NULL, NULL, NULL, -1, NULL, "FIPS mode" },
{ "floatbar", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "floatbar in fullscreen mode" },
{ "floatbar", COMMAND_LINE_VALUE_OPTIONAL, "sticky:[on|off],default:[visible|hidden],show:[always|fullscreen||window]", NULL, NULL, -1, NULL, "floatbar (default sticky in fullscreen mode)" },
{ "fonts", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "smooth fonts (ClearType)" },
{ "frame-ack", COMMAND_LINE_VALUE_REQUIRED, "<number>", NULL, NULL, -1, NULL, "Number of frame acknowledgement" },
{ "from-stdin", COMMAND_LINE_VALUE_OPTIONAL, "force", NULL, NULL, -1, NULL, "Read credentials from stdin. With <force> the prompt is done before connection, otherwise on server request." },

View File

@ -1518,7 +1518,7 @@ struct rdp_settings
ALIGN64 BYTE*
SettingsModified; /* byte array marking fields that have been modified from their default value */
ALIGN64 char* ActionScript;
ALIGN64 BOOL Floatbar;
ALIGN64 DWORD Floatbar;
};
typedef struct rdp_settings rdpSettings;