Backed out 3 changesets (bug 1804877) for causing multiple build bustages. CLOSED TREE

Backed out changeset 0f042a90a90b (bug 1804877)
Backed out changeset 800f78104e83 (bug 1804877)
Backed out changeset a6f5a91e18da (bug 1804877)
This commit is contained in:
Iulian Moraru 2023-01-04 04:27:21 +02:00
Родитель 2b7c4a2214
Коммит cad9265ea8
5 изменённых файлов: 93 добавлений и 223 удалений

Просмотреть файл

@ -19,7 +19,6 @@
#include "mozilla/WidgetUtilsGtk.h"
#include "mozilla/StaticPrefs_widget.h"
#include "mozilla/net/DNS.h"
#include "prenv.h"
#include <gio/gio.h>
#include <gtk/gtk.h>
@ -217,8 +216,7 @@ nsGIOMimeApp::Equals(nsIHandlerApp* aHandlerApp, bool* _retval) {
return NS_OK;
}
static RefPtr<GAppLaunchContext> GetLaunchContext(
const char* aXDGToken = nullptr) {
static RefPtr<GAppLaunchContext> GetLaunchContext() {
RefPtr<GAppLaunchContext> context = dont_AddRef(g_app_launch_context_new());
// Unset this before launching third-party MIME handlers. Otherwise, if
// Thunderbird sets this in its startup script (as it does in Debian and
@ -226,9 +224,6 @@ static RefPtr<GAppLaunchContext> GetLaunchContext(
// Debian), then Firefox will think it is part of Thunderbird and try to make
// Thunderbird the default browser. See bug 1494436.
g_app_launch_context_unsetenv(context, "MOZ_APP_LAUNCHER");
if (aXDGToken) {
g_app_launch_context_setenv(context, "XDG_ACTIVATION_TOKEN", aXDGToken);
}
return context;
}
@ -285,8 +280,9 @@ gboolean g_app_info_launch_default_for_uri_openbsd(const char* uri,
}
#endif
static NS_IMETHODIMP LaunchWithURIImpl(RefPtr<GAppInfo> aInfo, nsIURI* aUri,
const char* aXDGToken = nullptr) {
NS_IMETHODIMP
nsGIOMimeApp::LaunchWithURI(nsIURI* aUri,
mozilla::dom::BrowsingContext* aBrowsingContext) {
GList uris = {0};
nsCString spec;
aUri->GetSpec(spec);
@ -296,11 +292,10 @@ static NS_IMETHODIMP LaunchWithURIImpl(RefPtr<GAppInfo> aInfo, nsIURI* aUri,
GUniquePtr<GError> error;
#ifdef __OpenBSD__
gboolean result = g_app_info_launch_uris_openbsd(
aInfo, spec.get(), GetLaunchContext(aXDGToken).get(),
getter_Transfers(error));
mApp, spec.get(), GetLaunchContext().get(), getter_Transfers(error));
#else
gboolean result = g_app_info_launch_uris(
aInfo, &uris, GetLaunchContext(aXDGToken).get(), getter_Transfers(error));
mApp, &uris, GetLaunchContext().get(), getter_Transfers(error));
#endif
if (!result) {
g_warning("Cannot launch application: %s", error->message);
@ -310,26 +305,6 @@ static NS_IMETHODIMP LaunchWithURIImpl(RefPtr<GAppInfo> aInfo, nsIURI* aUri,
return NS_OK;
}
NS_IMETHODIMP
nsGIOMimeApp::LaunchWithURI(nsIURI* aUri,
mozilla::dom::BrowsingContext* aBrowsingContext) {
auto promise = mozilla::widget::RequestWaylandFocusPromise();
if (!promise) {
return LaunchWithURIImpl(mApp, aUri);
}
promise->Then(
GetMainThreadSerialEventTarget(), __func__,
/* resolve */
[app = RefPtr{mApp}, uri = RefPtr{aUri}](nsCString token) {
LaunchWithURIImpl(app, uri, token.get());
},
/* reject */
[app = RefPtr{mApp}, uri = RefPtr{aUri}](bool state) {
LaunchWithURIImpl(app, uri);
});
return NS_OK;
}
class GIOUTF8StringEnumerator final : public nsStringEnumeratorBase {
~GIOUTF8StringEnumerator() = default;
@ -618,18 +593,17 @@ nsGIOService::GetDescriptionForMimeType(const nsACString& aMimeType,
return NS_OK;
}
static nsresult ShowURIImpl(nsIURI* aURI, const char* aXDGToken = nullptr) {
nsresult nsGIOService::ShowURI(nsIURI* aURI) {
nsAutoCString spec;
MOZ_TRY(aURI->GetSpec(spec));
GUniquePtr<GError> error;
#ifdef __OpenBSD__
if (!g_app_info_launch_default_for_uri_openbsd(
spec.get(), GetLaunchContext(aXDGToken).get(),
if (!g_app_info_launch_default_for_uri_openbsd(spec.get(),
GetLaunchContext().get(),
#else
if (!g_app_info_launch_default_for_uri(spec.get(),
GetLaunchContext(aXDGToken).get(),
if (!g_app_info_launch_default_for_uri(spec.get(), GetLaunchContext().get(),
#endif
getter_Transfers(error))) {
getter_Transfers(error))) {
g_warning("Could not launch default application for URI: %s",
error->message);
return NS_ERROR_FAILURE;
@ -637,32 +611,16 @@ static nsresult ShowURIImpl(nsIURI* aURI, const char* aXDGToken = nullptr) {
return NS_OK;
}
nsresult nsGIOService::ShowURI(nsIURI* aURI) {
auto promise = mozilla::widget::RequestWaylandFocusPromise();
if (!promise) {
return ShowURIImpl(aURI);
}
promise->Then(
GetMainThreadSerialEventTarget(), __func__,
/* resolve */
[uri = RefPtr{aURI}](nsCString token) { ShowURIImpl(uri, token.get()); },
/* reject */
[uri = RefPtr{aURI}](bool state) { ShowURIImpl(uri); });
return NS_OK;
}
static nsresult LaunchPathImpl(const nsACString& aPath,
const char* aXDGToken = nullptr) {
static nsresult LaunchPath(const nsACString& aPath) {
RefPtr<GFile> file = dont_AddRef(
g_file_new_for_commandline_arg(PromiseFlatCString(aPath).get()));
GUniquePtr<char> spec(g_file_get_uri(file));
GUniquePtr<GError> error;
#ifdef __OpenBSD__
g_app_info_launch_default_for_uri_openbsd(spec.get(),
GetLaunchContext(aXDGToken).get(),
GetLaunchContext().get(),
#else
g_app_info_launch_default_for_uri(spec.get(),
GetLaunchContext(aXDGToken).get(),
g_app_info_launch_default_for_uri(spec.get(), GetLaunchContext().get(),
#endif
getter_Transfers(error));
if (error) {
@ -672,22 +630,6 @@ static nsresult LaunchPathImpl(const nsACString& aPath,
return NS_OK;
}
static nsresult LaunchPath(const nsACString& aPath) {
auto promise = mozilla::widget::RequestWaylandFocusPromise();
if (!promise) {
return LaunchPathImpl(aPath);
}
promise->Then(
GetMainThreadSerialEventTarget(), __func__,
/* resolve */
[path = nsCString{aPath}](nsCString token) {
LaunchPathImpl(path, token.get());
},
/* reject */
[path = nsCString{aPath}](bool state) { LaunchPathImpl(path); });
return NS_OK;
}
nsresult nsGIOService::LaunchFile(const nsACString& aPath) {
return LaunchPath(aPath);
}

Просмотреть файл

@ -11,20 +11,11 @@
#include "nsWindow.h"
#include "nsIGfxInfo.h"
#include "mozilla/Components.h"
#include "nsGtkKeyUtils.h"
#include <gtk/gtk.h>
#include <dlfcn.h>
#include <glib.h>
#ifdef MOZ_LOGGING
# include "mozilla/Logging.h"
extern mozilla::LazyLogModule gWidgetLog;
# define LOGW(...) MOZ_LOG(gWidgetLog, mozilla::LogLevel::Debug, (__VA_ARGS__))
#else
# define LOGW(...)
#endif /* MOZ_LOGGING */
namespace mozilla::widget {
int32_t WidgetUtilsGTK::IsTouchDeviceSupportPresent() {
@ -202,106 +193,4 @@ nsTArray<nsCString> ParseTextURIList(const nsACString& aData) {
return result;
}
#ifdef MOZ_WAYLAND
static gboolean token_failed(gpointer aData);
class XDGTokenRequest {
public:
void SetTokenID(const char* aTokenID) {
mTransferPromise->Resolve(aTokenID, __func__);
}
void Cancel() {
mTransferPromise->Reject(false, __func__);
mActivationTimeoutID = 0;
}
XDGTokenRequest(xdg_activation_token_v1* aXdgToken,
RefPtr<FocusRequestPromise::Private> aTransferPromise)
: mXdgToken(aXdgToken), mTransferPromise(std::move(aTransferPromise)) {
mActivationTimeoutID =
g_timeout_add(sActivationTimeout, token_failed, this);
}
~XDGTokenRequest() {
MozClearPointer(mXdgToken, xdg_activation_token_v1_destroy);
if (mActivationTimeoutID) {
g_source_remove(mActivationTimeoutID);
}
}
private:
xdg_activation_token_v1* mXdgToken;
RefPtr<FocusRequestPromise::Private> mTransferPromise;
guint mActivationTimeoutID;
// Reject FocusRequestPromise if we don't get XDG token in 0.5 sec.
static constexpr int sActivationTimeout = 500;
};
// Failed to get token in time
static gboolean token_failed(gpointer data) {
UniquePtr<XDGTokenRequest> request(static_cast<XDGTokenRequest*>(data));
request->Cancel();
return false;
}
// We've got activation token from Wayland compositor so it's time to use it.
static void token_done(gpointer data, struct xdg_activation_token_v1* provider,
const char* tokenID) {
UniquePtr<XDGTokenRequest> request(static_cast<XDGTokenRequest*>(data));
request->SetTokenID(tokenID);
}
static const struct xdg_activation_token_v1_listener token_listener = {
token_done,
};
RefPtr<FocusRequestPromise> RequestWaylandFocusPromise() {
if (!GdkIsWaylandDisplay() || !nsWindow::GetFocusedWindow() ||
nsWindow::GetFocusedWindow()->IsDestroyed()) {
return nullptr;
}
RefPtr<nsWindow> sourceWindow = nsWindow::GetFocusedWindow();
if (!sourceWindow) {
return nullptr;
}
RefPtr<nsWaylandDisplay> display = WaylandDisplayGet();
xdg_activation_v1* xdg_activation = display->GetXdgActivation();
if (!xdg_activation) {
return nullptr;
}
wl_surface* focusSurface;
uint32_t focusSerial;
KeymapWrapper::GetFocusInfo(&focusSurface, &focusSerial);
if (!focusSurface) {
return nullptr;
}
GdkWindow* gdkWindow = gtk_widget_get_window(sourceWindow->GetGtkWidget());
if (!gdkWindow) {
return nullptr;
}
wl_surface* surface = gdk_wayland_window_get_wl_surface(gdkWindow);
if (focusSurface != surface) {
return nullptr;
}
RefPtr<FocusRequestPromise::Private> transferPromise =
new FocusRequestPromise::Private(__func__);
xdg_activation_token_v1* aXdgToken =
xdg_activation_v1_get_activation_token(xdg_activation);
xdg_activation_token_v1_add_listener(
aXdgToken, &token_listener,
new XDGTokenRequest(aXdgToken, transferPromise));
xdg_activation_token_v1_set_serial(aXdgToken, focusSerial,
KeymapWrapper::GetSeat());
xdg_activation_token_v1_set_surface(aXdgToken, focusSurface);
xdg_activation_token_v1_commit(aXdgToken);
return transferPromise.forget();
}
#endif
} // namespace mozilla::widget

Просмотреть файл

@ -8,14 +8,12 @@
#include "nsString.h"
#include "nsTArray.h"
#include "mozilla/MozPromise.h"
#include <stdint.h>
typedef struct _GdkDisplay GdkDisplay;
typedef struct _GdkDevice GdkDevice;
typedef union _GdkEvent GdkEvent;
class nsWindow;
namespace mozilla::widget {
@ -61,11 +59,6 @@ bool ShouldUsePortal(PortalKind);
// Parse text/uri-list
nsTArray<nsCString> ParseTextURIList(const nsACString& data);
#ifdef MOZ_WAYLAND
using FocusRequestPromise = MozPromise<nsCString, bool, false>;
RefPtr<FocusRequestPromise> RequestWaylandFocusPromise();
#endif
} // namespace mozilla::widget
#endif // WidgetUtilsGtk_h__

Просмотреть файл

@ -608,6 +608,7 @@ void nsWindow::Destroy() {
mWaylandVsyncSource = nullptr;
}
mWaylandVsyncDispatcher = nullptr;
MozClearPointer(mXdgToken, xdg_activation_token_v1_destroy);
#endif
/** Need to clean our LayerManager up while still alive */
@ -3037,8 +3038,7 @@ void nsWindow::SetUserTimeAndStartupTokenForActivatedWindow() {
gtk_window_set_startup_id(GTK_WINDOW(mShell),
mWindowActivationTokenFromEnv.get());
// In the case of X11, the above call is all we need. For wayland we need
// to keep the token around until we take it in
// TransferFocusToWaylandWindow.
// to keep the token around until we take it in RequestFocusWaylandWindow.
mWindowActivationTokenFromEnv.Truncate();
}
} else if (uint32_t timestamp = toolkit->GetFocusTimestamp()) {
@ -3083,6 +3083,8 @@ guint32 nsWindow::GetLastUserInputTime() {
#ifdef MOZ_WAYLAND
void nsWindow::FocusWaylandWindow(const char* aTokenID) {
MOZ_DIAGNOSTIC_ASSERT(aTokenID);
auto releaseToken = MakeScopeExit(
[&] { MozClearPointer(mXdgToken, xdg_activation_token_v1_destroy); });
LOG("nsWindow::FocusWaylandWindow(%s)", aTokenID);
if (IsDestroyed()) {
@ -3105,26 +3107,80 @@ void nsWindow::FocusWaylandWindow(const char* aTokenID) {
xdg_activation_v1_activate(xdg_activation, aTokenID, surface);
}
// Transfer focus from gFocusWindow to aWindow and use xdg_activation
// protocol for it.
void nsWindow::TransferFocusToWaylandWindow(nsWindow* aWindow) {
LOGW("nsWindow::TransferFocusToWaylandWindow(%p) gFocusWindow %p", aWindow,
// We've got activation token from Wayland compositor so it's time to use it.
static void token_done(gpointer data, struct xdg_activation_token_v1* provider,
const char* token) {
// Compensate aWindow->AddRef() from nsWindow::RequestFocusWaylandWindow().
RefPtr<nsWindow> window = dont_AddRef(static_cast<nsWindow*>(data));
window->FocusWaylandWindow(token);
}
static const struct xdg_activation_token_v1_listener token_listener = {
token_done,
};
void nsWindow::RequestFocusWaylandWindow(RefPtr<nsWindow> aWindow) {
LOGW("nsWindow::RequestFocusWaylandWindow(%p) gFocusWindow %p", aWindow.get(),
gFocusWindow);
auto promise = mozilla::widget::RequestWaylandFocusPromise();
if (NS_WARN_IF(!promise)) {
LOGW(" quit, failed to create TransferFocusToWaylandWindow [%p]", aWindow);
auto existingToken = std::move(aWindow->mWindowActivationTokenFromEnv);
if (!existingToken.IsEmpty()) {
LOGW(" has existing activation token.");
aWindow->FocusWaylandWindow(existingToken.get());
return;
}
promise->Then(
GetMainThreadSerialEventTarget(), __func__,
/* resolve */
[window = RefPtr{aWindow}](nsCString token) {
window->FocusWaylandWindow(token.get());
},
/* reject */
[window = RefPtr{aWindow}](bool state) {
LOGW("TransferFocusToWaylandWindow [%p] failed", window.get());
});
if (!gFocusWindow || gFocusWindow->IsDestroyed()) {
LOGW(" missing gFocusWindow, quit.");
return;
}
RefPtr<nsWaylandDisplay> display = WaylandDisplayGet();
xdg_activation_v1* xdg_activation = display->GetXdgActivation();
if (!xdg_activation) {
LOGW(" xdg-activation is missing, quit.");
return;
}
wl_surface* focusSurface;
uint32_t focusSerial;
KeymapWrapper::GetFocusInfo(&focusSurface, &focusSerial);
if (!focusSurface) {
LOGW(" We're missing KeymapWrapper focused window, quit.");
return;
}
GdkWindow* gdkWindow = gtk_widget_get_window(gFocusWindow->mShell);
if (!gdkWindow) {
LOGW(" gFocusWindow is not mapped, quit.");
return;
}
wl_surface* surface = gdk_wayland_window_get_wl_surface(gdkWindow);
if (focusSurface != surface) {
LOGW(" focused surface %p and gFocusWindow surface %p don't match, quit.",
focusSurface, surface);
return;
}
LOGW(
" requesting xdg-activation token, surface %p ID %d serial %d seat ID "
"%d",
focusSurface,
focusSurface ? wl_proxy_get_id((struct wl_proxy*)focusSurface) : 0,
focusSerial, wl_proxy_get_id((struct wl_proxy*)KeymapWrapper::GetSeat()));
// Store activation token at activated window for further release.
MozClearPointer(aWindow->mXdgToken, xdg_activation_token_v1_destroy);
aWindow->mXdgToken = xdg_activation_v1_get_activation_token(xdg_activation);
// Addref aWindow to avoid potential release untill we get token_done
// callback.
xdg_activation_token_v1_add_listener(aWindow->mXdgToken, &token_listener,
do_AddRef(aWindow).take());
xdg_activation_token_v1_set_serial(aWindow->mXdgToken, focusSerial,
KeymapWrapper::GetSeat());
xdg_activation_token_v1_set_surface(aWindow->mXdgToken, focusSurface);
xdg_activation_token_v1_commit(aWindow->mXdgToken);
}
#endif
@ -3151,7 +3207,6 @@ void nsWindow::SetFocus(Raise aRaise, mozilla::dom::CallerType aCallerType) {
aRaise == Raise::Yes && toplevelWidget &&
!gtk_widget_has_focus(toplevelWidget)) {
if (gtk_widget_get_visible(mShell)) {
LOG(" toplevel is not focused");
gdk_window_show_unraised(gtk_widget_get_window(mShell));
// Unset the urgency hint if possible.
SetUrgencyHint(mShell, false);
@ -3172,8 +3227,7 @@ void nsWindow::SetFocus(Raise aRaise, mozilla::dom::CallerType aCallerType) {
if (StaticPrefs::mozilla_widget_raise_on_setfocus_AtStartup() &&
toplevelWindow->mIsShown && toplevelWindow->mShell &&
!gtk_window_is_active(GTK_WINDOW(toplevelWindow->mShell))) {
LOG(" toplevel is visible but not active, requesting activation [%p]",
toplevelWindow.get());
LOG(" requesting toplevel activation [%p]\n", toplevelWindow.get());
// Take the time here explicitly for the call below.
const uint32_t timestamp = [&] {
@ -3192,16 +3246,7 @@ void nsWindow::SetFocus(Raise aRaise, mozilla::dom::CallerType aCallerType) {
#ifdef MOZ_WAYLAND
if (GdkIsWaylandDisplay()) {
auto existingToken =
std::move(toplevelWindow->mWindowActivationTokenFromEnv);
if (!existingToken.IsEmpty()) {
LOG(" has existing activation token.");
toplevelWindow->FocusWaylandWindow(existingToken.get());
} else {
LOG(" missing activation token, try to transfer from focused "
"window");
TransferFocusToWaylandWindow(toplevelWindow);
}
RequestFocusWaylandWindow(toplevelWindow);
}
#endif
}

Просмотреть файл

@ -412,7 +412,7 @@ class nsWindow final : public nsBaseWidget {
#ifdef MOZ_WAYLAND
// Use xdg-activation protocol to transfer focus from gFocusWindow to aWindow.
static void TransferFocusToWaylandWindow(nsWindow* aWindow);
static void RequestFocusWaylandWindow(RefPtr<nsWindow> aWindow);
void FocusWaylandWindow(const char* aTokenID);
bool GetCSDDecorationOffset(int* aDx, int* aDy);
@ -979,6 +979,7 @@ class nsWindow final : public nsBaseWidget {
LayoutDeviceIntPoint mNativePointerLockCenter;
zwp_locked_pointer_v1* mLockedPointer = nullptr;
zwp_relative_pointer_v1* mRelativePointer = nullptr;
xdg_activation_token_v1* mXdgToken = nullptr;
#endif
// An activation token from our environment (see handling of the
// XDG_ACTIVATION_TOKEN/DESKTOP_STARTUP_ID) env vars.